[
  {
    "path": ".gitignore",
    "content": "# Visual Studio Code\n.vs/\n.vscode/\n\n# Build files\nbuild/\noutput/\n\n# Cli files\nvenv/\nscripts/sd-files/\n\n# Release files\nargon-nx.zip\n\n# Helpers\nnew-gui.sh"
  },
  {
    "path": "Changelog.md",
    "content": "# Changelog\n\n## v0.2\n\n- Cancel autolaunch/autochainloading of `argon/payload.bin` by holding VOL_DOWN_BUTTON when ArgonNX is booting.\n- Minerva training to improve performace.\n- Custom background. Just place your custom background inside `argon` directory and name it `background.bmp`. Use of custom background is optional.\n- Custom title. Just place your custom title inside argon directory and name it `title.bmp`. Use of custom title is optional.\n- By default ArgonNX uses dark background instead of the white one in v0.1.\n- Payloads' names now are centered below the logo.\n- Partial touch support. To enable touch support create an empty file called `touch` inside `argon` directory.\n- Take Screenshots to share your argon configuration! \n- Improve system stability to enhance user experience.\n\n## v0.3\n\n- Now background must be in a vertical position. New background size must be smaller or equal than 720x1280. (Performance reasons)\n- Using double buffering for rendering in order to avoid flickering and also improve performance.\n- Fully touch support. Thanks to @pixel-stuck\n- Now payloads are sorted by name.\n- Correctly deallocate argon-nx from memory when launching payloads.\n- Improve system stability to enhance user experience.\n\n## v1.0-alpha\n\n- ArgonNX's UI has been rewritten using [LittlevGL]() library. This rewrite has a lot of benefits. Some benefits include:\n    - Prettier font\n    - Faster rendering\n    - Better touch support\n    - In general terms improves UX\n- Now payloads are listed inside tabviews where each tab contains a group of 4 payloads.\n- New tab of tools. By now tools only are related to reboot stuff (reboot to rcm, power off, reboot to ofw)\n- Background size back to 1280*720. No more weird image flippings.\n- ArgonNX Command Line Interface to simplify the process to create logos and backgrounds.\n- Now there is no need to declare a `default.bmp` logo inside the `argon/logos` directory.\n- Improve system stability to enhance user experience.\n\n## v1.1-alpha\n\n- Fixing critical bug. Now launches using any payload sender.\n- Argon now is composed by 2 payloads (2 stages).\n    1. First stage configures hardware\n    2. Loads the GUI\n- Bootlogo/splash and wait until GUI is loaded.\n- Improve system stability to enhance user experience.\n"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\n 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Lesser General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n                            NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc.,\n    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.\n"
  },
  {
    "path": "Makefile",
    "content": "\n.PHONY: all clean\n\n\nall: directories primary gui\n\t$(MAKE) -C modules/minerva\n\ndirectories:\n\t@mkdir -p output\n\ngui:\n\t$(MAKE) -C argon-nx-gui\n\nprimary:\n\t$(MAKE) -C argon-first-stage\n\nclean:\n\t$(MAKE) -C modules/minerva clean\n\t$(MAKE) -C argon-first-stage clean\n\t$(MAKE) -C argon-nx-gui clean\n\trm -rf output/\n\ndist: clean all \n\tmkdir -p argon/logos\n\tmkdir -p argon/payloads\n\tmkdir -p argon/sys\n\n\tcp output/argon-nx.bin argon-nx.bin\n\tcp output/argon-nx-gui.bin argon/sys/argon-nx-gui.bin\n\n\tcp output/libsys_minerva.bso argon/sys/minerva.bso\n\t\n\tcp img/example-custom/logos/* argon/logos\n\tcp img/example-custom/backgrounds/default.bmp argon/background.bmp\n\tcp img/example-custom/splashes/default.bmp argon/splash.bmp\n\t\n\tcp modules/resources.argon argon/sys/resources.argon\n\n\tzip -r argon-nx.zip argon argon-nx.bin\n\n\trm -rf argon\n\trm argon-nx.bin"
  },
  {
    "path": "README.md",
    "content": "\n<img src=\"img/splash.jpg\" alt=\"banner\">\n\n![License badge](https://img.shields.io/badge/license-GPLv2-blue.svg)\n[![Homebrew Store](https://img.shields.io/badge/Homebrew%20Switch-store-%23ff4554.svg)](https://www.switchbru.com/appstore/#/app/argon-nx)\n\n## What Argon is?\n\nArgon is a noble gas.\n\"Argon\" comes from Greek \"Argon\", neuter of \"argos\" meaning *lazy* , *idle* or *inactive*.\nArgon recieved this name because of its chemical inactivity.\n\nArgon NX is an immutable payload which is injected to your Nintendo Switch via Fusee Gelee exploit.\n\n## Purpose \n\nThe purpose of Argon NX is to stay immutable, so you can always inject it, without caring about other payloads getting updated (Always use ArgonNX for TegraSmash, TegraGUI, TrinkedM0...).\n\n## How can it be immutable?\n\nWhen Argon NX is injected, it automatically launches the `payload.bin` loacted at `argon` directory on your SD Card root. \n\nIf `payload.bin` is not present or VOLUME DOWN button is pressed on payload injection, Argon NX will list all payloads located at `argon/payloads`, and you will be able to select one of them to launch it.\n\n## Features\n\n- **Autolaunch/autochainload** the payload named `payload.bin` inside `argon` directory in your sd card root.\n- If `argon/payload.bin` is not found or `VOLUME_DOWN_BUTTON` is held during ArgonNX injection, ArgonNX will list all the payloads located at `argon/payloads`, so you can select one of them to launch it.\n- **Customize payloads' logos**. **Logos must be smaller or equal than 280x280** (See About BMP format section). Example:\n\n```\nargon\n  ├───logos\n  │     fusee-primary.bmp # Logo for fusee-primary.bin payload\n  │     ReiNX.bmp # Logo for ReiNX.bin payload\n  │\n  └───payloads\n        fusee-primary.bin\n        ReiNX.bin         \n        hekate.bin # Will be rendered using default logo\n```\n\n- **Custom backgrounds** can be added by placing `background.bmp` file inside `argon` directory. **The background must be smaller or equal than 1280x720**.\n- Take **screenshots** to share your ArgonNX gui. To capture ArgonNX screen tap anywhere with two or more fingers.\n- Touch support. Thanks to @pixel-stuck\n- Simple tools. (Don't expect tools like the onew built in hekate, argon tools are much more lightweighted and simple, such as reboot options)\n- Command Line Interface (CLI) to facilitate the procedure to create bmp files for custom logos and backgrounds.\n\n## About BMP format\n\nThe only format supported is **BMP 32 bit ARGB color**.\nArgonNX recommends using a solid background without alpha channel (alpha channel set to 0xFF). Payloads' logos **support alpha channel**.\n\n### Generate new logos and background\n\nArgonNX provides a useful Command Line Interface (CLI) to create new logos and backgrounds for your payloads using a *jpg* or *png* images.\n\n#### CLI installation\n\nThe Argon CLI is written in Python. To install python follow the instructions listed [here](https://realpython.com/installing-python/). Once you have python3 installed just type the following commands (These will install the requirements for running the CLI):\n\n```bash\n$ cd scripts\n$ pip install -r requirements.txt\n$ sudo apt-get install libmagickwand-dev\n```\n\n> If you are using Windows visit [Wand's installation page](http://docs.wand-py.org/en/0.4.1/guide/install.html) and follow the steps to install libmagikcwand on Windows.\n\n#### CLI Usage\n\nTo generate a new logo use the following command.\n\n```bash\n$ cd scripts\n$ python argon.py img-to-logo <path-to-png-jpg-img>\n```\n\nTo generate a new background use the following command.\n\n```bash\n$ cd scripts\n$ python argon.py generate-background <path-to-png-jpg-img>\n```\n\nThe CLI stores the outputs of the commands at the recently created (also by the CLI) `sd-files/argon` directory (This directory simulates an sd-card argon structure).\n\nTo learn more about the CLI options type:\n\n```bash\n$ python argon.py --help\n```\n\n## GUI\n\nThese images were captured with the **screenshot** feature.\n\n<img src=\"img/example1.png\" alt=\"example\" width=\"700\">\n\n<img src=\"img/example2.png\" alt=\"example\" width=\"700\">\n\n<img src=\"img/example3.png\" alt=\"example\" width=\"700\">\n\n<img src=\"img/example4.png\" alt=\"example\" width=\"700\">\n\nAs you can see in the pictures, payloads are displayed in groups of 4 and each group is displayed in a different *payloads* tab.\n\nYou can find the logos used in the pictures inside [this directory](img/example-custom/logos) and backgrounds [here](img/example-custom/backgrounds).\n\n## ArgonNX sd card tree\n\nHow a full running ArgonNX example looks inside the sd card:\n\n```\nargon\n├─── payloads\n│       Atmosphere.bin\n│       ReiNX.bin\n│       fusee-gelee.bin\n│       hekate.bin\n│       SXOS.bin\n│\n├─── logos\n|       Atmosphere.bmp\n|       Reinx.bmp\n|       hekate.bmp\n|       SXOS.bmp\n|\n├─── sys\n|       minerva.bso # IMPORTANT if you want a good UX experience\n|       resources.argon # IMPORTANT. Binary file containing all render resources except the background and logos\n|\n└─── background.bmp\n```\n\n## Improve performance\n\nArgonNX can use **minerva training cell** to improve performance.\nThe use of minerva is optional but recommended. To use minerva just place the compiled `minerva.bso` inside `argon/sys`. The directory `argon/sys` with minerva, is included in `sd-files.zip` in the release section.\n\nTo learn more about Minerva Training Cell check its [official repo](https://github.com/CTCaer/minerva_tc).\n\n## Compatibility\n\nThis payload will chainload any CFW or payload. \n\nSome users reported issuses when chainloading SX OS. <small>But with Atmosphere out there... who wants SXOS?</small> 🙄\n\n## Roadmap\n\n1. Config file to manage tabs titles and argon sd card directory tree.\n2. More tools inside tools tab.\n\n## Credits\n\n* __devkitPro__ for the [devkitA64](https://devkitpro.org/) toolchain.\n* __naehrwert__ and __st4rk__ for the original [hekate](https://github.com/nwert/hekate) project and its hwinit code base.\n* __CTCaer__ for the continued [hekate](https://github.com/CTCaer/hekate) and his **minerva** project.\n* __xalgovia__ and __Retrogamer 74__ for the splash and logos. Also thanks them to use ArgonNX in RetroReloaded.\n* __langerhans__ and  __stuck-pixel__ for their implementation of touch support.\n* __LittlevGL__ for being such a good embedded graphics library.\n* __D3fau4__ for touch support testing.\n"
  },
  {
    "path": "argon-first-stage/Dockerfile",
    "content": "# Build Docker image using: docker build . -t argon-nx-builder\n# Run docker image using: docker run -a stdout -a stderr -v $(pwd)/output:/argon-nx/output argon-nx-builder\n\nFROM devkitpro/devkitarm\nWORKDIR /argon-first-stage\nCOPY . .\nENTRYPOINT [\"make\"]"
  },
  {
    "path": "argon-first-stage/Makefile",
    "content": "ifeq ($(strip $(DEVKITARM)),)\n$(error \"Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM\")\nendif\n\ninclude $(DEVKITARM)/base_rules\n\nTARGET          := argon-nx\nBUILD           := build\nOUTPUT          := ../output\nSOURCEDIR       := src\nSOURCES         := src \\\n\t\t\tsrc/ianos \\\n\t\t\tsrc/libs/fatfs src/libs/elfload src/libs/compr \\\n\t\t\tsrc/core \\\n\t\t\tsrc/gfx \\\n\t\t\tsrc/mem \\\n\t\t\tsrc/menu/gui \\\n\t\t\tsrc/power \\\n\t\t\tsrc/sec \\\n\t\t\tsrc/soc \\\n\t\t\tsrc/storage \\\n\t\t\tsrc/utils\n\nINCLUDES        := include\nVPATH           = $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))\nVPATH \t\t+= $(dir $(wildcard ./$(SOURCEDIR)/*/*/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/*/*/))\nCFILES          := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))\nSFILES          := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))\n\nOFILES_SRC      := $(SFILES:.s=.o) $(CFILES:.c=.o)\nHFILES_BIN      := $(addsuffix .h,$(subst .,_,$(BINFILES)))\n\nOBJS            = $(addprefix $(BUILD)/$(TARGET)/, $(OFILES_SRC))\n\n\nINCLUDE         :=$(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \\\n\t\t  $(foreach dir,$(LIBDIRS),-I$(dir)/include) \\\n\t\t  -I$(BUILD)/$(TARGET)\n\nARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork\nCFLAGS = $(INCLUDE) $(ARCH) -O2 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 -Wall\nLDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections\n\n\n.PHONY: all clean\n\nall: directories $(TARGET).bin\n\t@echo $(HFILES_BIN)\n\t@echo -n \"Payload size is \"\n\t@wc -c < $(OUTPUT)/$(TARGET).bin\n\t@echo \"Max size is 126296 Bytes.\"\n\ndirectories:\n\t@mkdir -p \"$(BUILD)\"\n\t@mkdir -p \"$(BUILD)/$(TARGET)\"\n\t@mkdir -p \"$(OUTPUT)\"\n\t\nclean:\n\t@rm -rf $(OBJS)\n\t@rm -rf $(BUILD)\n\t@rm -f $(OUTPUT)/$(TARGET).bin\n\n$(MODULEDIRS):\n\t$(MAKE) -C $@ $(MAKECMDGOALS)\n\n$(TARGET).bin: $(BUILD)/$(TARGET)/$(TARGET).elf $(MODULEDIRS)\n\t$(OBJCOPY) -S -O binary $< $(OUTPUT)/$@\n\n$(BUILD)/$(TARGET)/$(TARGET).elf: $(OBJS)\n\t$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@\n\n$(BUILD)/$(TARGET)/%.o: %.c\n\t$(CC) $(CFLAGS) -c $< -o $@\n\n$(BUILD)/$(TARGET)/%.o: %.s\n\t$(CC) $(CFLAGS) -c $< -o $@\n\n$(OFILES_SRC): $(HFILES_BIN)\n\nprint-%  : ; @echo $* = $($*)\n"
  },
  {
    "path": "argon-first-stage/include/core/launcher.h",
    "content": "/*\n * Copyright (c) 2018 Guillem96\n * \n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef _LAUNCHER_H_\n#define _LAUNCHER_H_\n\nint launch_payload(char*);\n\n#endif"
  },
  {
    "path": "argon-first-stage/include/gfx/di.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _DI_H_\n#define _DI_H_\n\n#include \"utils/types.h\"\n\n#define FB_ADDRESS 0xC0000000\n\n/*! Display registers. */\n#define _DIREG(reg) ((reg) * 4)\n\n#define DC_CMD_GENERAL_INCR_SYNCPT 0x00\n\n#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01\n#define  SYNCPT_CNTRL_NO_STALL   (1 << 8)\n#define  SYNCPT_CNTRL_SOFT_RESET (1 << 0)\n\n#define DC_CMD_CONT_SYNCPT_VSYNC 0x28\n#define  SYNCPT_VSYNC_ENABLE (1 << 8)\n\n#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031\n\n#define DC_CMD_DISPLAY_COMMAND 0x32\n#define  DISP_CTRL_MODE_STOP       (0 << 5)\n#define  DISP_CTRL_MODE_C_DISPLAY  (1 << 5)\n#define  DISP_CTRL_MODE_NC_DISPLAY (2 << 5)\n#define  DISP_CTRL_MODE_MASK       (3 << 5)\n\n#define DC_CMD_DISPLAY_POWER_CONTROL 0x36\n#define  PW0_ENABLE (1 <<  0)\n#define  PW1_ENABLE (1 <<  2)\n#define  PW2_ENABLE (1 <<  4)\n#define  PW3_ENABLE (1 <<  6)\n#define  PW4_ENABLE (1 <<  8)\n#define  PM0_ENABLE (1 << 16)\n#define  PM1_ENABLE (1 << 18)\n\n#define DC_CMD_INT_MASK 0x38\n#define DC_CMD_INT_ENABLE 0x39\n\n#define DC_CMD_STATE_ACCESS 0x40\n#define  READ_MUX  (1 << 0)\n#define  WRITE_MUX (1 << 2)\n\n#define DC_CMD_STATE_CONTROL 0x41\n#define  GENERAL_ACT_REQ (1 <<  0)\n#define  WIN_A_ACT_REQ   (1 <<  1)\n#define  WIN_B_ACT_REQ   (1 <<  2)\n#define  WIN_C_ACT_REQ   (1 <<  3)\n#define  CURSOR_ACT_REQ  (1 <<  7)\n#define  GENERAL_UPDATE  (1 <<  8)\n#define  WIN_A_UPDATE    (1 <<  9)\n#define  WIN_B_UPDATE    (1 << 10)\n#define  WIN_C_UPDATE    (1 << 11)\n#define  CURSOR_UPDATE   (1 << 15)\n#define  NC_HOST_TRIG    (1 << 24)\n\n#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42\n#define  WINDOW_A_SELECT (1 << 4)\n#define  WINDOW_B_SELECT (1 << 5)\n#define  WINDOW_C_SELECT (1 << 6)\n\n#define DC_CMD_REG_ACT_CONTROL 0x043\n\n#define DC_COM_CRC_CONTROL 0x300\n#define DC_COM_PIN_OUTPUT_ENABLE(x) (0x302 + (x))\n#define DC_COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x))\n\n#define DC_COM_DSC_TOP_CTL 0x33E\n\n#define DC_DISP_DISP_WIN_OPTIONS 0x402\n#define  HDMI_ENABLE     (1 << 30)\n#define  DSI_ENABLE      (1 << 29)\n#define  SOR1_TIMING_CYA (1 << 27)\n#define  SOR1_ENABLE     (1 << 26)\n#define  SOR_ENABLE      (1 << 25)\n#define  CURSOR_ENABLE   (1 << 16)\n\n#define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403\n#define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404\n#define DC_DISP_DISP_TIMING_OPTIONS 0x405\n#define DC_DISP_REF_TO_SYNC 0x406\n#define DC_DISP_SYNC_WIDTH 0x407\n#define DC_DISP_BACK_PORCH 0x408\n#define DC_DISP_ACTIVE 0x409\n#define DC_DISP_FRONT_PORCH 0x40A\n\n#define DC_DISP_DISP_CLOCK_CONTROL 0x42E\n#define  PIXEL_CLK_DIVIDER_PCD1  (0 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD1H (1 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD2  (2 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD3  (3 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD4  (4 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD6  (5 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD8  (6 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD9  (7 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD12 (8 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD16 (9 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD18 (10 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD24 (11 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD13 (12 << 8)\n#define  SHIFT_CLK_DIVIDER(x)    ((x) & 0xff)\n\n#define DC_DISP_DISP_INTERFACE_CONTROL 0x42F\n#define  DISP_DATA_FORMAT_DF1P1C    (0 << 0)\n#define  DISP_DATA_FORMAT_DF1P2C24B (1 << 0)\n#define  DISP_DATA_FORMAT_DF1P2C18B (2 << 0)\n#define  DISP_DATA_FORMAT_DF1P2C16B (3 << 0)\n#define  DISP_DATA_FORMAT_DF2S      (4 << 0)\n#define  DISP_DATA_FORMAT_DF3S      (5 << 0)\n#define  DISP_DATA_FORMAT_DFSPI     (6 << 0)\n#define  DISP_DATA_FORMAT_DF1P3C24B (7 << 0)\n#define  DISP_DATA_FORMAT_DF1P3C18B (8 << 0)\n#define  DISP_ALIGNMENT_MSB         (0 << 8)\n#define  DISP_ALIGNMENT_LSB         (1 << 8)\n#define  DISP_ORDER_RED_BLUE        (0 << 9)\n#define  DISP_ORDER_BLUE_RED        (1 << 9)\n\n#define DC_DISP_DISP_COLOR_CONTROL 0x430\n#define  DITHER_CONTROL_MASK    (3 << 8)\n#define  DITHER_CONTROL_DISABLE (0 << 8)\n#define  DITHER_CONTROL_ORDERED (2 << 8)\n#define  DITHER_CONTROL_ERRDIFF (3 << 8)\n#define  BASE_COLOR_SIZE_MASK   (0xf << 0)\n#define  BASE_COLOR_SIZE_666    (0 << 0)\n#define  BASE_COLOR_SIZE_111    (1 << 0)\n#define  BASE_COLOR_SIZE_222    (2 << 0)\n#define  BASE_COLOR_SIZE_333    (3 << 0)\n#define  BASE_COLOR_SIZE_444    (4 << 0)\n#define  BASE_COLOR_SIZE_555    (5 << 0)\n#define  BASE_COLOR_SIZE_565    (6 << 0)\n#define  BASE_COLOR_SIZE_332    (7 << 0)\n#define  BASE_COLOR_SIZE_888    (8 << 0)\n\n#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431\n#define  SC1_H_QUALIFIER_NONE\t(1 << 16)\n#define  SC0_H_QUALIFIER_NONE\t(1 <<  0)\n\n#define DC_DISP_DATA_ENABLE_OPTIONS 0x432\n#define  DE_SELECT_ACTIVE_BLANK  (0 << 0)\n#define  DE_SELECT_ACTIVE        (1 << 0)\n#define  DE_SELECT_ACTIVE_IS     (2 << 0)\n#define  DE_CONTROL_ONECLK       (0 << 2)\n#define  DE_CONTROL_NORMAL       (1 << 2)\n#define  DE_CONTROL_EARLY_EXT    (2 << 2)\n#define  DE_CONTROL_EARLY        (3 << 2)\n#define  DE_CONTROL_ACTIVE_BLANK (4 << 2)\n\n#define DC_DISP_DC_MCCIF_FIFOCTRL 0x480\n#define DC_DISP_SD_BL_PARAMETERS 0x4D7\n#define DC_DISP_SD_BL_CONTROL 0x4DC\n#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4\n\n#define DC_WIN_CSC_YOF 0x611\n#define DC_WIN_CSC_KYRGB 0x612\n#define DC_WIN_CSC_KUR 0x613\n#define DC_WIN_CSC_KVR 0x614\n#define DC_WIN_CSC_KUG 0x615\n#define DC_WIN_CSC_KVG 0x616\n#define DC_WIN_CSC_KUB 0x617\n#define DC_WIN_CSC_KVB 0x618\n#define DC_WIN_AD_WIN_OPTIONS 0xB80\n#define DC_WIN_BD_WIN_OPTIONS 0xD80\n#define DC_WIN_CD_WIN_OPTIONS 0xF80\n\n// The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER).\n#define DC_WIN_WIN_OPTIONS 0x700\n#define  H_DIRECTION  (1 <<  0)\n#define  V_DIRECTION  (1 <<  2)\n#define  SCAN_COLUMN  (1 <<  4)\n#define  COLOR_EXPAND (1 <<  6)\n#define  CSC_ENABLE   (1 << 18)\n#define  WIN_ENABLE   (1 << 30)\n\n#define DC_WIN_COLOR_DEPTH 0x703\n#define  WIN_COLOR_DEPTH_P1             0x0\n#define  WIN_COLOR_DEPTH_P2             0x1\n#define  WIN_COLOR_DEPTH_P4             0x2\n#define  WIN_COLOR_DEPTH_P8             0x3\n#define  WIN_COLOR_DEPTH_B4G4R4A4       0x4\n#define  WIN_COLOR_DEPTH_B5G5R5A        0x5\n#define  WIN_COLOR_DEPTH_B5G6R5         0x6\n#define  WIN_COLOR_DEPTH_AB5G5R5        0x7\n#define  WIN_COLOR_DEPTH_B8G8R8A8       0xC\n#define  WIN_COLOR_DEPTH_R8G8B8A8       0xD\n#define  WIN_COLOR_DEPTH_B6x2G6x2R6x2A8 0xE\n#define  WIN_COLOR_DEPTH_R6x2G6x2B6x2A8 0xF\n#define  WIN_COLOR_DEPTH_YCbCr422       0x10\n#define  WIN_COLOR_DEPTH_YUV422         0x11\n#define  WIN_COLOR_DEPTH_YCbCr420P      0x12\n#define  WIN_COLOR_DEPTH_YUV420P        0x13\n#define  WIN_COLOR_DEPTH_YCbCr422P      0x14\n#define  WIN_COLOR_DEPTH_YUV422P        0x15\n#define  WIN_COLOR_DEPTH_YCbCr422R      0x16\n#define  WIN_COLOR_DEPTH_YUV422R        0x17\n#define  WIN_COLOR_DEPTH_YCbCr422RA     0x18\n#define  WIN_COLOR_DEPTH_YUV422RA       0x19\n\n#define DC_WIN_BUFFER_CONTROL 0x702\n#define DC_WIN_POSITION 0x704\n\n#define DC_WIN_SIZE 0x705\n#define  H_SIZE(x) (((x) & 0x1fff) <<  0)\n#define  V_SIZE(x) (((x) & 0x1fff) << 16)\n\n#define DC_WIN_PRESCALED_SIZE 0x706\n#define  H_PRESCALED_SIZE(x) (((x) & 0x7fff) <<  0)\n#define  V_PRESCALED_SIZE(x) (((x) & 0x1fff) << 16)\n\n#define DC_WIN_H_INITIAL_DDA 0x707\n#define DC_WIN_V_INITIAL_DDA 0x708\n\n#define DC_WIN_DDA_INC 0x709\n#define  H_DDA_INC(x) (((x) & 0xffff) <<  0)\n#define  V_DDA_INC(x) (((x) & 0xffff) << 16)\n\n#define DC_WIN_LINE_STRIDE 0x70A\n#define  LINE_STRIDE(x)\t   (x)\n#define  UV_LINE_STRIDE(x) (((x) & 0xffff) << 16)\n#define DC_WIN_DV_CONTROL 0x70E\n\n// The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER).\n#define DC_WINBUF_START_ADDR 0x800\n#define DC_WINBUF_ADDR_H_OFFSET 0x806\n#define DC_WINBUF_ADDR_V_OFFSET 0x808\n#define DC_WINBUF_SURFACE_KIND 0x80B\n#define  PITCH\t(0 << 0)\n#define  TILED\t(1 << 0)\n#define  BLOCK\t(2 << 0)\n#define  BLOCK_HEIGHT(x) (((x) & 0x7) << 4)\n\n/*! Display serial interface registers. */\n#define _DSIREG(reg) ((reg) * 4)\n\n#define DSI_RD_DATA 0x9\n#define DSI_WR_DATA 0xA\n\n#define DSI_POWER_CONTROL 0xB\n#define  DSI_POWER_CONTROL_ENABLE 1\n\n#define DSI_INT_ENABLE 0xC\n#define DSI_INT_STATUS 0xD\n#define DSI_INT_MASK 0xE\n\n#define DSI_HOST_CONTROL 0xF\n#define  DSI_HOST_CONTROL_FIFO_RESET   (1 << 21)\n#define  DSI_HOST_CONTROL_CRC_RESET    (1 << 20)\n#define  DSI_HOST_CONTROL_TX_TRIG_SOL  (0 << 12)\n#define  DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12)\n#define  DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12)\n#define  DSI_HOST_CONTROL_RAW          (1 << 6)\n#define  DSI_HOST_CONTROL_HS           (1 << 5)\n#define  DSI_HOST_CONTROL_FIFO_SEL     (1 << 4)\n#define  DSI_HOST_CONTROL_IMM_BTA      (1 << 3)\n#define  DSI_HOST_CONTROL_PKT_BTA      (1 << 2)\n#define  DSI_HOST_CONTROL_CS           (1 << 1)\n#define  DSI_HOST_CONTROL_ECC          (1 << 0)\n\n#define DSI_CONTROL 0x10\n#define  DSI_CONTROL_HS_CLK_CTRL  (1 << 20)\n#define  DSI_CONTROL_CHANNEL(c)   (((c) & 0x3) << 16)\n#define  DSI_CONTROL_FORMAT(f)    (((f) & 0x3) << 12)\n#define  DSI_CONTROL_TX_TRIG(x)   (((x) & 0x3) <<  8)\n#define  DSI_CONTROL_LANES(n)     (((n) & 0x3) <<  4)\n#define  DSI_CONTROL_DCS_ENABLE   (1 << 3)\n#define  DSI_CONTROL_SOURCE(s)    (((s) & 0x1) <<  2)\n#define  DSI_CONTROL_VIDEO_ENABLE (1 << 1)\n#define  DSI_CONTROL_HOST_ENABLE  (1 << 0)\n\n#define DSI_SOL_DELAY 0x11\n#define DSI_MAX_THRESHOLD 0x12\n\n#define DSI_TRIGGER 0x13\n#define  DSI_TRIGGER_HOST  (1 << 1)\n#define  DSI_TRIGGER_VIDEO (1 << 0)\n\n#define DSI_TX_CRC 0x14\n#define DSI_STATUS 0x15\n#define DSI_INIT_SEQ_CONTROL 0x1A\n#define DSI_INIT_SEQ_DATA_0 0x1B\n#define DSI_INIT_SEQ_DATA_1 0x1C\n#define DSI_INIT_SEQ_DATA_2 0x1D\n#define DSI_INIT_SEQ_DATA_3 0x1E\n#define DSI_PKT_SEQ_0_LO 0x23\n#define DSI_PKT_SEQ_0_HI 0x24\n#define DSI_PKT_SEQ_1_LO 0x25\n#define DSI_PKT_SEQ_1_HI 0x26\n#define DSI_PKT_SEQ_2_LO 0x27\n#define DSI_PKT_SEQ_2_HI 0x28\n#define DSI_PKT_SEQ_3_LO 0x29\n#define DSI_PKT_SEQ_3_HI 0x2A\n#define DSI_PKT_SEQ_4_LO 0x2B\n#define DSI_PKT_SEQ_4_HI 0x2C\n#define DSI_PKT_SEQ_5_LO 0x2D\n#define DSI_PKT_SEQ_5_HI 0x2E\n#define DSI_DCS_CMDS 0x33\n#define DSI_PKT_LEN_0_1 0x34\n#define DSI_PKT_LEN_2_3 0x35\n#define DSI_PKT_LEN_4_5 0x36\n#define DSI_PKT_LEN_6_7 0x37\n#define DSI_PHY_TIMING_0 0x3C\n#define DSI_PHY_TIMING_1 0x3D\n#define DSI_PHY_TIMING_2 0x3E\n#define DSI_BTA_TIMING 0x3F\n\n#define DSI_TIMEOUT_0 0x44\n#define  DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)\n#define  DSI_TIMEOUT_HTX(x) (((x) & 0xffff) <<  0)\n\n#define DSI_TIMEOUT_1 0x45\n#define  DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)\n#define  DSI_TIMEOUT_TA(x) (((x) & 0xffff) <<  0)\n\n#define DSI_TO_TALLY 0x46\n\n#define DSI_PAD_CONTROL_0 0x4B\n#define  DSI_PAD_CONTROL_VS1_PULLDN_CLK (1 << 24)\n#define  DSI_PAD_CONTROL_VS1_PULLDN(x)  (((x) & 0xf) << 16)\n#define  DSI_PAD_CONTROL_VS1_PDIO_CLK   (1 <<  8)\n#define  DSI_PAD_CONTROL_VS1_PDIO(x)    (((x) & 0xf) <<  0)\n\n#define DSI_PAD_CONTROL_CD 0x4C\n#define DSI_VIDEO_MODE_CONTROL 0x4E\n\n#define DSI_PAD_CONTROL_1 0x4F\n#define DSI_PAD_CONTROL_2 0x50\n\n#define DSI_PAD_CONTROL_3 0x51\n#define  DSI_PAD_PREEMP_PD_CLK(x) (((x) & 0x3) << 12)\n#define  DSI_PAD_PREEMP_PU_CLK(x) (((x) & 0x3) << 8)\n#define  DSI_PAD_PREEMP_PD(x)     (((x) & 0x3) << 4)\n#define  DSI_PAD_PREEMP_PU(x)     (((x) & 0x3) << 0)\n\n#define DSI_PAD_CONTROL_4 0x52\n#define DSI_INIT_SEQ_DATA_15 0x5F\n\n#define MIPI_CAL_MIPI_BIAS_PAD_CFG2 0x60\n\nvoid display_init();\nvoid display_backlight_pwm_init();\nvoid display_end();\n\n/*! Show one single color on the display. */\nvoid display_color_screen(u32 color);\n\n/*! Switches screen backlight ON/OFF. */\nvoid display_backlight(bool enable);\nvoid display_backlight_brightness(u32 brightness, u32 step_delay);\n\n/*! Init display in full 1280x720 resolution (B8G8R8A8, line stride 768, framebuffer size = 1280*768*4 bytes). */\nu32 *display_init_framebuffer();\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/gfx/di.inl",
    "content": "/*\n* Copyright (c) 2018 naehrwert\n* Copyright (C) 2018 CTCaer\n*\n* This program is free software; you can redistribute it and/or modify it\n* under the terms and conditions of the GNU General Public License,\n* version 2, as published by the Free Software Foundation.\n*\n* This program is distributed in the hope it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n//Clock config.\nstatic const cfg_op_t _display_config_1[4] = {\n\t{0x4E, 0x40000000}, //CLK_RST_CONTROLLER_CLK_SOURCE_DISP1\n\t{0x34, 0x4830A001}, //CLK_RST_CONTROLLER_PLLD_BASE\n\t{0x36, 0x20},       //CLK_RST_CONTROLLER_PLLD_MISC1\n\t{0x37, 0x2D0AAA}    //CLK_RST_CONTROLLER_PLLD_MISC\n};\n\n//Display A config.\nstatic const cfg_op_t _display_config_2[94] = {\n\t{DC_CMD_STATE_ACCESS, 0},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n\t{DC_CMD_REG_ACT_CONTROL, 0x54},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_DISP_DC_MCCIF_FIFOCTRL, 0},\n\t{DC_DISP_DISP_MEM_HIGH_PRIORITY, 0},\n\t{DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER, 0},\n\t{DC_CMD_DISPLAY_POWER_CONTROL, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE},\n\t{DC_CMD_GENERAL_INCR_SYNCPT_CNTRL, SYNCPT_CNTRL_NO_STALL},\n\t{DC_CMD_CONT_SYNCPT_VSYNC, SYNCPT_VSYNC_ENABLE | 0x9}, // 9: SYNCPT\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},\n\t{DC_CMD_STATE_ACCESS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_DV_CONTROL, 0},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t/* Setup default YUV colorspace conversion coefficients */\n\t{DC_WIN_CSC_YOF,   0xF0},\n\t{DC_WIN_CSC_KYRGB, 0x12A},\n\t{DC_WIN_CSC_KUR,   0},\n\t{DC_WIN_CSC_KVR,   0x198},\n\t{DC_WIN_CSC_KUG,   0x39B},\n\t{DC_WIN_CSC_KVG,   0x32F},\n\t{DC_WIN_CSC_KUB,   0x204},\n\t{DC_WIN_CSC_KVB,   0},\n\t/* End of color coefficients */\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_DV_CONTROL, 0},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t/* Setup default YUV colorspace conversion coefficients */\n\t{DC_WIN_CSC_YOF,   0xF0},\n\t{DC_WIN_CSC_KYRGB, 0x12A},\n\t{DC_WIN_CSC_KUR,   0},\n\t{DC_WIN_CSC_KVR,   0x198},\n\t{DC_WIN_CSC_KUG,   0x39B},\n\t{DC_WIN_CSC_KVG,   0x32F},\n\t{DC_WIN_CSC_KUB,   0x204},\n\t{DC_WIN_CSC_KVB,   0},\n\t/* End of color coefficients */\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_DV_CONTROL, 0},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t/* Setup default YUV colorspace conversion coefficients */\n\t{DC_WIN_CSC_YOF,   0xF0},\n\t{DC_WIN_CSC_KYRGB, 0x12A},\n\t{DC_WIN_CSC_KUR,   0},\n\t{DC_WIN_CSC_KVR,   0x198},\n\t{DC_WIN_CSC_KUG,   0x39B},\n\t{DC_WIN_CSC_KVG,   0x32F},\n\t{DC_WIN_CSC_KUB,   0x204},\n\t{DC_WIN_CSC_KVB,   0},\n\t/* End of color coefficients */\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},\n\t{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},\n\t{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},\n\t{DC_COM_PIN_OUTPUT_POLARITY(3), 0},\n\t{0x4E4, 0},\n\t{DC_COM_CRC_CONTROL, 0},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{0x716, 0x10000FF},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{0x716, 0x10000FF},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{0x716, 0x10000FF},\n\t{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ}\n};\n\n//DSI Init config.\nstatic const cfg_op_t _display_config_3[61] = { \n\t{DSI_WR_DATA, 0},\n\t{DSI_INT_ENABLE, 0},\n\t{DSI_INT_STATUS, 0},\n\t{DSI_INT_MASK, 0},\n\t{DSI_INIT_SEQ_DATA_0, 0},\n\t{DSI_INIT_SEQ_DATA_1, 0},\n\t{DSI_INIT_SEQ_DATA_2, 0},\n\t{DSI_INIT_SEQ_DATA_3, 0},\n\t{DSI_INIT_SEQ_DATA_15, 0},\n\t{DSI_DCS_CMDS, 0},\n\t{DSI_PKT_SEQ_0_LO, 0},\n\t{DSI_PKT_SEQ_1_LO, 0},\n\t{DSI_PKT_SEQ_2_LO, 0},\n\t{DSI_PKT_SEQ_3_LO, 0},\n\t{DSI_PKT_SEQ_4_LO, 0},\n\t{DSI_PKT_SEQ_5_LO, 0},\n\t{DSI_PKT_SEQ_0_HI, 0},\n\t{DSI_PKT_SEQ_1_HI, 0},\n\t{DSI_PKT_SEQ_2_HI, 0},\n\t{DSI_PKT_SEQ_3_HI, 0},\n\t{DSI_PKT_SEQ_4_HI, 0},\n\t{DSI_PKT_SEQ_5_HI, 0},\n\t{DSI_CONTROL, 0},\n\t{DSI_PAD_CONTROL_CD, 0},\n\t{DSI_SOL_DELAY, 0x18},\n\t{DSI_MAX_THRESHOLD, 0x1E0},\n\t{DSI_TRIGGER, 0},\n\t{DSI_INIT_SEQ_CONTROL, 0},\n\t{DSI_PKT_LEN_0_1, 0},\n\t{DSI_PKT_LEN_2_3, 0},\n\t{DSI_PKT_LEN_4_5, 0},\n\t{DSI_PKT_LEN_6_7, 0},\n\t{DSI_PAD_CONTROL_1, 0},\n\t{DSI_PHY_TIMING_0, 0x6070601},\n\t{DSI_PHY_TIMING_1, 0x40A0E05},\n\t{DSI_PHY_TIMING_2, 0x30109},\n\t{DSI_BTA_TIMING, 0x190A14},\n\t{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},\n\t{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},\n\t{DSI_TO_TALLY, 0},\n\t{DSI_PAD_CONTROL_0, DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0)}, // Enable\n\t{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},\n\t{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},\n\t{DSI_POWER_CONTROL, 0},\n\t{DSI_POWER_CONTROL, 0},\n\t{DSI_PAD_CONTROL_1, 0},\n\t{DSI_PHY_TIMING_0, 0x6070601},\n\t{DSI_PHY_TIMING_1, 0x40A0E05},\n\t{DSI_PHY_TIMING_2, 0x30118},\n\t{DSI_BTA_TIMING, 0x190A14},\n\t{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},\n\t{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},\n\t{DSI_TO_TALLY, 0},\n\t{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},\n\t{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},\n\t{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},\n\t{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},\n\t{DSI_MAX_THRESHOLD, 0x40},\n\t{DSI_TRIGGER, 0},\n\t{DSI_TX_CRC, 0},\n\t{DSI_INIT_SEQ_CONTROL, 0}\n};\n\n//DSI config (if ver == 0x10).\nstatic const cfg_op_t _display_config_4[43] = {\n\t{DSI_WR_DATA, 0x439},\n\t{DSI_WR_DATA, 0x9483FFB9},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0xBD15},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0x1939},\n\t{DSI_WR_DATA, 0xAAAAAAD8},\n\t{DSI_WR_DATA, 0xAAAAAAEB},\n\t{DSI_WR_DATA, 0xAAEBAAAA},\n\t{DSI_WR_DATA, 0xAAAAAAAA},\n\t{DSI_WR_DATA, 0xAAAAAAEB},\n\t{DSI_WR_DATA, 0xAAEBAAAA},\n\t{DSI_WR_DATA, 0xAA},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0x1BD15},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0x2739},\n\t{DSI_WR_DATA, 0xFFFFFFD8},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFF},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0x2BD15},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0xF39},\n\t{DSI_WR_DATA, 0xFFFFFFD8},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFF},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0xBD15},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0x6D915},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0x439},\n\t{DSI_WR_DATA, 0xB9},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST}\n};\n\n//DSI config.\nstatic const cfg_op_t _display_config_5[21] = {\n\t{DSI_PAD_CONTROL_1, 0},\n\t{DSI_PHY_TIMING_0, 0x6070601},\n\t{DSI_PHY_TIMING_1, 0x40A0E05},\n\t{DSI_PHY_TIMING_2, 0x30172},\n\t{DSI_BTA_TIMING, 0x190A14},\n\t{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xA40)},\n\t{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},\n\t{DSI_TO_TALLY, 0},\n\t{DSI_PKT_SEQ_0_LO, 0x40000208},\n\t{DSI_PKT_SEQ_2_LO, 0x40000308},\n\t{DSI_PKT_SEQ_4_LO, 0x40000308},\n\t{DSI_PKT_SEQ_1_LO, 0x40000308},\n\t{DSI_PKT_SEQ_3_LO, 0x3F3B2B08},\n\t{DSI_PKT_SEQ_3_HI, 0x2CC},\n\t{DSI_PKT_SEQ_5_LO, 0x3F3B2B08},\n\t{DSI_PKT_SEQ_5_HI, 0x2CC},\n\t{DSI_PKT_LEN_0_1, 0xCE0000},\n\t{DSI_PKT_LEN_2_3, 0x87001A2},\n\t{DSI_PKT_LEN_4_5, 0x190},\n\t{DSI_PKT_LEN_6_7, 0x190},\n\t{DSI_HOST_CONTROL, 0},\n};\n\n//Clock config.\nstatic const cfg_op_t _display_config_6[3] = {\n\t{0x34, 0x4810C001}, //CLK_RST_CONTROLLER_PLLD_BASE\n\t{0x36, 0x20},       //CLK_RST_CONTROLLER_PLLD_MISC1\n\t{0x37, 0x2DFC00}    //CLK_RST_CONTROLLER_PLLD_MISC\n};\n\n//DSI config.\nstatic const cfg_op_t _display_config_7[10] = {\n\t{DSI_TRIGGER, 0},\n\t{DSI_CONTROL, 0},\n\t{DSI_SOL_DELAY, 6},\n\t{DSI_MAX_THRESHOLD, 0x1E0},\n\t{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},\n\t{DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},\n\t{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_FIFO_SEL| DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},\n\t{DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},\n\t{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},\n\t{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}\n};\n\n//MIPI CAL config.\nstatic const cfg_op_t _display_config_8[6] = {\n\t{0x18, 0},          // MIPI_CAL_MIPI_BIAS_PAD_CFG2\n\t{0x02, 0xF3F10000}, // MIPI_CAL_CIL_MIPI_CAL_STATUS\n\t{0x16, 0},          // MIPI_CAL_MIPI_BIAS_PAD_CFG0\n\t{0x18, 0},          // MIPI_CAL_MIPI_BIAS_PAD_CFG2\n\t{0x18, 0x10010},    // MIPI_CAL_MIPI_BIAS_PAD_CFG2\n\t{0x17, 0x300}       // MIPI_CAL_MIPI_BIAS_PAD_CFG1\n};\n\n//DSI config.\nstatic const cfg_op_t _display_config_9[4] = {\n\t{DSI_PAD_CONTROL_1, 0},\n\t{DSI_PAD_CONTROL_2, 0},\n\t{DSI_PAD_CONTROL_3, DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3)},\n\t{DSI_PAD_CONTROL_4, 0}\n};\n\n//MIPI CAL config.\nstatic const cfg_op_t _display_config_10[16] = {\n\t{0x0E, 0x200200}, // MIPI_CAL_DSIA_MIPI_CAL_CONFIG\n\t{0x0F, 0x200200}, // MIPI_CAL_DSIB_MIPI_CAL_CONFIG\n\t{0x19, 0x200002}, // MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2\n\t{0x1A, 0x200002}, // MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2\n\t{0x05, 0},        // MIPI_CAL_CILA_MIPI_CAL_CONFIG\n\t{0x06, 0},        // MIPI_CAL_CILB_MIPI_CAL_CONFIG\n\t{0x07, 0},        // MIPI_CAL_CILC_MIPI_CAL_CONFIG\n\t{0x08, 0},        // MIPI_CAL_CILD_MIPI_CAL_CONFIG\n\t{0x09, 0},        // MIPI_CAL_CILE_MIPI_CAL_CONFIG\n\t{0x0A, 0},        // MIPI_CAL_CILF_MIPI_CAL_CONFIG\n\t{0x10, 0},        // MIPI_CAL_DSIC_MIPI_CAL_CONFIG\n\t{0x11, 0},        // MIPI_CAL_DSID_MIPI_CAL_CONFIG\n\t{0x1A, 0},        // MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2\n\t{0x1C, 0},        // MIPI_CAL_DSIC_MIPI_CAL_CONFIG_2\n\t{0x1D, 0},        // MIPI_CAL_DSID_MIPI_CAL_CONFIG_2\n\t{0, 0x2A000001}   // MIPI_CAL_DSIA_MIPI_CAL_CONFIG\n};\n\n//Display A config.\nstatic const cfg_op_t _display_config_11[113] = {\n\t{DC_CMD_STATE_ACCESS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_DV_CONTROL, 0},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t/* Setup default YUV colorspace conversion coefficients */\n\t{DC_WIN_CSC_YOF,   0xF0},\n\t{DC_WIN_CSC_KYRGB, 0x12A},\n\t{DC_WIN_CSC_KUR,   0},\n\t{DC_WIN_CSC_KVR,   0x198},\n\t{DC_WIN_CSC_KUG,   0x39B},\n\t{DC_WIN_CSC_KVG,   0x32F},\n\t{DC_WIN_CSC_KUB,   0x204},\n\t{DC_WIN_CSC_KVB,   0},\n\t/* End of color coefficients */\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_DV_CONTROL, 0},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t/* Setup default YUV colorspace conversion coefficients */\n\t{DC_WIN_CSC_YOF,   0xF0},\n\t{DC_WIN_CSC_KYRGB, 0x12A},\n\t{DC_WIN_CSC_KUR,   0},\n\t{DC_WIN_CSC_KVR,   0x198},\n\t{DC_WIN_CSC_KUG,   0x39B},\n\t{DC_WIN_CSC_KVG,   0x32F},\n\t{DC_WIN_CSC_KUB,   0x204},\n\t{DC_WIN_CSC_KVB,   0},\n\t/* End of color coefficients */\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_DV_CONTROL, 0},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t/* Setup default YUV colorspace conversion coefficients */\n\t{DC_WIN_CSC_YOF,   0xF0},\n\t{DC_WIN_CSC_KYRGB, 0x12A},\n\t{DC_WIN_CSC_KUR,   0},\n\t{DC_WIN_CSC_KVR,   0x198},\n\t{DC_WIN_CSC_KUG,   0x39B},\n\t{DC_WIN_CSC_KVG,   0x32F},\n\t{DC_WIN_CSC_KUB,   0x204},\n\t{DC_WIN_CSC_KVB,   0},\n\t/* End of color coefficients */\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},\n\t{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},\n\t{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},\n\t{DC_COM_PIN_OUTPUT_POLARITY(3), 0},\n\t{0x4E4, 0},\n\t{DC_COM_CRC_CONTROL, 0},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{0x716, 0x10000FF},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{0x716, 0x10000FF},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{0x716, 0x10000FF},\n\t{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},\n\t{DC_CMD_STATE_ACCESS, 0},\n\t/* Set Display timings */\n\t{DC_DISP_DISP_TIMING_OPTIONS, 0},\n\t{DC_DISP_REF_TO_SYNC, (1 << 16)}, // h_ref_to_sync = 0, v_ref_to_sync = 1.\n\t{DC_DISP_SYNC_WIDTH,  0x10048},\n\t{DC_DISP_BACK_PORCH,  0x90048},\n\t{DC_DISP_ACTIVE,      0x50002D0},\n\t{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd.\n\t/* End of Display timings */\n\t{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},\n\t{DC_COM_PIN_OUTPUT_ENABLE(1), 0},\n\t{DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},\n\t{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},\n\t{DC_DISP_DISP_CLOCK_CONTROL, 0},\n\t{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n\t{DC_CMD_STATE_ACCESS, READ_MUX | WRITE_MUX},\n\t{DC_DISP_FRONT_PORCH, 0xA0088},\n\t{DC_CMD_STATE_ACCESS, 0},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n\t{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},\n\t{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n\t{DC_CMD_STATE_ACCESS, 0},\n\t{DC_DISP_DISP_CLOCK_CONTROL, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4)},\n\t{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},\n\t{DC_CMD_DISPLAY_COMMAND_OPTION0, 0}\n};\n\n////Display A config.\nstatic const cfg_op_t _display_config_12[17] = {\n\t{DC_DISP_FRONT_PORCH, 0xA0088},\n\t{DC_CMD_INT_MASK, 0},\n\t{DC_CMD_STATE_ACCESS, 0},\n\t{DC_CMD_INT_ENABLE, 0},\n\t{DC_CMD_CONT_SYNCPT_VSYNC, 0},\n\t{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n\t{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},\n\t{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n\t{DC_CMD_DISPLAY_POWER_CONTROL, 0},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n};\n\n//DSI config.\nstatic const cfg_op_t _display_config_13[16] = {\n\t{DSI_POWER_CONTROL, 0},\n\t{DSI_PAD_CONTROL_1, 0},\n\t{DSI_PHY_TIMING_0, 0x6070601},\n\t{DSI_PHY_TIMING_1, 0x40A0E05},\n\t{DSI_PHY_TIMING_2, 0x30118},\n\t{DSI_BTA_TIMING, 0x190A14},\n\t{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF) },\n\t{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},\n\t{DSI_TO_TALLY, 0},\n\t{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},\n\t{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},\n\t{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},\n\t{DSI_MAX_THRESHOLD, 0x40},\n\t{DSI_TRIGGER, 0},\n\t{DSI_TX_CRC, 0},\n\t{DSI_INIT_SEQ_CONTROL, 0}\n};\n\n//DSI config (if ver == 0x10).\nstatic const cfg_op_t _display_config_14[22] = {\n\t{DSI_WR_DATA, 0x439},\n\t{DSI_WR_DATA, 0x9483FFB9},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0x2139},\n\t{DSI_WR_DATA, 0x191919D5},\n\t{DSI_WR_DATA, 0x19191919},\n\t{DSI_WR_DATA, 0x19191919},\n\t{DSI_WR_DATA, 0x19191919},\n\t{DSI_WR_DATA, 0x19191919},\n\t{DSI_WR_DATA, 0x19191919},\n\t{DSI_WR_DATA, 0x19191919},\n\t{DSI_WR_DATA, 0x19191919},\n\t{DSI_WR_DATA, 0x19},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0xB39},\n\t{DSI_WR_DATA, 0x4F0F41B1},\n\t{DSI_WR_DATA, 0xF179A433},\n\t{DSI_WR_DATA, 0x2D81},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0x439},\n\t{DSI_WR_DATA, 0xB9},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST}\n};\n\n//Display A config.\nstatic const cfg_op_t cfg_display_one_color[8] = {\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, //Enable window A.\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, //Enable window B.\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, //Enable window C.\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE\n\t{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY} //DISPLAY_CTRL_MODE: continuous display.\n};\n\n//Display A config.\nstatic const cfg_op_t cfg_display_framebuffer[32] = {\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, //Enable window C.\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, //Enable window B.\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, //Enable window A.\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE\n\t{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, //T_A8R8G8B8 //NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_WIN_POSITION, 0}, //(0,0)\n\t{DC_WIN_H_INITIAL_DDA, 0},\n\t{DC_WIN_V_INITIAL_DDA, 0},\n\t{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(2880)}, //Pre-scaled size: 1280x2880 bytes.\n\t{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)},\n\t{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)}, //Window size: 1280 vertical lines x 720 horizontal pixels.\n\t{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.\n\t{DC_WIN_BUFFER_CONTROL, 0},\n\t{DC_WINBUF_SURFACE_KIND, 0}, //Regular surface.\n\t{DC_WINBUF_START_ADDR, FB_ADDRESS}, //Framebuffer address.\n\t{DC_WINBUF_ADDR_H_OFFSET, 0},\n\t{DC_WINBUF_ADDR_V_OFFSET, 0},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE\n\t{DC_WIN_WIN_OPTIONS, WIN_ENABLE}, //Enable window AD.\n\t{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, //DISPLAY_CTRL_MODE: continuous display.\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE}, //General update; window A update.\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ} //General activation request; window A activation request.\n};\n"
  },
  {
    "path": "argon-first-stage/include/gfx/gfx.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018 CTCaer\n * Copyright (C) 2018 M4xw\n * Copyright (C) 2018 Guillem96\n * \n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _GFX_H_\n#define _GFX_H_\n\n#include \"utils/types.h\"\n\n#define RED 0xFF0000FF\n#define GREEN 0xFF00FF00\n#define BLUE 0xFFFF0000\n#define YELLOW 0xFF00FFFF\n#define ORANGE 0xFF3891FF\n#define WHITE 0xFFFFFFFF\n#define BLACK 0xFF000000\n\n#define CHAR_WIDTH 8\n#define CHAR_HEIGHT 8\n\ntypedef struct _gfx_ctxt_t\n{\n\tu32 *fb;\n    u32* next;\n\tu32 width;\n\tu32 height;\n\tu32 stride;\n} gfx_ctxt_t;\n\ntypedef struct _gfx_con_t\n{\n\tgfx_ctxt_t *gfx_ctxt;\n    u8 scale;\n\tu32 fntsz;\n\tu32 x;\n\tu32 y;\n\tu32 savedx;\n\tu32 savedy;\n\tu32 fgcol;\n\tint fillbg;\n\tu32 bgcol;\n\tbool mute;\n} gfx_con_t;\n\ntypedef struct \n{\n    u32 size;\n    u32 size_x;\n    u32 size_y;\n    u32 offset;\n    u32 pos_x;\n    u32 pos_y;\n} bmp_data_t;\n\n\n#define FB_ADDRESS 0xC0000000\n\nvoid gfx_init_ctxt(u32 *fb, u32 width, u32 height, u32 stride);\nvoid gfx_clear_grey(u8 color);\nvoid gfx_clear_partial_grey(u8 color, u32 pos_x, u32 height);\nvoid gfx_clear_color(u32 color);\nvoid gfx_con_init();\nvoid gfx_con_setcol(u32 fgcol, int fillbg, u32 bgcol);\nvoid gfx_con_getpos(u32 *x, u32 *y);\nvoid gfx_con_setpos(u32 x, u32 y);\nvoid gfx_putc(char c);\nvoid gfx_puts(const char *s);\nvoid gfx_printf(const char *fmt, ...);\nvoid gfx_hexdump(u32 base, const u8 *buf, u32 len);\n\nvoid gfx_set_pixel(u32 x, u32 y, u32 color);\nvoid gfx_line(int x0, int y0, int x1, int y1, u32 color);\nvoid gfx_put_small_sep();\nvoid gfx_put_big_sep();\nvoid gfx_set_rect_grey(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);\nvoid gfx_set_rect_rgb(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);\nvoid gfx_set_rect_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);\nvoid gfx_render_bmp_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);\nvoid gfx_render_splash(u8 *bitmap);\n\n// Global gfx console and context.\ngfx_ctxt_t g_gfx_ctxt;\ngfx_con_t g_gfx_con;\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/ianos/ianos.h",
    "content": "/*\n * Copyright (c) 2018 M4xw\n * Copyright (c) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef IANOS_H\n#define IANOS_H\n\n#include <stdint.h>\n#include \"utils/types.h\"\n\ntypedef enum\n{\n\tDRAM_LIB = 0, // DRAM library.\n\tEXEC_ELF = 1, // Executable elf that does not return.\n\tDR64_LIB = 2, // AARCH64 DRAM library.\n\tAR64_ELF = 3, // Executable elf that does not return.\n\tKEEP_IN_RAM = (1 << 31)  // Shared library mask.\n} elfType_t;\n\nuintptr_t ianos_loader(bool sdmount, char *path, elfType_t type, void* config);\n\n#endif"
  },
  {
    "path": "argon-first-stage/include/libs/compr/blz.h",
    "content": "/*\n * Copyright (c) 2018 rajkosto\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _BLZ_H_\n#define _BLZ_H_\n\n#include \"utils/types.h\"\n\ntypedef struct _blz_footer\n{\n\tu32 cmp_and_hdr_size;\n\tu32 header_size;\n\tu32 addl_size;\n} blz_footer;\n\n// Returns pointer to footer in compData if present, additionally copies it to outFooter if not NULL.\nconst blz_footer *blz_get_footer(const unsigned char *compData, unsigned int compDataLen, blz_footer *outFooter);\n// Returns 0 on failure.\nint blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const blz_footer *footer);\n// Returns 0 on failure.\nint blz_uncompress_srcdest(const unsigned char *compData, unsigned int compDataLen, unsigned char *dstData, unsigned int dstSize);\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/libs/compr/lz.h",
    "content": "/*************************************************************************\n* Name:        lz.h\n* Author:      Marcus Geelnard\n* Description: LZ77 coder/decoder interface.\n* Reentrant:   Yes\n*-------------------------------------------------------------------------\n* Copyright (c) 2003-2006 Marcus Geelnard\n*\n* This software is provided 'as-is', without any express or implied\n* warranty. In no event will the authors be held liable for any damages\n* arising from the use of this software.\n*\n* Permission is granted to anyone to use this software for any purpose,\n* including commercial applications, and to alter it and redistribute it\n* freely, subject to the following restrictions:\n*\n* 1. The origin of this software must not be misrepresented; you must not\n*    claim that you wrote the original software. If you use this software\n*    in a product, an acknowledgment in the product documentation would\n*    be appreciated but is not required.\n*\n* 2. Altered source versions must be plainly marked as such, and must not\n*    be misrepresented as being the original software.\n*\n* 3. This notice may not be removed or altered from any source\n*    distribution.\n*\n* Marcus Geelnard\n* marcus.geelnard at home.se\n*************************************************************************/\n\n#ifndef _lz_h_\n#define _lz_h_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/*************************************************************************\n* Function prototypes\n*************************************************************************/\n\nvoid LZ_Uncompress( const unsigned char *in, unsigned char *out,\n                    unsigned int insize );\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _lz_h_ */\n"
  },
  {
    "path": "argon-first-stage/include/libs/elfload/elf.h",
    "content": "/*    $OpenBSD: exec_elf.h,v 1.53 2014/01/03 03:00:39 guenther Exp $    */\n/*\n * Copyright (c) 1995, 1996 Erik Theisen.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/* imported sys/exec_elf.h from OpenBSD */\n\n#ifndef ELF_H\n#define ELF_H\n#include <stdint.h>\n\ntypedef uint8_t Elf_Byte;\n\ntypedef uint32_t Elf32_Addr; /* Unsigned program address */\ntypedef uint32_t Elf32_Off;  /* Unsigned file offset */\ntypedef int32_t Elf32_Sword; /* Signed large integer */\ntypedef uint32_t Elf32_Word; /* Unsigned large integer */\ntypedef uint16_t Elf32_Half; /* Unsigned medium integer */\n\ntypedef uint64_t Elf64_Addr;\ntypedef uint64_t Elf64_Off;\ntypedef int32_t Elf64_Shalf;\n\n#ifdef __alpha__\ntypedef int64_t Elf64_Sword;\ntypedef uint64_t Elf64_Word;\n#else\ntypedef int32_t Elf64_Sword;\ntypedef uint32_t Elf64_Word;\n#endif\n\ntypedef int64_t Elf64_Sxword;\ntypedef uint64_t Elf64_Xword;\n\ntypedef uint32_t Elf64_Half;\ntypedef uint16_t Elf64_Quarter;\n\n/*\n * e_ident[] identification indexes\n * See http://www.sco.com/developers/gabi/latest/ch4.eheader.html\n */\n#define EI_MAG0 0       /* file ID */\n#define EI_MAG1 1       /* file ID */\n#define EI_MAG2 2       /* file ID */\n#define EI_MAG3 3       /* file ID */\n#define EI_CLASS 4      /* file class */\n#define EI_DATA 5       /* data encoding */\n#define EI_VERSION 6    /* ELF header version */\n#define EI_OSABI 7      /* OS/ABI ID */\n#define EI_ABIVERSION 8 /* ABI version */\n#define EI_PAD 9        /* start of pad bytes */\n#define EI_NIDENT 16    /* Size of e_ident[] */\n\n/* e_ident[] magic number */\n#define ELFMAG0 0x7f     /* e_ident[EI_MAG0] */\n#define ELFMAG1 'E'      /* e_ident[EI_MAG1] */\n#define ELFMAG2 'L'      /* e_ident[EI_MAG2] */\n#define ELFMAG3 'F'      /* e_ident[EI_MAG3] */\n#define ELFMAG \"\\177ELF\" /* magic */\n#define SELFMAG 4        /* size of magic */\n\n/* e_ident[] file class */\n#define ELFCLASSNONE 0 /* invalid */\n#define ELFCLASS32 1   /* 32-bit objs */\n#define ELFCLASS64 2   /* 64-bit objs */\n#define ELFCLASSNUM 3  /* number of classes */\n\n/* e_ident[] data encoding */\n#define ELFDATANONE 0 /* invalid */\n#define ELFDATA2LSB 1 /* Little-Endian */\n#define ELFDATA2MSB 2 /* Big-Endian */\n#define ELFDATANUM 3  /* number of data encode defines */\n\n/* e_ident[] Operating System/ABI */\n#define ELFOSABI_SYSV 0         /* UNIX System V ABI */\n#define ELFOSABI_HPUX 1         /* HP-UX operating system */\n#define ELFOSABI_NETBSD 2       /* NetBSD */\n#define ELFOSABI_LINUX 3        /* GNU/Linux */\n#define ELFOSABI_HURD 4         /* GNU/Hurd */\n#define ELFOSABI_86OPEN 5       /* 86Open common IA32 ABI */\n#define ELFOSABI_SOLARIS 6      /* Solaris */\n#define ELFOSABI_MONTEREY 7     /* Monterey */\n#define ELFOSABI_IRIX 8         /* IRIX */\n#define ELFOSABI_FREEBSD 9      /* FreeBSD */\n#define ELFOSABI_TRU64 10       /* TRU64 UNIX */\n#define ELFOSABI_MODESTO 11     /* Novell Modesto */\n#define ELFOSABI_OPENBSD 12     /* OpenBSD */\n#define ELFOSABI_ARM 97         /* ARM */\n#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */\n\n/* e_ident */\n#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \\\n                      (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \\\n                      (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \\\n                      (ehdr).e_ident[EI_MAG3] == ELFMAG3)\n\n/* ELF Header */\ntypedef struct\n{\n    unsigned char e_ident[EI_NIDENT]; /* ELF Identification */\n    Elf32_Half e_type;                /* object file type */\n    Elf32_Half e_machine;             /* machine */\n    Elf32_Word e_version;             /* object file version */\n    Elf32_Addr e_entry;               /* virtual entry point */\n    Elf32_Off e_phoff;                /* program header table offset */\n    Elf32_Off e_shoff;                /* section header table offset */\n    Elf32_Word e_flags;               /* processor-specific flags */\n    Elf32_Half e_ehsize;              /* ELF header size */\n    Elf32_Half e_phentsize;           /* program header entry size */\n    Elf32_Half e_phnum;               /* number of program header entries */\n    Elf32_Half e_shentsize;           /* section header entry size */\n    Elf32_Half e_shnum;               /* number of section header entries */\n    Elf32_Half e_shstrndx;            /* section header table's \"section\n                                                header string table\" entry offset */\n} Elf32_Ehdr;\n\ntypedef struct\n{\n    unsigned char e_ident[EI_NIDENT]; /* Id bytes */\n    Elf64_Quarter e_type;             /* file type */\n    Elf64_Quarter e_machine;          /* machine type */\n    Elf64_Half e_version;             /* version number */\n    Elf64_Addr e_entry;               /* entry point */\n    Elf64_Off e_phoff;                /* Program hdr offset */\n    Elf64_Off e_shoff;                /* Section hdr offset */\n    Elf64_Half e_flags;               /* Processor flags */\n    Elf64_Quarter e_ehsize;           /* sizeof ehdr */\n    Elf64_Quarter e_phentsize;        /* Program header entry size */\n    Elf64_Quarter e_phnum;            /* Number of program headers */\n    Elf64_Quarter e_shentsize;        /* Section header entry size */\n    Elf64_Quarter e_shnum;            /* Number of section headers */\n    Elf64_Quarter e_shstrndx;         /* String table index */\n} Elf64_Ehdr;\n\n/* e_type */\n#define ET_NONE 0        /* No file type */\n#define ET_REL 1         /* relocatable file */\n#define ET_EXEC 2        /* executable file */\n#define ET_DYN 3         /* shared object file */\n#define ET_CORE 4        /* core file */\n#define ET_NUM 5         /* number of types */\n#define ET_LOPROC 0xff00 /* reserved range for processor */\n#define ET_HIPROC 0xffff /*  specific e_type */\n\n/* e_machine */\n#define EM_NONE 0  /* No Machine */\n#define EM_M32 1   /* AT&T WE 32100 */\n#define EM_SPARC 2 /* SPARC */\n#define EM_386 3   /* Intel 80386 */\n#define EM_68K 4   /* Motorola 68000 */\n#define EM_88K 5   /* Motorola 88000 */\n#define EM_486 6   /* Intel 80486 - unused? */\n#define EM_860 7   /* Intel 80860 */\n#define EM_MIPS 8  /* MIPS R3000 Big-Endian only */\n/*\n * Don't know if EM_MIPS_RS4_BE,\n * EM_SPARC64, EM_PARISC,\n * or EM_PPC are ABI compliant\n */\n#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */\n#define EM_SPARC64 11     /* SPARC v9 64-bit unofficial */\n#define EM_PARISC 15      /* HPPA */\n#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */\n#define EM_PPC 20         /* PowerPC */\n#define EM_ARM 40         /* ARM AArch32 */\n#define EM_ALPHA 41       /* DEC ALPHA */\n#define EM_SH 42          /* Hitachi/Renesas Super-H */\n#define EM_SPARCV9 43     /* SPARC version 9 */\n#define EM_IA_64 50       /* Intel IA-64 Processor */\n#define EM_AMD64 62       /* AMD64 architecture */\n#define EM_VAX 75         /* DEC VAX */\n#define EM_AARCH64 183    /* ARM AArch64 */\n\n/* Non-standard */\n#define EM_ALPHA_EXP 0x9026 /* DEC ALPHA */\n\n/* Version */\n#define EV_NONE 0    /* Invalid */\n#define EV_CURRENT 1 /* Current */\n#define EV_NUM 2     /* number of versions */\n\n/* Section Header */\ntypedef struct\n{\n    Elf32_Word sh_name;      /* name - index into section header\n                                 * string table section */\n    Elf32_Word sh_type;      /* type */\n    Elf32_Word sh_flags;     /* flags */\n    Elf32_Addr sh_addr;      /* address */\n    Elf32_Off sh_offset;     /* file offset */\n    Elf32_Word sh_size;      /* section size */\n    Elf32_Word sh_link;      /* section header table index link */\n    Elf32_Word sh_info;      /* extra information */\n    Elf32_Word sh_addralign; /* address alignment */\n    Elf32_Word sh_entsize;   /* section entry size */\n} Elf32_Shdr;\n\ntypedef struct\n{\n    Elf64_Half sh_name;       /* section name */\n    Elf64_Half sh_type;       /* section type */\n    Elf64_Xword sh_flags;     /* section flags */\n    Elf64_Addr sh_addr;       /* virtual address */\n    Elf64_Off sh_offset;      /* file offset */\n    Elf64_Xword sh_size;      /* section size */\n    Elf64_Half sh_link;       /* link to another */\n    Elf64_Half sh_info;       /* misc info */\n    Elf64_Xword sh_addralign; /* memory alignment */\n    Elf64_Xword sh_entsize;   /* table entry size */\n} Elf64_Shdr;\n\n/* Special Section Indexes */\n#define SHN_UNDEF 0          /* undefined */\n#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */\n#define SHN_LOPROC 0xff00    /* reserved range for processor */\n#define SHN_HIPROC 0xff1f    /*   specific section indexes */\n#define SHN_ABS 0xfff1       /* absolute value */\n#define SHN_COMMON 0xfff2    /* common symbol */\n#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */\n\n/* sh_type */\n#define SHT_NULL 0            /* inactive */\n#define SHT_PROGBITS 1        /* program defined information */\n#define SHT_SYMTAB 2          /* symbol table section */\n#define SHT_STRTAB 3          /* string table section */\n#define SHT_RELA 4            /* relocation section with addends*/\n#define SHT_HASH 5            /* symbol hash table section */\n#define SHT_DYNAMIC 6         /* dynamic section */\n#define SHT_NOTE 7            /* note section */\n#define SHT_NOBITS 8          /* no space section */\n#define SHT_REL 9             /* relation section without addends */\n#define SHT_SHLIB 10          /* reserved - purpose unknown */\n#define SHT_DYNSYM 11         /* dynamic symbol table section */\n#define SHT_NUM 12            /* number of section types */\n#define SHT_LOPROC 0x70000000 /* reserved range for processor */\n#define SHT_HIPROC 0x7fffffff /*  specific section header types */\n#define SHT_LOUSER 0x80000000 /* reserved range for application */\n#define SHT_HIUSER 0xffffffff /*  specific indexes */\n\n/* Section names */\n#define ELF_BSS \".bss\"               /* uninitialized data */\n#define ELF_DATA \".data\"             /* initialized data */\n#define ELF_DEBUG \".debug\"           /* debug */\n#define ELF_DYNAMIC \".dynamic\"       /* dynamic linking information */\n#define ELF_DYNSTR \".dynstr\"         /* dynamic string table */\n#define ELF_DYNSYM \".dynsym\"         /* dynamic symbol table */\n#define ELF_FINI \".fini\"             /* termination code */\n#define ELF_GOT \".got\"               /* global offset table */\n#define ELF_HASH \".hash\"             /* symbol hash table */\n#define ELF_INIT \".init\"             /* initialization code */\n#define ELF_REL_DATA \".rel.data\"     /* relocation data */\n#define ELF_REL_FINI \".rel.fini\"     /* relocation termination code */\n#define ELF_REL_INIT \".rel.init\"     /* relocation initialization code */\n#define ELF_REL_DYN \".rel.dyn\"       /* relocation dynamic link info */\n#define ELF_REL_RODATA \".rel.rodata\" /* relocation read-only data */\n#define ELF_REL_TEXT \".rel.text\"     /* relocation code */\n#define ELF_RODATA \".rodata\"         /* read-only data */\n#define ELF_SHSTRTAB \".shstrtab\"     /* section header string table */\n#define ELF_STRTAB \".strtab\"         /* string table */\n#define ELF_SYMTAB \".symtab\"         /* symbol table */\n#define ELF_TEXT \".text\"             /* code */\n\n/* Section Attribute Flags - sh_flags */\n#define SHF_WRITE 0x1           /* Writable */\n#define SHF_ALLOC 0x2           /* occupies memory */\n#define SHF_EXECINSTR 0x4       /* executable */\n#define SHF_TLS 0x400           /* thread local storage */\n#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor \\\n                                 *  specific section attributes */\n\n/* Symbol Table Entry */\ntypedef struct elf32_sym\n{\n    Elf32_Word st_name;     /* name - index into string table */\n    Elf32_Addr st_value;    /* symbol value */\n    Elf32_Word st_size;     /* symbol size */\n    unsigned char st_info;  /* type and binding */\n    unsigned char st_other; /* 0 - no defined meaning */\n    Elf32_Half st_shndx;    /* section header index */\n} Elf32_Sym;\n\ntypedef struct\n{\n    Elf64_Half st_name;     /* Symbol name index in str table */\n    Elf_Byte st_info;       /* type / binding attrs */\n    Elf_Byte st_other;      /* unused */\n    Elf64_Quarter st_shndx; /* section index of symbol */\n    Elf64_Xword st_value;   /* value of symbol */\n    Elf64_Xword st_size;    /* size of symbol */\n} Elf64_Sym;\n\n/* Symbol table index */\n#define STN_UNDEF 0 /* undefined */\n\n/* Extract symbol info - st_info */\n#define ELF32_ST_BIND(x) ((x) >> 4)\n#define ELF32_ST_TYPE(x) (((unsigned int)x) & 0xf)\n#define ELF32_ST_INFO(b, t) (((b) << 4) + ((t)&0xf))\n\n#define ELF64_ST_BIND(x) ((x) >> 4)\n#define ELF64_ST_TYPE(x) (((unsigned int)x) & 0xf)\n#define ELF64_ST_INFO(b, t) (((b) << 4) + ((t)&0xf))\n\n/* Symbol Binding - ELF32_ST_BIND - st_info */\n#define STB_LOCAL 0   /* Local symbol */\n#define STB_GLOBAL 1  /* Global symbol */\n#define STB_WEAK 2    /* like global - lower precedence */\n#define STB_NUM 3     /* number of symbol bindings */\n#define STB_LOPROC 13 /* reserved range for processor */\n#define STB_HIPROC 15 /*  specific symbol bindings */\n\n/* Symbol type - ELF32_ST_TYPE - st_info */\n#define STT_NOTYPE 0  /* not specified */\n#define STT_OBJECT 1  /* data object */\n#define STT_FUNC 2    /* function */\n#define STT_SECTION 3 /* section */\n#define STT_FILE 4    /* file */\n#define STT_TLS 6     /* thread local storage */\n#define STT_LOPROC 13 /* reserved range for processor */\n#define STT_HIPROC 15 /*  specific symbol types */\n\n/* Relocation entry with implicit addend */\ntypedef struct\n{\n    Elf32_Addr r_offset; /* offset of relocation */\n    Elf32_Word r_info;   /* symbol table index and type */\n} Elf32_Rel;\n\n/* Relocation entry with explicit addend */\ntypedef struct\n{\n    Elf32_Addr r_offset; /* offset of relocation */\n    Elf32_Word r_info;   /* symbol table index and type */\n    Elf32_Sword r_addend;\n} Elf32_Rela;\n\n/* Extract relocation info - r_info */\n#define ELF32_R_SYM(i) ((i) >> 8)\n#define ELF32_R_TYPE(i) ((unsigned char)(i))\n#define ELF32_R_INFO(s, t) (((s) << 8) + (unsigned char)(t))\n\ntypedef struct\n{\n    Elf64_Xword r_offset; /* where to do it */\n    Elf64_Xword r_info;   /* index & type of relocation */\n} Elf64_Rel;\n\ntypedef struct\n{\n    Elf64_Xword r_offset;  /* where to do it */\n    Elf64_Xword r_info;    /* index & type of relocation */\n    Elf64_Sxword r_addend; /* adjustment value */\n} Elf64_Rela;\n\n#define ELF64_R_SYM(info) ((info) >> 32)\n#define ELF64_R_TYPE(info) ((info)&0xFFFFFFFF)\n#define ELF64_R_INFO(s, t) (((s) << 32) + (__uint32_t)(t))\n\n#if defined(__mips64__) && defined(__MIPSEL__)\n/*\n * The 64-bit MIPS ELF ABI uses a slightly different relocation format\n * than the regular ELF ABI: the r_info field is split into several\n * pieces (see gnu/usr.bin/binutils/include/elf/mips.h for details).\n */\n#undef ELF64_R_SYM\n#undef ELF64_R_TYPE\n#undef ELF64_R_INFO\n#define ELF64_R_TYPE(info) (swap32((info) >> 32))\n#define ELF64_R_SYM(info) ((info)&0xFFFFFFFF)\n#define ELF64_R_INFO(s, t) (((__uint64_t)swap32(t) << 32) + (__uint32_t)(s))\n#endif /* __mips64__ && __MIPSEL__ */\n\n/* Program Header */\ntypedef struct\n{\n    Elf32_Word p_type;   /* segment type */\n    Elf32_Off p_offset;  /* segment offset */\n    Elf32_Addr p_vaddr;  /* virtual address of segment */\n    Elf32_Addr p_paddr;  /* physical address - ignored? */\n    Elf32_Word p_filesz; /* number of bytes in file for seg. */\n    Elf32_Word p_memsz;  /* number of bytes in mem. for seg. */\n    Elf32_Word p_flags;  /* flags */\n    Elf32_Word p_align;  /* memory alignment */\n} Elf32_Phdr;\n\ntypedef struct\n{\n    Elf64_Half p_type;    /* entry type */\n    Elf64_Half p_flags;   /* flags */\n    Elf64_Off p_offset;   /* offset */\n    Elf64_Addr p_vaddr;   /* virtual address */\n    Elf64_Addr p_paddr;   /* physical address */\n    Elf64_Xword p_filesz; /* file size */\n    Elf64_Xword p_memsz;  /* memory size */\n    Elf64_Xword p_align;  /* memory & file alignment */\n} Elf64_Phdr;\n\n/* Segment types - p_type */\n#define PT_NULL 0            /* unused */\n#define PT_LOAD 1            /* loadable segment */\n#define PT_DYNAMIC 2         /* dynamic linking section */\n#define PT_INTERP 3          /* the RTLD */\n#define PT_NOTE 4            /* auxiliary information */\n#define PT_SHLIB 5           /* reserved - purpose undefined */\n#define PT_PHDR 6            /* program header */\n#define PT_TLS 7             /* thread local storage */\n#define PT_LOOS 0x60000000   /* reserved range for OS */\n#define PT_HIOS 0x6fffffff   /*  specific segment types */\n#define PT_LOPROC 0x70000000 /* reserved range for processor */\n#define PT_HIPROC 0x7fffffff /*  specific segment types */\n\n#define PT_OPENBSD_RANDOMIZE 0x65a3dbe6 /* fill with random data */\n#define PT_GANDR_KERNEL 0x67646b6c      /* gdkl */\n\n/* Segment flags - p_flags */\n#define PF_X 0x1               /* Executable */\n#define PF_W 0x2               /* Writable */\n#define PF_R 0x4               /* Readable */\n#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */\n                               /*  specific segment flags */\n\n/* Dynamic structure */\ntypedef struct\n{\n    Elf32_Sword d_tag; /* controls meaning of d_val */\n    union {\n        Elf32_Word d_val; /* Multiple meanings - see d_tag */\n        Elf32_Addr d_ptr; /* program virtual address */\n    } d_un;\n} Elf32_Dyn;\n\ntypedef struct\n{\n    Elf64_Xword d_tag; /* controls meaning of d_val */\n    union {\n        Elf64_Addr d_ptr;\n        Elf64_Xword d_val;\n    } d_un;\n} Elf64_Dyn;\n\n/* Dynamic Array Tags - d_tag */\n#define DT_NULL 0            /* marks end of _DYNAMIC array */\n#define DT_NEEDED 1          /* string table offset of needed lib */\n#define DT_PLTRELSZ 2        /* size of relocation entries in PLT */\n#define DT_PLTGOT 3          /* address PLT/GOT */\n#define DT_HASH 4            /* address of symbol hash table */\n#define DT_STRTAB 5          /* address of string table */\n#define DT_SYMTAB 6          /* address of symbol table */\n#define DT_RELA 7            /* address of relocation table */\n#define DT_RELASZ 8          /* size of relocation table */\n#define DT_RELAENT 9         /* size of relocation entry */\n#define DT_STRSZ 10          /* size of string table */\n#define DT_SYMENT 11         /* size of symbol table entry */\n#define DT_INIT 12           /* address of initialization func. */\n#define DT_FINI 13           /* address of termination function */\n#define DT_SONAME 14         /* string table offset of shared obj */\n#define DT_RPATH 15          /* string table offset of library \\\n                              * search path */\n#define DT_SYMBOLIC 16       /* start sym search in shared obj. */\n#define DT_REL 17            /* address of rel. tbl. w addends */\n#define DT_RELSZ 18          /* size of DT_REL relocation table */\n#define DT_RELENT 19         /* size of DT_REL relocation entry */\n#define DT_PLTREL 20         /* PLT referenced relocation entry */\n#define DT_DEBUG 21          /* bugger */\n#define DT_TEXTREL 22        /* Allow rel. mod. to unwritable seg */\n#define DT_JMPREL 23         /* add. of PLT's relocation entries */\n#define DT_BIND_NOW 24       /* Bind now regardless of env setting */\n#define DT_LOOS 0x6000000d   /* reserved range for OS */\n#define DT_HIOS 0x6ffff000   /*  specific dynamic array tags */\n#define DT_LOPROC 0x70000000 /* reserved range for processor */\n#define DT_HIPROC 0x7fffffff /*  specific dynamic array tags */\n\n/* some other useful tags */\n#define DT_RELACOUNT 0x6ffffff9 /* if present, number of RELATIVE */\n#define DT_RELCOUNT 0x6ffffffa  /* relocs, which must come first */\n#define DT_FLAGS_1 0x6ffffffb\n\n/* Dynamic Flags - DT_FLAGS_1 .dynamic entry */\n#define DF_1_NOW 0x00000001\n#define DF_1_GLOBAL 0x00000002\n#define DF_1_GROUP 0x00000004\n#define DF_1_NODELETE 0x00000008\n#define DF_1_LOADFLTR 0x00000010\n#define DF_1_INITFIRST 0x00000020\n#define DF_1_NOOPEN 0x00000040\n#define DF_1_ORIGIN 0x00000080\n#define DF_1_DIRECT 0x00000100\n#define DF_1_TRANS 0x00000200\n#define DF_1_INTERPOSE 0x00000400\n#define DF_1_NODEFLIB 0x00000800\n#define DF_1_NODUMP 0x00001000\n#define DF_1_CONLFAT 0x00002000\n\n/* ld.so: number of low tags that are used saved internally (0 .. DT_NUM-1) */\n#define DT_NUM (DT_JMPREL + 1)\n\n/*\n * Note Definitions\n */\ntypedef struct\n{\n    Elf32_Word namesz;\n    Elf32_Word descsz;\n    Elf32_Word type;\n} Elf32_Note;\n\ntypedef struct\n{\n    Elf64_Half namesz;\n    Elf64_Half descsz;\n    Elf64_Half type;\n} Elf64_Note;\n\n#if defined(ELFSIZE) && (ELFSIZE == 32)\n#define Elf_Ehdr Elf32_Ehdr\n#define Elf_Phdr Elf32_Phdr\n#define Elf_Shdr Elf32_Shdr\n#define Elf_Sym Elf32_Sym\n#define Elf_Rel Elf32_Rel\n#define Elf_RelA Elf32_Rela\n#define Elf_Dyn Elf32_Dyn\n#define Elf_Half Elf32_Half\n#define Elf_Word Elf32_Word\n#define Elf_Sword Elf32_Sword\n#define Elf_Addr Elf32_Addr\n#define Elf_Off Elf32_Off\n#define Elf_Nhdr Elf32_Nhdr\n#define Elf_Note Elf32_Note\n\n#define ELF_R_SYM ELF32_R_SYM\n#define ELF_R_TYPE ELF32_R_TYPE\n#define ELF_R_INFO ELF32_R_INFO\n#define ELFCLASS ELFCLASS32\n\n#define ELF_ST_BIND ELF32_ST_BIND\n#define ELF_ST_TYPE ELF32_ST_TYPE\n#define ELF_ST_INFO ELF32_ST_INFO\n\n#elif defined(ELFSIZE) && (ELFSIZE == 64)\n\n#define Elf_Ehdr Elf64_Ehdr\n#define Elf_Phdr Elf64_Phdr\n#define Elf_Shdr Elf64_Shdr\n#define Elf_Sym Elf64_Sym\n#define Elf_Rel Elf64_Rel\n#define Elf_RelA Elf64_Rela\n#define Elf_Dyn Elf64_Dyn\n#define Elf_Half Elf64_Half\n#define Elf_Word Elf64_Word\n#define Elf_Sword Elf64_Sword\n#define Elf_Addr Elf64_Addr\n#define Elf_Off Elf64_Off\n#define Elf_Nhdr Elf64_Nhdr\n#define Elf_Note Elf64_Note\n\n#define ELF_R_SYM ELF64_R_SYM\n#define ELF_R_TYPE ELF64_R_TYPE\n#define ELF_R_INFO ELF64_R_INFO\n#define ELFCLASS ELFCLASS64\n\n#define ELF_ST_BIND ELF64_ST_BIND\n#define ELF_ST_TYPE ELF64_ST_TYPE\n#define ELF_ST_INFO ELF64_ST_INFO\n\n#endif\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/libs/elfload/elfarch.h",
    "content": "/*\n * Copyright © 2014, Owen Shepherd\n *\n * Permission to use, copy, modify, and/or distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\n * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\n * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n * PERFORMANCE OF THIS SOFTWARE.\n */\n\n#ifndef ELFARCH_H\n#define ELFARCH_H\n\n#if defined(__i386__)\n#define EM_THIS EM_386\n#define EL_ARCH_USES_REL\n#elif defined(__amd64__)\n#define EM_THIS EM_AMD64\n#define EL_ARCH_USES_RELA\n#elif defined(__arm__)\n#define EM_THIS EM_ARM\n#define EL_ARCH_USES_REL\n#elif defined(__aarch64__)\n#define EM_THIS EM_AARCH64\n#define EL_ARCH_USES_RELA\n#define EL_ARCH_USES_REL\n#else\n#error specify your ELF architecture\n#endif\n\n#if defined(__LP64__) || defined(__LLP64__)\n#define ELFSIZE 64\n#else\n#define ELFSIZE 32\n#endif\n\n#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\n#define ELFDATATHIS ELFDATA2LSB\n#else\n#define ELFDATATHIS ELFDATA2MSB\n#endif\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/libs/elfload/elfload.h",
    "content": "/*\n * Copyright © 2018, M4xw\n * Copyright © 2014, Owen Shepherd\n *\n * Permission to use, copy, modify, and/or distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\n * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\n * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n * PERFORMANCE OF THIS SOFTWARE.\n */\n\n#ifndef ELFLOAD_H\n#define ELFLOAD_H\n#include <stddef.h>\n\n#include \"elfarch.h\"\n#include \"elf.h\"\n\n#include \"utils/types.h\"\n\n#ifdef DEBUG\n#include \"gfx/gfx.h\"\nextern gfx_con_t g_gfx_con;\n#define EL_DEBUG(format, ...) \\\n\tgfx_printf(format __VA_OPT__(, ) __VA_ARGS__)\n#else\n#define EL_DEBUG(...) \\\n\tdo                \\\n\t{                 \\\n\t} while (0)\n#endif\n\ntypedef enum\n{\n\tEL_OK = 0,\n\n\tEL_EIO,\n\tEL_ENOMEM,\n\n\tEL_NOTELF,\n\tEL_WRONGBITS,\n\tEL_WRONGENDIAN,\n\tEL_WRONGARCH,\n\tEL_WRONGOS,\n\tEL_NOTEXEC,\n\tEL_NODYN,\n\tEL_BADREL,\n\n} el_status;\n\ntypedef struct el_ctx\n{\n\tbool (*pread)(struct el_ctx *ctx, void *dest, size_t nb, size_t offset);\n\n\t/* base_load_* -> address we are actually going to load at\n\t */\n\tElf_Addr\n\t\tbase_load_paddr,\n\t\tbase_load_vaddr;\n\n\t/* size in memory of binary */\n\tElf_Addr memsz;\n\n\t/* required alignment */\n\tElf_Addr align;\n\n\t/* ELF header */\n\tElf_Ehdr ehdr;\n\n\t// Section Header Str Table\n\tElf_Shdr shstr;\n\tElf_Shdr symtab;\n\t\n\t/* Offset of dynamic table (0 if not ET_DYN) */\n\tElf_Off dynoff;\n\t/* Size of dynamic table (0 if not ET_DYN) */\n\tElf_Addr dynsize;\n} el_ctx;\n\nel_status el_pread(el_ctx *ctx, void *def, size_t nb, size_t offset);\n\nel_status el_init(el_ctx *ctx);\ntypedef void *(*el_alloc_cb)(\n\tel_ctx *ctx,\n\tElf_Addr phys,\n\tElf_Addr virt,\n\tElf_Addr size);\n\nel_status el_load(el_ctx *ctx, el_alloc_cb alloccb);\n\n/* find the next phdr of type \\p type, starting at \\p *i.\n * On success, returns EL_OK with *i set to the phdr number, and the phdr loaded\n * in *phdr.\n *\n * If the end of the phdrs table was reached, *i is set to -1 and the contents\n * of *phdr are undefined\n */\nel_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, uint32_t type, unsigned *i);\n\n/* Relocate the loaded executable */\nel_status el_relocate(el_ctx *ctx);\n\n/* find a dynamic table entry\n * returns the entry on success, dyn->d_tag = DT_NULL on failure\n */\nel_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, uint32_t type);\n\ntypedef struct\n{\n\tElf_Off tableoff;\n\tElf_Addr tablesize;\n\tElf_Addr entrysize;\n} el_relocinfo;\n\n/* find all information regarding relocations of a specific type.\n *\n * pass DT_REL or DT_RELA for type\n * sets ri->entrysize = 0 if not found\n */\nel_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, uint32_t type);\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/libs/fatfs/diskio.h",
    "content": "/*-----------------------------------------------------------------------/\n/  Low level disk interface modlue include file   (C)ChaN, 2014          /\n/-----------------------------------------------------------------------*/\n\n#ifndef _DISKIO_DEFINED\n#define _DISKIO_DEFINED\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"../../utils/types.h\"\n\n/* Status of Disk Functions */\ntypedef BYTE\tDSTATUS;\n\n/* Results of Disk Functions */\ntypedef enum {\n\tRES_OK = 0,\t\t/* 0: Successful */\n\tRES_ERROR,\t\t/* 1: R/W Error */\n\tRES_WRPRT,\t\t/* 2: Write Protected */\n\tRES_NOTRDY,\t\t/* 3: Not Ready */\n\tRES_PARERR\t\t/* 4: Invalid Parameter */\n} DRESULT;\n\n\n/*---------------------------------------*/\n/* Prototypes for disk control functions */\n\n\nDSTATUS disk_initialize (BYTE pdrv);\nDSTATUS disk_status (BYTE pdrv);\nDRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);\nDRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);\nDRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);\n\n\n/* Disk Status Bits (DSTATUS) */\n\n#define STA_NOINIT\t\t0x01\t/* Drive not initialized */\n#define STA_NODISK\t\t0x02\t/* No medium in the drive */\n#define STA_PROTECT\t\t0x04\t/* Write protected */\n\n\n/* Command code for disk_ioctrl fucntion */\n\n/* Generic command (Used by FatFs) */\n#define CTRL_SYNC\t\t\t0\t/* Complete pending write process (needed at FF_FS_READONLY == 0) */\n#define GET_SECTOR_COUNT\t1\t/* Get media size (needed at FF_USE_MKFS == 1) */\n#define GET_SECTOR_SIZE\t\t2\t/* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */\n#define GET_BLOCK_SIZE\t\t3\t/* Get erase block size (needed at FF_USE_MKFS == 1) */\n#define CTRL_TRIM\t\t\t4\t/* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */\n\n/* Generic command (Not used by FatFs) */\n#define CTRL_POWER\t\t\t5\t/* Get/Set power status */\n#define CTRL_LOCK\t\t\t6\t/* Lock/Unlock media removal */\n#define CTRL_EJECT\t\t\t7\t/* Eject media */\n#define CTRL_FORMAT\t\t\t8\t/* Create physical format on the media */\n\n/* MMC/SDC specific ioctl command */\n#define MMC_GET_TYPE\t\t10\t/* Get card type */\n#define MMC_GET_CSD\t\t\t11\t/* Get CSD */\n#define MMC_GET_CID\t\t\t12\t/* Get CID */\n#define MMC_GET_OCR\t\t\t13\t/* Get OCR */\n#define MMC_GET_SDSTAT\t\t14\t/* Get SD status */\n#define ISDIO_READ\t\t\t55\t/* Read data form SD iSDIO register */\n#define ISDIO_WRITE\t\t\t56\t/* Write data to SD iSDIO register */\n#define ISDIO_MRITE\t\t\t57\t/* Masked write data to SD iSDIO register */\n\n/* ATA/CF specific ioctl command */\n#define ATA_GET_REV\t\t\t20\t/* Get F/W revision */\n#define ATA_GET_MODEL\t\t21\t/* Get model name */\n#define ATA_GET_SN\t\t\t22\t/* Get serial number */\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif"
  },
  {
    "path": "argon-first-stage/include/libs/fatfs/ff.h",
    "content": "/*----------------------------------------------------------------------------/\n/  FatFs - Generic FAT Filesystem module  R0.13c                              /\n/-----------------------------------------------------------------------------/\n/\n/ Copyright (C) 2018, ChaN, all right reserved.\n/\n/ FatFs module is an open source software. Redistribution and use of FatFs in\n/ source and binary forms, with or without modification, are permitted provided\n/ that the following condition is met:\n/ 1. Redistributions of source code must retain the above copyright notice,\n/    this condition and the following disclaimer.\n/\n/ This software is provided by the copyright holder and contributors \"AS IS\"\n/ and any warranties related to this software are DISCLAIMED.\n/ The copyright owner or contributors be NOT LIABLE for any damages caused\n/ by use of this software.\n/\n/----------------------------------------------------------------------------*/\n\n\n#ifndef FF_DEFINED\n#define FF_DEFINED\t86604\t/* Revision ID */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"../../utils/types.h\"\t/* Basic integer types */\n#include \"ffconf.h\"\t\t/* FatFs configuration options */\n\n#if FF_DEFINED != FFCONF_DEF\n#error Wrong configuration file (ffconf.h).\n#endif\n\n\n\n/* Definitions of volume management */\n\n#if FF_MULTI_PARTITION\t\t/* Multiple partition configuration */\ntypedef struct {\n\tBYTE pd;\t/* Physical drive number */\n\tBYTE pt;\t/* Partition: 0:Auto detect, 1-4:Forced partition) */\n} PARTITION;\nextern PARTITION VolToPart[];\t/* Volume - Partition resolution table */\n#endif\n\n#if FF_STR_VOLUME_ID\n#ifndef FF_VOLUME_STRS\nextern const char* VolumeStr[FF_VOLUMES];\t/* User defied volume ID */\n#endif\n#endif\n\n\n\n/* Type of path name strings on FatFs API */\n\n#ifndef _INC_TCHAR\n#define _INC_TCHAR\n\n#if FF_USE_LFN && FF_LFN_UNICODE == 1 \t/* Unicode in UTF-16 encoding */\ntypedef WCHAR TCHAR;\n#define _T(x) L ## x\n#define _TEXT(x) L ## x\n#elif FF_USE_LFN && FF_LFN_UNICODE == 2\t/* Unicode in UTF-8 encoding */\ntypedef char TCHAR;\n#define _T(x) u8 ## x\n#define _TEXT(x) u8 ## x\n#elif FF_USE_LFN && FF_LFN_UNICODE == 3\t/* Unicode in UTF-32 encoding */\ntypedef DWORD TCHAR;\n#define _T(x) U ## x\n#define _TEXT(x) U ## x\n#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3)\n#error Wrong FF_LFN_UNICODE setting\n#else\t\t\t\t\t\t\t\t\t/* ANSI/OEM code in SBCS/DBCS */\ntypedef char TCHAR;\n#define _T(x) x\n#define _TEXT(x) x\n#endif\n\n#endif\n\n\n\n/* Type of file size variables */\n\n#if FF_FS_EXFAT\ntypedef QWORD FSIZE_t;\n#else\ntypedef DWORD FSIZE_t;\n#endif\n\n\n\n/* Filesystem object structure (FATFS) */\n\ntypedef struct {\n\tBYTE\tfs_type;\t\t/* Filesystem type (0:not mounted) */\n\tBYTE\tpdrv;\t\t\t/* Associated physical drive */\n\tBYTE\tn_fats;\t\t\t/* Number of FATs (1 or 2) */\n\tBYTE\twflag;\t\t\t/* win[] flag (b0:dirty) */\n\tBYTE\tfsi_flag;\t\t/* FSINFO flags (b7:disabled, b0:dirty) */\n\tWORD\tid;\t\t\t\t/* Volume mount ID */\n\tWORD\tn_rootdir;\t\t/* Number of root directory entries (FAT12/16) */\n\tWORD\tcsize;\t\t\t/* Cluster size [sectors] */\n#if FF_MAX_SS != FF_MIN_SS\n\tWORD\tssize;\t\t\t/* Sector size (512, 1024, 2048 or 4096) */\n#endif\n#if FF_USE_LFN\n\tWCHAR*\tlfnbuf;\t\t\t/* LFN working buffer */\n#endif\n#if FF_FS_EXFAT\n\tBYTE*\tdirbuf;\t\t\t/* Directory entry block scratchpad buffer for exFAT */\n#endif\n#if FF_FS_REENTRANT\n\tFF_SYNC_t\tsobj;\t\t/* Identifier of sync object */\n#endif\n#if !FF_FS_READONLY\n\tDWORD\tlast_clst;\t\t/* Last allocated cluster */\n\tDWORD\tfree_clst;\t\t/* Number of free clusters */\n#endif\n#if FF_FS_RPATH\n\tDWORD\tcdir;\t\t\t/* Current directory start cluster (0:root) */\n#if FF_FS_EXFAT\n\tDWORD\tcdc_scl;\t\t/* Containing directory start cluster (invalid when cdir is 0) */\n\tDWORD\tcdc_size;\t\t/* b31-b8:Size of containing directory, b7-b0: Chain status */\n\tDWORD\tcdc_ofs;\t\t/* Offset in the containing directory (invalid when cdir is 0) */\n#endif\n#endif\n\tDWORD\tn_fatent;\t\t/* Number of FAT entries (number of clusters + 2) */\n\tDWORD\tfsize;\t\t\t/* Size of an FAT [sectors] */\n\tDWORD\tvolbase;\t\t/* Volume base sector */\n\tDWORD\tfatbase;\t\t/* FAT base sector */\n\tDWORD\tdirbase;\t\t/* Root directory base sector/cluster */\n\tDWORD\tdatabase;\t\t/* Data base sector */\n#if FF_FS_EXFAT\n\tDWORD\tbitbase;\t\t/* Allocation bitmap base sector */\n#endif\n\tDWORD\twinsect;\t\t/* Current sector appearing in the win[] */\n\tBYTE\twin[FF_MAX_SS];\t/* Disk access window for Directory, FAT (and file data at tiny cfg) */\n} FATFS;\n\n\n\n/* Object ID and allocation information (FFOBJID) */\n\ntypedef struct {\n\tFATFS*\tfs;\t\t\t\t/* Pointer to the hosting volume of this object */\n\tWORD\tid;\t\t\t\t/* Hosting volume mount ID */\n\tBYTE\tattr;\t\t\t/* Object attribute */\n\tBYTE\tstat;\t\t\t/* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */\n\tDWORD\tsclust;\t\t\t/* Object data start cluster (0:no cluster or root directory) */\n\tFSIZE_t\tobjsize;\t\t/* Object size (valid when sclust != 0) */\n#if FF_FS_EXFAT\n\tDWORD\tn_cont;\t\t\t/* Size of first fragment - 1 (valid when stat == 3) */\n\tDWORD\tn_frag;\t\t\t/* Size of last fragment needs to be written to FAT (valid when not zero) */\n\tDWORD\tc_scl;\t\t\t/* Containing directory start cluster (valid when sclust != 0) */\n\tDWORD\tc_size;\t\t\t/* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */\n\tDWORD\tc_ofs;\t\t\t/* Offset in the containing directory (valid when file object and sclust != 0) */\n#endif\n#if FF_FS_LOCK\n\tUINT\tlockid;\t\t\t/* File lock ID origin from 1 (index of file semaphore table Files[]) */\n#endif\n} FFOBJID;\n\n\n\n/* File object structure (FIL) */\n\ntypedef struct {\n\tFFOBJID\tobj;\t\t\t/* Object identifier (must be the 1st member to detect invalid object pointer) */\n\tBYTE\tflag;\t\t\t/* File status flags */\n\tBYTE\terr;\t\t\t/* Abort flag (error code) */\n\tFSIZE_t\tfptr;\t\t\t/* File read/write pointer (Zeroed on file open) */\n\tDWORD\tclust;\t\t\t/* Current cluster of fpter (invalid when fptr is 0) */\n\tDWORD\tsect;\t\t\t/* Sector number appearing in buf[] (0:invalid) */\n#if !FF_FS_READONLY\n\tDWORD\tdir_sect;\t\t/* Sector number containing the directory entry (not used at exFAT) */\n\tBYTE*\tdir_ptr;\t\t/* Pointer to the directory entry in the win[] (not used at exFAT) */\n#endif\n#if !FF_FS_TINY\n\tBYTE\tbuf[FF_MAX_SS];\t/* File private data read/write window */\n#endif\n#if FF_USE_FASTSEEK\n\tDWORD*\tcltbl;\t\t\t/* Pointer to the cluster link map table (nulled on open, set by application) */\n#endif\n} FIL;\n\n\n\n/* Directory object structure (DIR) */\n\ntypedef struct {\n\tFFOBJID\tobj;\t\t\t/* Object identifier */\n\tDWORD\tdptr;\t\t\t/* Current read/write offset */\n\tDWORD\tclust;\t\t\t/* Current cluster */\n\tDWORD\tsect;\t\t\t/* Current sector (0:Read operation has terminated) */\n\tBYTE*\tdir;\t\t\t/* Pointer to the directory item in the win[] */\n\tBYTE\tfn[12];\t\t\t/* SFN (in/out) {body[8],ext[3],status[1]} */\n#if FF_USE_LFN\n\tDWORD\tblk_ofs;\t\t/* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */\n#endif\n#if FF_USE_FIND\n\tconst TCHAR* pat;\t\t/* Pointer to the name matching pattern */\n#endif\n} DIR;\n\n\n\n/* File information structure (FILINFO) */\n\ntypedef struct {\n\tFSIZE_t\tfsize;\t\t\t/* File size */\n\tWORD\tfdate;\t\t\t/* Modified date */\n\tWORD\tftime;\t\t\t/* Modified time */\n\tBYTE\tfattrib;\t\t/* File attribute */\n#if FF_USE_LFN\n\tTCHAR\taltname[FF_SFN_BUF + 1];/* Altenative file name */\n\tTCHAR\tfname[FF_LFN_BUF + 1];\t/* Primary file name */\n#else\n\tTCHAR\tfname[12 + 1];\t/* File name */\n#endif\n} FILINFO;\n\n\n\n/* File function return code (FRESULT) */\n\ntypedef enum {\n\tFR_OK = 0,\t\t\t\t/* (0) Succeeded */\n\tFR_DISK_ERR,\t\t\t/* (1) A hard error occurred in the low level disk I/O layer */\n\tFR_INT_ERR,\t\t\t\t/* (2) Assertion failed */\n\tFR_NOT_READY,\t\t\t/* (3) The physical drive cannot work */\n\tFR_NO_FILE,\t\t\t\t/* (4) Could not find the file */\n\tFR_NO_PATH,\t\t\t\t/* (5) Could not find the path */\n\tFR_INVALID_NAME,\t\t/* (6) The path name format is invalid */\n\tFR_DENIED,\t\t\t\t/* (7) Access denied due to prohibited access or directory full */\n\tFR_EXIST,\t\t\t\t/* (8) Access denied due to prohibited access */\n\tFR_INVALID_OBJECT,\t\t/* (9) The file/directory object is invalid */\n\tFR_WRITE_PROTECTED,\t\t/* (10) The physical drive is write protected */\n\tFR_INVALID_DRIVE,\t\t/* (11) The logical drive number is invalid */\n\tFR_NOT_ENABLED,\t\t\t/* (12) The volume has no work area */\n\tFR_NO_FILESYSTEM,\t\t/* (13) There is no valid FAT volume */\n\tFR_MKFS_ABORTED,\t\t/* (14) The f_mkfs() aborted due to any problem */\n\tFR_TIMEOUT,\t\t\t\t/* (15) Could not get a grant to access the volume within defined period */\n\tFR_LOCKED,\t\t\t\t/* (16) The operation is rejected according to the file sharing policy */\n\tFR_NOT_ENOUGH_CORE,\t\t/* (17) LFN working buffer could not be allocated */\n\tFR_TOO_MANY_OPEN_FILES,\t/* (18) Number of open files > FF_FS_LOCK */\n#ifdef FF_FASTFS\n\tFR_INVALID_PARAMETER,\t/* (19) Given parameter is invalid */\n\tFR_CLTBL_NO_INIT\t    /* (20) The cluster table for fast seek/read/write was not created */\n#else\n\tFR_INVALID_PARAMETER\t/* (19) Given parameter is invalid */\n#endif\n} FRESULT;\n\n\n\n/*--------------------------------------------------------------*/\n/* FatFs module application interface                           */\n\nFRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode);\t\t\t\t/* Open or create a file */\nFRESULT f_close (FIL* fp);\t\t\t\t\t\t\t\t\t\t\t/* Close an open file object */\nFRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br);\t\t\t/* Read data from the file */\nFRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw);\t/* Write data to the file */\n#ifdef FF_FASTFS\nFRESULT f_read_fast (FIL* fp, const void* buff, UINT btr);\t\t\t/* Fast read data from the file */\nFRESULT f_write_fast (FIL* fp, const void* buff, UINT btw);         /* Fast write data to the file */\n#endif\nFRESULT f_lseek (FIL* fp, FSIZE_t ofs);\t\t\t\t\t\t\t\t/* Move file pointer of the file object */\nFRESULT f_truncate (FIL* fp);\t\t\t\t\t\t\t\t\t\t/* Truncate the file */\nFRESULT f_sync (FIL* fp);\t\t\t\t\t\t\t\t\t\t\t/* Flush cached data of the writing file */\nFRESULT f_opendir (DIR* dp, const TCHAR* path);\t\t\t\t\t\t/* Open a directory */\nFRESULT f_closedir (DIR* dp);\t\t\t\t\t\t\t\t\t\t/* Close an open directory */\nFRESULT f_readdir (DIR* dp, FILINFO* fno);\t\t\t\t\t\t\t/* Read a directory item */\nFRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern);\t/* Find first file */\nFRESULT f_findnext (DIR* dp, FILINFO* fno);\t\t\t\t\t\t\t/* Find next file */\nFRESULT f_mkdir (const TCHAR* path);\t\t\t\t\t\t\t\t/* Create a sub directory */\nFRESULT f_unlink (const TCHAR* path);\t\t\t\t\t\t\t\t/* Delete an existing file or directory */\nFRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new);\t/* Rename/Move a file or directory */\nFRESULT f_stat (const TCHAR* path, FILINFO* fno);\t\t\t\t\t/* Get file status */\nFRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask);\t\t\t/* Change attribute of a file/dir */\nFRESULT f_utime (const TCHAR* path, const FILINFO* fno);\t\t\t/* Change timestamp of a file/dir */\nFRESULT f_chdir (const TCHAR* path);\t\t\t\t\t\t\t\t/* Change current directory */\nFRESULT f_chdrive (const TCHAR* path);\t\t\t\t\t\t\t\t/* Change current drive */\nFRESULT f_getcwd (TCHAR* buff, UINT len);\t\t\t\t\t\t\t/* Get current directory */\nFRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs);\t/* Get number of free clusters on the drive */\nFRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn);\t/* Get volume label */\nFRESULT f_setlabel (const TCHAR* label);\t\t\t\t\t\t\t/* Set volume label */\nFRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf);\t/* Forward data to the stream */\n#ifdef FF_FASTFS\nDWORD  *f_expand_cltbl (FIL* fp, UINT tblsz, FSIZE_t ofs);\t\t\t/* Expand file and populate cluster table */\n#endif\nFRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt);\t\t\t\t\t/* Allocate a contiguous block to the file */\nFRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt);\t\t\t/* Mount/Unmount a logical drive */\nFRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len);\t/* Create a FAT volume */\nFRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work);\t\t\t/* Divide a physical drive into some partitions */\nFRESULT f_setcp (WORD cp);\t\t\t\t\t\t\t\t\t\t\t/* Set current code page */\nint f_putc (TCHAR c, FIL* fp);\t\t\t\t\t\t\t\t\t\t/* Put a character to the file */\nint f_puts (const TCHAR* str, FIL* cp);\t\t\t\t\t\t\t\t/* Put a string to the file */\nint f_printf (FIL* fp, const TCHAR* str, ...);\t\t\t\t\t\t/* Put a formatted string to the file */\nTCHAR* f_gets (TCHAR* buff, int len, FIL* fp);\t\t\t\t\t\t/* Get a string from the file */\n\n#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))\n#define f_error(fp) ((fp)->err)\n#define f_tell(fp) ((fp)->fptr)\n#define f_size(fp) ((fp)->obj.objsize)\n#define f_rewind(fp) f_lseek((fp), 0)\n#define f_rewinddir(dp) f_readdir((dp), 0)\n#define f_rmdir(path) f_unlink(path)\n#define f_unmount(path) f_mount(0, path, 0)\n\n#ifndef EOF\n#define EOF (-1)\n#endif\n\n\n\n\n/*--------------------------------------------------------------*/\n/* Additional user defined functions                            */\n\n/* RTC function */\n#if !FF_FS_READONLY && !FF_FS_NORTC\nDWORD get_fattime (void);\n#endif\n\n/* LFN support functions */\n#if FF_USE_LFN >= 1\t\t\t\t\t\t/* Code conversion (defined in unicode.c) */\nWCHAR ff_oem2uni (WCHAR oem, WORD cp);\t/* OEM code to Unicode conversion */\nWCHAR ff_uni2oem (DWORD uni, WORD cp);\t/* Unicode to OEM code conversion */\nDWORD ff_wtoupper (DWORD uni);\t\t\t/* Unicode upper-case conversion */\n#endif\n#if FF_USE_LFN == 3\t\t\t\t\t\t/* Dynamic memory allocation */\nvoid* ff_memalloc (UINT msize);\t\t\t/* Allocate memory block */\nvoid ff_memfree (void* mblock);\t\t\t/* Free memory block */\n#endif\n\n/* Sync functions */\n#if FF_FS_REENTRANT\nint ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj);\t/* Create a sync object */\nint ff_req_grant (FF_SYNC_t sobj);\t\t/* Lock sync object */\nvoid ff_rel_grant (FF_SYNC_t sobj);\t\t/* Unlock sync object */\nint ff_del_syncobj (FF_SYNC_t sobj);\t/* Delete a sync object */\n#endif\n\n\n\n\n/*--------------------------------------------------------------*/\n/* Flags and offset address                                     */\n\n\n/* File access mode and open method flags (3rd argument of f_open) */\n#define\tFA_READ\t\t\t\t0x01\n#define\tFA_WRITE\t\t\t0x02\n#define\tFA_OPEN_EXISTING\t0x00\n#define\tFA_CREATE_NEW\t\t0x04\n#define\tFA_CREATE_ALWAYS\t0x08\n#define\tFA_OPEN_ALWAYS\t\t0x10\n#define\tFA_OPEN_APPEND\t\t0x30\n\n/* Fast seek controls (2nd argument of f_lseek) */\n#define CREATE_LINKMAP\t((FSIZE_t)0 - 1)\n\n/* Format options (2nd argument of f_mkfs) */\n#define FM_FAT\t\t0x01\n#define FM_FAT32\t0x02\n#define FM_EXFAT\t0x04\n#define FM_ANY\t\t0x07\n#define FM_SFD\t\t0x08\n\n/* Filesystem type (FATFS.fs_type) */\n#define FS_FAT12\t1\n#define FS_FAT16\t2\n#define FS_FAT32\t3\n#define FS_EXFAT\t4\n\n/* File attribute bits for directory entry (FILINFO.fattrib) */\n#define\tAM_RDO\t0x01\t/* Read only */\n#define\tAM_HID\t0x02\t/* Hidden */\n#define\tAM_SYS\t0x04\t/* System */\n#define AM_DIR\t0x10\t/* Directory */\n#define AM_ARC\t0x20\t/* Archive */\n\n\n#ifdef __cplusplus\n}\n#endif\n#endif /* FF_DEFINED */"
  },
  {
    "path": "argon-first-stage/include/libs/fatfs/ffconf.h",
    "content": "/*---------------------------------------------------------------------------/\n/  FatFs Functional Configurations\n/---------------------------------------------------------------------------*/\n\n#define FFCONF_DEF\t86604\t/* Revision ID */\n\n/*---------------------------------------------------------------------------/\n/ Function Configurations\n/---------------------------------------------------------------------------*/\n\n#define FF_FS_READONLY\t0\n/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)\n/  Read-only configuration removes writing API functions, f_write(), f_sync(),\n/  f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()\n/  and optional writing functions as well. */\n\n\n#define FF_FS_MINIMIZE\t0\n/* This option defines minimization level to remove some basic API functions.\n/\n/   0: Basic functions are fully enabled.\n/   1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()\n/      are removed.\n/   2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.\n/   3: f_lseek() function is removed in addition to 2. */\n\n\n#define FF_USE_STRFUNC\t2\n/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().\n/\n/  0: Disable string functions.\n/  1: Enable without LF-CRLF conversion.\n/  2: Enable with LF-CRLF conversion. */\n\n\n#define FF_USE_FIND\t\t1\n/* This option switches filtered directory read functions, f_findfirst() and\n/  f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */\n\n\n#define FF_USE_MKFS\t\t0\n/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */\n\n#define FF_FASTFS 1\n\n#ifdef FF_FASTFS\n#define FF_USE_FASTSEEK\t1\n#else\n#define FF_USE_FASTSEEK\t0\n#endif\n/* This option switches fast seek function. (0:Disable or 1:Enable) */\n\n\n#define FF_USE_EXPAND\t0\n/* This option switches f_expand function. (0:Disable or 1:Enable) */\n\n\n#define FF_USE_CHMOD\t1\n/* This option switches attribute manipulation functions, f_chmod() and f_utime().\n/  (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */\n\n\n#define FF_USE_LABEL\t0\n/* This option switches volume label functions, f_getlabel() and f_setlabel().\n/  (0:Disable or 1:Enable) */\n\n\n#define FF_USE_FORWARD\t0\n/* This option switches f_forward() function. (0:Disable or 1:Enable) */\n\n\n/*---------------------------------------------------------------------------/\n/ Locale and Namespace Configurations\n/---------------------------------------------------------------------------*/\n\n#define FF_CODE_PAGE\t850\n/* This option specifies the OEM code page to be used on the target system.\n/  Incorrect code page setting can cause a file open failure.\n/\n/   437 - U.S.\n/   720 - Arabic\n/   737 - Greek\n/   771 - KBL\n/   775 - Baltic\n/   850 - Latin 1\n/   852 - Latin 2\n/   855 - Cyrillic\n/   857 - Turkish\n/   860 - Portuguese\n/   861 - Icelandic\n/   862 - Hebrew\n/   863 - Canadian French\n/   864 - Arabic\n/   865 - Nordic\n/   866 - Russian\n/   869 - Greek 2\n/   932 - Japanese (DBCS)\n/   936 - Simplified Chinese (DBCS)\n/   949 - Korean (DBCS)\n/   950 - Traditional Chinese (DBCS)\n/     0 - Include all code pages above and configured by f_setcp()\n*/\n\n\n#define FF_USE_LFN\t\t3\n#define FF_MAX_LFN\t\t255\n/* The FF_USE_LFN switches the support for LFN (long file name).\n/\n/   0: Disable LFN. FF_MAX_LFN has no effect.\n/   1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.\n/   2: Enable LFN with dynamic working buffer on the STACK.\n/   3: Enable LFN with dynamic working buffer on the HEAP.\n/\n/  To enable the LFN, ffunicode.c needs to be added to the project. The LFN function\n/  requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and\n/  additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.\n/  The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can\n/  be in range of 12 to 255. It is recommended to be set 255 to fully support LFN\n/  specification.\n/  When use stack for the working buffer, take care on stack overflow. When use heap\n/  memory for the working buffer, memory management functions, ff_memalloc() and\n/  ff_memfree() in ffsystem.c, need to be added to the project. */\n\n\n#define FF_LFN_UNICODE\t0\n/* This option switches the character encoding on the API when LFN is enabled.\n/\n/   0: ANSI/OEM in current CP (TCHAR = char)\n/   1: Unicode in UTF-16 (TCHAR = WCHAR)\n/   2: Unicode in UTF-8 (TCHAR = char)\n/   3: Unicode in UTF-32 (TCHAR = DWORD)\n/\n/  Also behavior of string I/O functions will be affected by this option.\n/  When LFN is not enabled, this option has no effect. */\n\n\n#define FF_LFN_BUF\t\t255\n#define FF_SFN_BUF\t\t12\n/* This set of options defines size of file name members in the FILINFO structure\n/  which is used to read out directory items. These values should be suffcient for\n/  the file names to read. The maximum possible length of the read file name depends\n/  on character encoding. When LFN is not enabled, these options have no effect. */\n\n\n#define FF_STRF_ENCODE\t0\n/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),\n/  f_putc(), f_puts and f_printf() convert the character encoding in it.\n/  This option selects assumption of character encoding ON THE FILE to be\n/  read/written via those functions.\n/\n/   0: ANSI/OEM in current CP\n/   1: Unicode in UTF-16LE\n/   2: Unicode in UTF-16BE\n/   3: Unicode in UTF-8\n*/\n\n\n#define FF_FS_RPATH\t\t0\n/* This option configures support for relative path.\n/\n/   0: Disable relative path and remove related functions.\n/   1: Enable relative path. f_chdir() and f_chdrive() are available.\n/   2: f_getcwd() function is available in addition to 1.\n*/\n\n\n/*---------------------------------------------------------------------------/\n/ Drive/Volume Configurations\n/---------------------------------------------------------------------------*/\n\n#define FF_VOLUMES\t\t1\n/* Number of volumes (logical drives) to be used. (1-10) */\n\n\n#define FF_STR_VOLUME_ID\t0\n#define FF_VOLUME_STRS\t\t\"sd\"\n/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.\n/  When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive\n/  number in the path name. FF_VOLUME_STRS defines the volume ID strings for each\n/  logical drives. Number of items must not be less than FF_VOLUMES. Valid\n/  characters for the volume ID strings are A-Z, a-z and 0-9, however, they are\n/  compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is\n/  not defined, a user defined volume string table needs to be defined as:\n/\n/  const char* VolumeStr[FF_VOLUMES] = {\"ram\",\"flash\",\"sd\",\"usb\",...\n*/\n\n\n#define FF_MULTI_PARTITION\t0\n/* This option switches support for multiple volumes on the physical drive.\n/  By default (0), each logical drive number is bound to the same physical drive\n/  number and only an FAT volume found on the physical drive will be mounted.\n/  When this function is enabled (1), each logical drive number can be bound to\n/  arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()\n/  funciton will be available. */\n\n\n#define FF_MIN_SS\t\t512\n#define FF_MAX_SS\t\t512\n/* This set of options configures the range of sector size to be supported. (512,\n/  1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and\n/  harddisk. But a larger value may be required for on-board flash memory and some\n/  type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured\n/  for variable sector size mode and disk_ioctl() function needs to implement\n/  GET_SECTOR_SIZE command. */\n\n\n#define FF_USE_TRIM\t\t0\n/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)\n/  To enable Trim function, also CTRL_TRIM command should be implemented to the\n/  disk_ioctl() function. */\n\n\n#define FF_FS_NOFSINFO\t1\n/* If you need to know correct free space on the FAT32 volume, set bit 0 of this\n/  option, and f_getfree() function at first time after volume mount will force\n/  a full FAT scan. Bit 1 controls the use of last allocated cluster number.\n/\n/  bit0=0: Use free cluster count in the FSINFO if available.\n/  bit0=1: Do not trust free cluster count in the FSINFO.\n/  bit1=0: Use last allocated cluster number in the FSINFO if available.\n/  bit1=1: Do not trust last allocated cluster number in the FSINFO.\n*/\n\n\n\n/*---------------------------------------------------------------------------/\n/ System Configurations\n/---------------------------------------------------------------------------*/\n\n#define FF_FS_TINY\t\t0\n/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)\n/  At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.\n/  Instead of private sector buffer eliminated from the file object, common sector\n/  buffer in the filesystem object (FATFS) is used for the file data transfer. */\n\n\n#define FF_FS_EXFAT\t\t1\n/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)\n/  To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)\n/  Note that enabling exFAT discards ANSI C (C89) compatibility. */\n\n\n#define FF_FS_NORTC\t\t1\n#define FF_NORTC_MON\t1\n#define FF_NORTC_MDAY\t1\n#define FF_NORTC_YEAR\t2019\n/* The option FF_FS_NORTC switches timestamp function. If the system does not have\n/  any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable\n/  the timestamp function. Every object modified by FatFs will have a fixed timestamp\n/  defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.\n/  To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be\n/  added to the project to read current time form real-time clock. FF_NORTC_MON,\n/  FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.\n/  These options have no effect at read-only configuration (FF_FS_READONLY = 1). */\n\n\n#define FF_FS_LOCK\t\t0\n/* The option FF_FS_LOCK switches file lock function to control duplicated file open\n/  and illegal operation to open objects. This option must be 0 when FF_FS_READONLY\n/  is 1.\n/\n/  0:  Disable file lock function. To avoid volume corruption, application program\n/      should avoid illegal open, remove and rename to the open objects.\n/  >0: Enable file lock function. The value defines how many files/sub-directories\n/      can be opened simultaneously under file lock control. Note that the file\n/      lock control is independent of re-entrancy. */\n\n\n/* #include <somertos.h>\t// O/S definitions */\n#define FF_FS_REENTRANT\t0\n#define FF_FS_TIMEOUT\t1000\n#define FF_SYNC_t\t\tHANDLE\n/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs\n/  module itself. Note that regardless of this option, file access to different\n/  volume is always re-entrant and volume control functions, f_mount(), f_mkfs()\n/  and f_fdisk() function, are always not re-entrant. Only file/directory access\n/  to the same volume is under control of this function.\n/\n/   0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.\n/   1: Enable re-entrancy. Also user provided synchronization handlers,\n/      ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()\n/      function, must be added to the project. Samples are available in\n/      option/syscall.c.\n/\n/  The FF_FS_TIMEOUT defines timeout period in unit of time tick.\n/  The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,\n/  SemaphoreHandle_t and etc. A header file for O/S definitions needs to be\n/  included somewhere in the scope of ff.h. */\n\n\n\n/*--- End of configuration options ---*/"
  },
  {
    "path": "argon-first-stage/include/mem/emc.h",
    "content": "/*\n * arch/arm/mach-tegra/tegra21_emc.h\n *\n * Copyright (c) 2014-2015, NVIDIA CORPORATION.  All rights reserved.\n * Copyright (c) 2018 Atmosphère-NX\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\n *\n */\n \n#ifndef FUSEE_EMC_H_\n#define FUSEE_EMC_H_\n\n#define EMC_BASE 0x7001B000\n#define EMC0_BASE 0x7001E000\n#define EMC1_BASE 0x7001F000\n#define MAKE_EMC_REG(n) MAKE_REG32(EMC_BASE + n)\n#define MAKE_EMC0_REG(n) MAKE_REG32(EMC0_BASE + n)\n#define MAKE_EMC1_REG(n) MAKE_REG32(EMC1_BASE + n)\n\n#define EMC_INTSTATUS                       0x0\n#define EMC_INTSTATUS_MRR_DIVLD                 (0x1 << 5)\n#define EMC_INTSTATUS_CLKCHANGE_COMPLETE            (0x1 << 4)\n\n#define EMC_INTMASK                     0x4\n#define EMC_DBG                         0x8\n#define EMC_DBG_WRITE_MUX_ACTIVE                (1 << 1)\n#define EMC_DBG_CFG_SWAP_SHIFT                  26\n#define EMC_DBG_CFG_SWAP_MASK                   \\\n    (0x3 << EMC_DBG_CFG_SWAP_SHIFT)\n#define EMC_DBG_WRITE_ACTIVE_ONLY               (1 << 30)\n\n#define EMC_CONFIG_SAMPLE_DELAY                 0x5f0\n#define EMC_CFG_UPDATE                      0x5f4\n#define EMC_CFG_UPDATE_UPDATE_DLL_IN_UPDATE_SHIFT       9\n#define EMC_CFG_UPDATE_UPDATE_DLL_IN_UPDATE_MASK        \\\n    (0x3 << EMC_CFG_UPDATE_UPDATE_DLL_IN_UPDATE_SHIFT)\n#define EMC_CFG                         0xc\n#define EMC_CFG_DRAM_CLKSTOP_PD                 (1 << 31)\n#define EMC_CFG_DRAM_CLKSTOP_SR                 (1 << 30)\n#define EMC_CFG_DRAM_ACPD                   (1 << 29)\n#define EMC_CFG_DYN_SELF_REF                    (1 << 28)\n#define EMC_CFG_REQACT_ASYNC                    (1 << 26)\n#define EMC_CFG_AUTO_PRE_WR                 (1 << 25)\n#define EMC_CFG_AUTO_PRE_RD                 (1 << 24)\n#define EMC_CFG_MAM_PRE_WR                  (1 << 23)\n#define EMC_CFG_MAN_PRE_RD                  (1 << 22)\n#define EMC_CFG_PERIODIC_QRST                   (1 << 21)\n#define EMC_CFG_PERIODIC_QRST_SHIFT             (21)\n#define EMC_CFG_EN_DYNAMIC_PUTERM               (1 << 20)\n#define EMC_CFG_DLY_WR_DQ_HALF_CLOCK                (1 << 19)\n#define EMC_CFG_DSR_VTTGEN_DRV_EN               (1 << 18)\n#define EMC_CFG_EMC2MC_CLK_RATIO                (3 << 16)\n#define EMC_CFG_WAIT_FOR_ISP2B_READY_B4_CC          (1 << 9)\n#define EMC_CFG_WAIT_FOR_VI2_READY_B4_CC            (1 << 8)\n#define EMC_CFG_WAIT_FOR_ISP2_READY_B4_CC           (1 << 7)\n#define EMC_CFG_INVERT_DQM                  (1 << 6)\n#define EMC_CFG_WAIT_FOR_DISPLAYB_READY_B4_CC           (1 << 5)\n#define EMC_CFG_WAIT_FOR_DISPLAY_READY_B4_CC            (1 << 4)\n#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE2         (1 << 3)\n#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE1         (1 << 2)\n#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_ADDRPIPE          (1 << 1)\n\n#define EMC_ADR_CFG                     0x10\n#define EMC_REFCTRL                     0x20\n#define EMC_REFCTRL_DEV_SEL_SHIFT               0\n#define EMC_REFCTRL_DEV_SEL_MASK                \\\n    (0x3 << EMC_REFCTRL_DEV_SEL_SHIFT)\n#define EMC_REFCTRL_ENABLE                  (0x1 << 31)\n#define EMC_REFCTRL_ENABLE_ALL(num)             \\\n    (((((num) > 1) ? 0 : 2) << EMC_REFCTRL_DEV_SEL_SHIFT)   \\\n     | EMC_REFCTRL_ENABLE)\n#define EMC_REFCTRL_DISABLE_ALL(num)                \\\n    ((((num) > 1) ? 0 : 2) << EMC_REFCTRL_DEV_SEL_SHIFT)\n\n#define EMC_PIN                         0x24\n#define EMC_PIN_PIN_CKE_PER_DEV                 (1 << 2)\n#define EMC_PIN_PIN_CKEB                    (1 << 1)\n#define EMC_PIN_PIN_CKE                     (1 << 0)\n\n#define EMC_CLK_FORCE_CC_TRIGGER                (1 << 27)\n\n#define EMC_TIMING_CONTROL                  0x28\n#define EMC_RC                          0x2c\n#define EMC_RFC                         0x30\n#define EMC_RFCPB                       0x590\n#define EMC_RAS                         0x34\n#define EMC_RP                          0x38\n#define EMC_R2W                         0x3c\n#define EMC_W2R                         0x40\n#define EMC_R2P                         0x44\n#define EMC_W2P                         0x48\n#define EMC_CCDMW                       0x5c0\n#define EMC_RD_RCD                      0x4c\n#define EMC_WR_RCD                      0x50\n#define EMC_RRD                         0x54\n#define EMC_REXT                        0x58\n#define EMC_WDV                         0x5c\n#define EMC_QUSE                        0x60\n#define EMC_QRST                        0x64\n#define EMC_ISSUE_QRST                      0x428\n#define EMC_QSAFE                       0x68\n#define EMC_RDV                         0x6c\n#define EMC_REFRESH                     0x70\n#define EMC_BURST_REFRESH_NUM                   0x74\n#define EMC_PDEX2WR                     0x78\n#define EMC_PDEX2RD                     0x7c\n#define EMC_PDEX2CKE                        0x118\n#define EMC_PCHG2PDEN                       0x80\n#define EMC_ACT2PDEN                        0x84\n#define EMC_AR2PDEN                     0x88\n#define EMC_RW2PDEN                     0x8c\n#define EMC_CKE2PDEN                        0x11c\n#define EMC_TXSR                        0x90\n#define EMC_TCKE                        0x94\n#define EMC_TFAW                        0x98\n#define EMC_TRPAB                       0x9c\n#define EMC_TCLKSTABLE                      0xa0\n#define EMC_TCLKSTOP                        0xa4\n#define EMC_TREFBW                      0xa8\n#define EMC_TPPD                        0xac\n#define EMC_PDEX2MRR                        0xb4\n#define EMC_ODT_WRITE                       0xb0\n#define EMC_WEXT                        0xb8\n#define EMC_RFC_SLR                     0xc0\n#define EMC_MRS_WAIT_CNT2                   0xc4\n#define EMC_MRS_WAIT_CNT2_MRS_EXT2_WAIT_CNT_SHIFT       16\n#define EMC_MRS_WAIT_CNT2_MRS_EXT2_WAIT_CNT_MASK        \\\n    (0x7ff << EMC_MRS_WAIT_CNT2_MRS_EXT2_WAIT_CNT_SHIFT)\n#define EMC_MRS_WAIT_CNT2_MRS_EXT1_WAIT_CNT_SHIFT       0\n#define EMC_MRS_WAIT_CNT2_MRS_EXT1_WAIT_CNT_MASK        \\\n    (0x3ff << EMC_MRS_WAIT_CNT2_MRS_EXT1_WAIT_CNT_SHIFT)\n\n#define EMC_MRS_WAIT_CNT                    0xc8\n#define EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT           0\n#define EMC_MRS_WAIT_CNT_SHORT_WAIT_MASK            \\\n    (0x3FF << EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT)\n#define EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT            16\n#define EMC_MRS_WAIT_CNT_LONG_WAIT_MASK             \\\n    (0x3FF << EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT)\n\n#define EMC_MRS                         0xcc\n#define EMC_MODE_SET_DLL_RESET                  (1 << 8)\n#define EMC_MRS_USE_MRS_LONG_CNT                (1 << 26)\n\n#define EMC_EMRS                        0xd0\n#define EMC_EMRS_USE_EMRS_LONG_CNT              (1 << 26)\n\n#define EMC_REF                         0xd4\n#define EMC_REF_FORCE_CMD                   1\n\n#define EMC_PRE                         0xd8\n#define EMC_NOP                         0xdc\n#define EMC_SELF_REF                            0xe0\n#define EMC_SELF_REF_CMD_ENABLED                (1 << 0)\n#define EMC_SELF_REF_ACTIVE_SELF_REF                (1 << 8)\n#define EMC_SELF_REF_DEV_SEL_SHIFT              30\n#define EMC_SELF_REF_DEV_SEL_MASK               \\\n    (0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)\n\n#define EMC_DPD                         0xe4\n#define EMC_MRW                         0xe8\n#define EMC_MRW_MRW_OP_SHIFT                    0\n#define EMC_MRW_MRW_OP_MASK                 \\\n    (0xff << EMC_MRW_MRW_OP_SHIFT)\n#define EMC_MRW_MRW_MA_SHIFT                    16\n#define EMC_MRW_MRW_MA_MASK                 \\\n    (0xff << EMC_MRW_MRW_MA_SHIFT)\n#define EMC_MRW_USE_MRW_LONG_CNT                26\n#define EMC_MRW_USE_MRW_EXT_CNT                 27\n#define EMC_MRW_MRW_DEV_SELECTN_SHIFT               30\n#define EMC_MRW_MRW_DEV_SELECTN_MASK                \\\n    (0x3 << EMC_MRW_MRW_DEV_SELECTN_SHIFT)\n\n#define EMC_MRR                         0xec\n#define EMC_MRR_DEV_SEL_SHIFT                   30\n#define EMC_MRR_DEV_SEL_MASK                    \\\n    (0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)\n#define EMC_MRR_MA_SHIFT                    16\n#define EMC_MRR_MA_MASK                     \\\n    (0xff << EMC_MRR_MA_SHIFT)\n#define EMC_MRR_DATA_SHIFT                  0\n#define EMC_MRR_DATA_MASK                   \\\n    (0xffff << EMC_MRR_DATA_SHIFT)\n#define LPDDR2_MR4_TEMP_SHIFT                   0\n#define LPDDR2_MR4_TEMP_MASK                    \\\n    (0x7 << LPDDR2_MR4_TEMP_SHIFT)\n\n#define EMC_CMDQ                        0xf0\n#define EMC_MC2EMCQ                     0xf4\n#define EMC_FBIO_SPARE                      0x100\n#define EMC_FBIO_CFG5                       0x104\n#define EMC_FBIO_CFG5_DRAM_TYPE_SHIFT               0\n#define EMC_FBIO_CFG5_DRAM_TYPE_MASK                \\\n    (0x3 << EMC_FBIO_CFG5_DRAM_TYPE_SHIFT)\n#define EMC_FBIO_CFG5_CMD_TX_DIS                (1 << 8)\n#define EMC_FBIO_CFG5_CMD_BUS_RETURN_TO_ZERO            (1 << 27)\n\n#define EMC_CFG5_QUSE_MODE_SHIFT                13\n#define EMC_CFG5_QUSE_MODE_MASK                 \\\n    (0x7 << EMC_CFG5_QUSE_MODE_SHIFT)\n\n#define EMC_CFG_RSV                     0x120\n#define EMC_ACPD_CONTROL                    0x124\n#define EMC_MPC                         0x128\n#define EMC_EMRS2                       0x12c\n#define EMC_EMRS2_USE_EMRS2_LONG_CNT                (1 << 26)\n\n#define EMC_EMRS3                       0x130\n#define EMC_MRW2                        0x134\n#define EMC_MRW3                        0x138\n#define EMC_MRW4                        0x13c\n#define EMC_MRW5                        0x4a0\n#define EMC_MRW6                        0x4a4\n#define EMC_MRW7                        0x4a8\n#define EMC_MRW8                        0x4ac\n#define EMC_MRW9                        0x4b0\n#define EMC_MRW10                       0x4b4\n#define EMC_MRW11                       0x4b8\n#define EMC_MRW12                       0x4bc\n#define EMC_MRW13                       0x4c0\n#define EMC_MRW14                       0x4c4\n#define EMC_MRW15                       0x4d0\n#define EMC_CFG_SYNC                        0x4d4\n#define EMC_CLKEN_OVERRIDE                  0x140\n#define EMC_R2R                         0x144\n#define EMC_W2W                         0x148\n#define EMC_EINPUT                      0x14c\n#define EMC_EINPUT_DURATION                     0x150\n#define EMC_PUTERM_EXTRA                    0x154\n#define EMC_TCKESR                      0x158\n#define EMC_TPD                         0x15c\n#define EMC_STAT_CONTROL                    0x160\n#define EMC_STAT_STATUS                     0x164\n#define EMC_STAT_DRAM_CLOCK_LIMIT_LO                0x19c\n#define EMC_STAT_DRAM_CLOCK_LIMIT_HI                0x1a0\n#define EMC_STAT_DRAM_CLOCKS_LO                 0x1a4\n#define EMC_STAT_DRAM_CLOCKS_HI                 0x1a8\n#define EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_LO          0x1ac\n#define EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_HI          0x1b0\n#define EMC_STAT_DRAM_DEV0_READ_CNT_LO              0x1b4\n#define EMC_STAT_DRAM_DEV0_READ_CNT_HI              0x1b8\n#define EMC_STAT_DRAM_DEV0_READ8_CNT_LO             0x1bc\n#define EMC_STAT_DRAM_DEV0_READ8_CNT_HI             0x1c0\n#define EMC_STAT_DRAM_DEV0_WRITE_CNT_LO             0x1c4\n#define EMC_STAT_DRAM_DEV0_WRITE_CNT_HI             0x1c8\n#define EMC_STAT_DRAM_DEV0_WRITE8_CNT_LO            0x1cc\n#define EMC_STAT_DRAM_DEV0_WRITE8_CNT_HI            0x1d0\n#define EMC_STAT_DRAM_DEV0_REF_CNT_LO               0x1d4\n#define EMC_STAT_DRAM_DEV0_REF_CNT_HI               0x1d8\n#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO  0x1dc\n#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI  0x1e0\n#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO  0x1e4\n#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI  0x1e8\n#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO  0x1ec\n#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI  0x1f0\n#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO  0x1f4\n#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI  0x1f8\n#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO    0x1fc\n#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI    0x200\n#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO    0x204\n#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI    0x208\n#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO    0x20c\n#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI    0x210\n#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO    0x214\n#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI    0x218\n#define EMC_STAT_DRAM_DEV0_SR_CKE_EQ0_CLKS_LO               0x21c\n#define EMC_STAT_DRAM_DEV0_SR_CKE_EQ0_CLKS_HI               0x220\n#define EMC_STAT_DRAM_DEV0_DSR                      0x224\n#define EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_LO              0x228\n#define EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_HI              0x22c\n#define EMC_STAT_DRAM_DEV1_READ_CNT_LO                  0x230\n#define EMC_STAT_DRAM_DEV1_READ_CNT_HI                  0x234\n#define EMC_STAT_DRAM_DEV1_READ8_CNT_LO                 0x238\n#define EMC_STAT_DRAM_DEV1_READ8_CNT_HI                 0x23c\n#define EMC_STAT_DRAM_DEV1_WRITE_CNT_LO                 0x240\n#define EMC_STAT_DRAM_DEV1_WRITE_CNT_HI                 0x244\n#define EMC_STAT_DRAM_DEV1_WRITE8_CNT_LO                0x248\n#define EMC_STAT_DRAM_DEV1_WRITE8_CNT_HI                0x24c\n#define EMC_STAT_DRAM_DEV1_REF_CNT_LO                   0x250\n#define EMC_STAT_DRAM_DEV1_REF_CNT_HI                   0x254\n#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO  0x258\n#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI  0x25c\n#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO  0x260\n#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI  0x264\n#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO  0x268\n#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI  0x26c\n#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO  0x270\n#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI  0x274\n#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO    0x278\n#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI    0x27c\n#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO    0x280\n#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI    0x284\n#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO    0x288\n#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI    0x28c\n#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO    0x290\n#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI    0x294\n#define EMC_STAT_DRAM_DEV1_SR_CKE_EQ0_CLKS_LO               0x298\n#define EMC_STAT_DRAM_DEV1_SR_CKE_EQ0_CLKS_HI               0x29c\n#define EMC_STAT_DRAM_DEV1_DSR                      0x2a0\n#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO    0xc8c\n#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI    0xc90\n#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO    0xc94\n#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI    0xc98\n#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO    0xc9c\n#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI    0xca0\n#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO    0xca4\n#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI    0xca8\n#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO  0xcac\n#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI  0xcb0\n#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO  0xcb4\n#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI  0xcb8\n#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO  0xcbc\n#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI  0xcc0\n#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO  0xcc4\n#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI  0xcc8\n#define EMC_STAT_DRAM_IO_SR_CKE_EQ0_CLKS_LO         0xccc\n#define EMC_STAT_DRAM_IO_SR_CKE_EQ0_CLKS_HI         0xcd0\n#define EMC_STAT_DRAM_IO_DSR                    0xcd4\n#define EMC_AUTO_CAL_CONFIG                 0x2a4\n#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_COMPUTE_START      (1 << 0)\n#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_MEASURE_STALL      (1 << 9)\n#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_UPDATE_STALL       (1 << 10)\n#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_ENABLE         (1 << 29)\n#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_START          (1 << 31)\n\n#define EMC_AUTO_CAL_CONFIG2                    0x458\n#define EMC_AUTO_CAL_CONFIG3                    0x45c\n#define EMC_AUTO_CAL_CONFIG4                    0x5b0\n#define EMC_AUTO_CAL_CONFIG5                    0x5b4\n#define EMC_AUTO_CAL_CONFIG6                    0x5cc\n#define EMC_AUTO_CAL_CONFIG7                    0x574\n#define EMC_AUTO_CAL_CONFIG8                    0x2dc\n#define EMC_AUTO_CAL_VREF_SEL_0                 0x2f8\n#define EMC_AUTO_CAL_VREF_SEL_1                 0x300\n#define EMC_AUTO_CAL_INTERVAL                   0x2a8\n#define EMC_AUTO_CAL_STATUS                 0x2ac\n#define EMC_AUTO_CAL_STATUS2                    0x3d4\n#define EMC_AUTO_CAL_CHANNEL                    0x464\n#define EMC_PMACRO_RX_TERM                  0xc48\n#define EMC_PMACRO_DQ_TX_DRV                    0xc70\n#define EMC_PMACRO_CA_TX_DRV                    0xc74\n#define EMC_PMACRO_CMD_TX_DRV                   0xc4c\n#define EMC_PMACRO_AUTOCAL_CFG_0                0x700\n#define EMC_PMACRO_AUTOCAL_CFG_1                0x704\n#define EMC_PMACRO_AUTOCAL_CFG_2                0x708\n#define EMC_PMACRO_AUTOCAL_CFG_COMMON               0xc78\n#define EMC_PMACRO_AUTOCAL_CFG_COMMON_E_CAL_BYPASS_DVFS     (1 << 16)\n\n#define EMC_PMACRO_ZCTRL                    0xc44\n#define EMC_XM2COMPPADCTRL                  0x30c\n#define EMC_XM2COMPPADCTRL_VREF_CAL_ENABLE          (1 << 10)\n\n#define EMC_XM2COMPPADCTRL2                 0x578\n#define EMC_XM2COMPPADCTRL3                 0x2f4\n#define EMC_COMP_PAD_SW_CTRL                    0x57c\n#define EMC_REQ_CTRL                        0x2b0\n#define EMC_EMC_STATUS                      0x2b4\n#define EMC_EMC_STATUS_MRR_DIVLD                (1 << 20)\n#define EMC_EMC_STATUS_TIMING_UPDATE_STALLED            (1 << 23)\n#define EMC_EMC_STATUS_DRAM_IN_POWERDOWN_SHIFT          4\n#define EMC_EMC_STATUS_DRAM_IN_POWERDOWN_MASK           \\\n    (0x3 << EMC_EMC_STATUS_DRAM_IN_POWERDOWN_SHIFT)\n#define EMC_EMC_STATUS_DRAM_IN_SELF_REFRESH_SHIFT       8\n#define EMC_EMC_STATUS_DRAM_IN_SELF_REFRESH_MASK        \\\n    (0x3 << EMC_EMC_STATUS_DRAM_IN_SELF_REFRESH_SHIFT)\n\n#define EMC_CFG_2                       0x2b8\n#define EMC_CFG_DIG_DLL                     0x2bc\n#define EMC_CFG_DIG_DLL_CFG_DLL_EN              (1 << 0)\n#define EMC_CFG_DIG_DLL_CFG_DLL_STALL_ALL_UNTIL_LOCK        (1 << 1)\n#define EMC_CFG_DIG_DLL_CFG_DLL_STALL_ALL_TRAFFIC       (1 << 3)\n#define EMC_CFG_DIG_DLL_CFG_DLL_STALL_RW_UNTIL_LOCK     (1 << 4)\n#define EMC_CFG_DIG_DLL_CFG_DLL_MODE_SHIFT          6\n#define EMC_CFG_DIG_DLL_CFG_DLL_MODE_MASK           \\\n    (0x3 << EMC_CFG_DIG_DLL_CFG_DLL_MODE_SHIFT)\n#define EMC_CFG_DIG_DLL_CFG_DLL_LOCK_LIMIT_SHIFT        8\n#define EMC_CFG_DIG_DLL_CFG_DLL_LOCK_LIMIT_MASK         \\\n    (0x7 << EMC_CFG_DIG_DLL_CFG_DLL_LOCK_LIMIT_SHIFT)\n\n#define EMC_CFG_DIG_DLL_PERIOD                  0x2c0\n#define EMC_DIG_DLL_STATUS                  0x2c4\n#define EMC_DIG_DLL_STATUS_DLL_LOCK             (1 << 15)\n#define EMC_DIG_DLL_STATUS_DLL_PRIV_UPDATED         (1 << 17)\n#define EMC_DIG_DLL_STATUS_DLL_OUT_SHIFT            0\n#define EMC_DIG_DLL_STATUS_DLL_OUT_MASK             \\\n    (0x7ff << EMC_DIG_DLL_STATUS_DLL_OUT_SHIFT)\n\n#define EMC_CFG_DIG_DLL_1                   0x2c8\n#define EMC_RDV_MASK                        0x2cc\n#define EMC_WDV_MASK                        0x2d0\n#define EMC_RDV_EARLY_MASK                  0x2d4\n#define EMC_RDV_EARLY                       0x2d8\n#define EMC_WDV_CHK                     0x4e0\n#define EMC_ZCAL_INTERVAL                   0x2e0\n#define EMC_ZCAL_WAIT_CNT                   0x2e4\n#define EMC_ZCAL_WAIT_CNT_ZCAL_WAIT_CNT_MASK            0x7ff\n#define EMC_ZCAL_WAIT_CNT_ZCAL_WAIT_CNT_SHIFT           0\n\n#define EMC_ZCAL_MRW_CMD                    0x2e8\n#define EMC_ZQ_CAL                      0x2ec\n#define EMC_ZQ_CAL_DEV_SEL_SHIFT                30\n#define EMC_ZQ_CAL_DEV_SEL_MASK                 \\\n    (0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)\n#define EMC_ZQ_CAL_LONG                     (1 << 4)\n#define EMC_ZQ_CAL_ZQ_LATCH_CMD                 (1 << 1)\n#define EMC_ZQ_CAL_ZQ_CAL_CMD                   (1 << 0)\n#define EMC_ZQ_CAL_LONG_CMD_DEV0                \\\n    (DRAM_DEV_SEL_0 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD)\n#define EMC_ZQ_CAL_LONG_CMD_DEV1                \\\n    (DRAM_DEV_SEL_1 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD)\n\n#define EMC_SCRATCH0                        0x324\n#define EMC_STALL_THEN_EXE_BEFORE_CLKCHANGE         0x3c8\n#define EMC_STALL_THEN_EXE_AFTER_CLKCHANGE          0x3cc\n#define EMC_UNSTALL_RW_AFTER_CLKCHANGE              0x3d0\n#define EMC_FDPD_CTRL_CMD_NO_RAMP               0x4d8\n#define EMC_FDPD_CTRL_CMD_NO_RAMP_CMD_DPD_NO_RAMP_ENABLE    (1 << 0)\n\n#define EMC_SEL_DPD_CTRL                    0x3d8\n#define EMC_SEL_DPD_CTRL_DATA_SEL_DPD_EN            (1 << 8)\n#define EMC_SEL_DPD_CTRL_ODT_SEL_DPD_EN             (1 << 5)\n#define EMC_SEL_DPD_CTRL_RESET_SEL_DPD_EN           (1 << 4)\n#define EMC_SEL_DPD_CTRL_CA_SEL_DPD_EN              (1 << 3)\n#define EMC_SEL_DPD_CTRL_CLK_SEL_DPD_EN             (1 << 2)\n#define EMC_SEL_DPD_CTRL_DDR3_MASK              \\\n    ((0xf << 2) | (0x1 << 8))\n#define EMC_SEL_DPD_CTRL_MAS                    \\\n    ((0x3 << 2) | (0x1 << 5) | (0x1 << 8))\n\n#define EMC_FDPD_CTRL_DQ                    0x310\n#define EMC_FDPD_CTRL_CMD                   0x314\n#define EMC_PRE_REFRESH_REQ_CNT                 0x3dc\n#define EMC_REFCTRL2                        0x580\n#define EMC_FBIO_CFG7                       0x584\n#define EMC_FBIO_CFG7_CH0_ENABLE                (1 << 1)\n#define EMC_FBIO_CFG7_CH1_ENABLE                (1 << 2)\n\n#define EMC_DATA_BRLSHFT_0                  0x588\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_SHIFT   21\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_SHIFT   18\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_SHIFT   15\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_SHIFT   12\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_SHIFT   9\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_SHIFT   6\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_SHIFT   3\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_SHIFT   0\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_SHIFT)\n\n#define EMC_DATA_BRLSHFT_1                  0x58c\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_SHIFT   21\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_SHIFT   18\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_SHIFT   15\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_SHIFT   12\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_SHIFT   9\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_SHIFT   6\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_SHIFT   3\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_SHIFT   0\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_SHIFT)\n\n#define EMC_DQS_BRLSHFT_0                   0x594\n#define EMC_DQS_BRLSHFT_1                   0x598\n#define EMC_CMD_BRLSHFT_0                   0x59c\n#define EMC_CMD_BRLSHFT_1                   0x5a0\n#define EMC_CMD_BRLSHFT_2                   0x5a4\n#define EMC_CMD_BRLSHFT_3                   0x5a8\n#define EMC_QUSE_BRLSHFT_0                  0x5ac\n#define EMC_QUSE_BRLSHFT_1                  0x5b8\n#define EMC_QUSE_BRLSHFT_2                  0x5bc\n#define EMC_QUSE_BRLSHFT_3                  0x5c4\n#define EMC_FBIO_CFG8                       0x5c8\n#define EMC_CMD_MAPPING_CMD0_0                  0x380\n#define EMC_CMD_MAPPING_CMD0_1                  0x384\n#define EMC_CMD_MAPPING_CMD0_2                  0x388\n#define EMC_CMD_MAPPING_CMD1_0                  0x38c\n#define EMC_CMD_MAPPING_CMD1_1                  0x390\n#define EMC_CMD_MAPPING_CMD1_2                  0x394\n#define EMC_CMD_MAPPING_CMD2_0                  0x398\n#define EMC_CMD_MAPPING_CMD2_1                  0x39c\n#define EMC_CMD_MAPPING_CMD2_2                  0x3a0\n#define EMC_CMD_MAPPING_CMD3_0                  0x3a4\n#define EMC_CMD_MAPPING_CMD3_1                  0x3a8\n#define EMC_CMD_MAPPING_CMD3_2                  0x3ac\n#define EMC_CMD_MAPPING_BYTE                    0x3b0\n#define EMC_DYN_SELF_REF_CONTROL                0x3e0\n#define EMC_TXSRDLL                     0x3e4\n#define EMC_CCFIFO_ADDR                     0x3e8\n#define EMC_CCFIFO_DATA                     0x3ec\n#define EMC_CCFIFO_STATUS                   0x3f0\n#define EMC_SWIZZLE_RANK0_BYTE0                 0x404\n#define EMC_SWIZZLE_RANK0_BYTE1                 0x408\n#define EMC_SWIZZLE_RANK0_BYTE2                 0x40c\n#define EMC_SWIZZLE_RANK0_BYTE3                 0x410\n#define EMC_SWIZZLE_RANK1_BYTE0                 0x418\n#define EMC_SWIZZLE_RANK1_BYTE1                 0x41c\n#define EMC_SWIZZLE_RANK1_BYTE2                 0x420\n#define EMC_SWIZZLE_RANK1_BYTE3                 0x424\n#define EMC_TR_TIMING_0                     0x3b4\n#define EMC_TR_CTRL_0                       0x3b8\n#define EMC_TR_CTRL_1                       0x3bc\n#define EMC_TR_DVFS                     0x460\n#define EMC_TR_DVFS_TRAINING_DVFS               (1 << 0)\n\n#define EMC_SWITCH_BACK_CTRL                    0x3c0\n#define EMC_TR_RDV                      0x3c4\n#define EMC_TR_QPOP                     0x3f4\n#define EMC_TR_RDV_MASK                     0x3f8\n#define EMC_TR_QSAFE                        0x3fc\n#define EMC_TR_QRST                     0x400\n#define EMC_IBDLY                       0x468\n#define EMC_OBDLY                       0x46c\n#define EMC_TXDSRVTTGEN                     0x480\n#define EMC_WE_DURATION                     0x48c\n#define EMC_WS_DURATION                     0x490\n#define EMC_WEV                         0x494\n#define EMC_WSV                         0x498\n#define EMC_CFG_3                       0x49c\n#define EMC_CFG_PIPE_2                      0x554\n#define EMC_CFG_PIPE_CLK                    0x558\n#define EMC_CFG_PIPE_CLK_CLK_ALWAYS_ON              (1 << 0)\n\n#define EMC_CFG_PIPE_1                      0x55c\n#define EMC_CFG_PIPE                        0x560\n#define EMC_QPOP                        0x564\n#define EMC_QUSE_WIDTH                      0x568\n#define EMC_PUTERM_WIDTH                    0x56c\n#define EMC_PROTOBIST_CONFIG_ADR_1              0x5d0\n#define EMC_PROTOBIST_CONFIG_ADR_2              0x5d4\n#define EMC_PROTOBIST_MISC                  0x5d8\n#define EMC_PROTOBIST_WDATA_LOWER               0x5dc\n#define EMC_PROTOBIST_WDATA_UPPER               0x5e0\n#define EMC_PROTOBIST_RDATA                 0x5ec\n#define EMC_DLL_CFG_0                       0x5e4\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_IGNORE_START         (1 << 29)\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_DUAL_PASS_LOCK       (1 << 28)\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_STEP_SIZE_SHIFT      24\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_STEP_SIZE_MASK       \\\n    (0xf << EMC_DLL_CFG_0_DDLLCAL_CTRL_STEP_SIZE_SHIFT)\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_END_COUNT_SHIFT      20\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_END_COUNT_MASK       \\\n    (0xf << EMC_DLL_CFG_0_DDLLCAL_CTRL_END_COUNT_SHIFT)\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_FILTER_BITS_SHIFT        16\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_FILTER_BITS_MASK     \\\n    (0xf << EMC_DLL_CFG_0_DDLLCAL_CTRL_FILTER_BITS_SHIFT)\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_COUNT_SHIFT       12\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_COUNT_MASK        \\\n    (0xf << EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_COUNT_SHIFT)\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_DELAY_SHIFT       4\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_DELAY_MASK        \\\n    (0xff << EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_DELAY_SHIFT)\n#define EMC_DLL_CFG_0_DDLLCAL_UPDATE_CNT_LIMIT_SHIFT        0\n#define EMC_DLL_CFG_0_DDLLCAL_UPDATE_CNT_LIMIT_MASK     \\\n    (0xf << EMC_DLL_CFG_0_DDLLCAL_UPDATE_CNT_LIMIT_SHIFT)\n\n#define EMC_DLL_CFG_1                       0x5e8\n#define EMC_DLL_CFG_1_DDLLCAL_CTRL_START_TRIM_SHIFT     10\n#define EMC_DLL_CFG_1_DDLLCAL_CTRL_START_TRIM_MASK      \\\n    (0x7ff << EMC_DLL_CFG_1_DDLLCAL_CTRL_START_TRIM_SHIFT)\n\n#define EMC_TRAINING_CMD                    0xe00\n#define EMC_TRAINING_CMD_PRIME                  (1 << 0)\n#define EMC_TRAINING_CMD_CA                 (1 << 1)\n#define EMC_TRAINING_CMD_RD                 (1 << 2)\n#define EMC_TRAINING_CMD_WR                 (1 << 3)\n#define EMC_TRAINING_CMD_QUSE                   (1 << 4)\n#define EMC_TRAINING_CMD_CA_VREF                (1 << 5)\n#define EMC_TRAINING_CMD_RD_VREF                (1 << 6)\n#define EMC_TRAINING_CMD_WR_VREF                (1 << 7)\n#define EMC_TRAINING_CMD_QUSE_VREF              (1 << 8)\n#define EMC_TRAINING_CMD_GO                 (1 << 31)\n\n#define EMC_TRAINING_CTRL                   0xe04\n#define EMC_TRAINING_CTRL_SWAP_RANK             (1 << 14)\n\n#define EMC_TRAINING_STATUS                 0xe08\n#define EMC_TRAINING_QUSE_CORS_CTRL             0xe0c\n#define EMC_TRAINING_QUSE_FINE_CTRL             0xe10\n#define EMC_TRAINING_QUSE_CTRL_MISC             0xe14\n#define EMC_TRAINING_WRITE_FINE_CTRL                0xe18\n#define EMC_TRAINING_WRITE_CTRL_MISC                0xe1c\n#define EMC_TRAINING_WRITE_VREF_CTRL                0xe20\n#define EMC_TRAINING_READ_FINE_CTRL             0xe24\n#define EMC_TRAINING_READ_CTRL_MISC             0xe28\n#define EMC_TRAINING_READ_VREF_CTRL             0xe2c\n#define EMC_TRAINING_CA_FINE_CTRL               0xe30\n#define EMC_TRAINING_CA_CTRL_MISC               0xe34\n#define EMC_TRAINING_CA_CTRL_MISC1              0xe38\n#define EMC_TRAINING_CA_VREF_CTRL               0xe3c\n#define EMC_TRAINING_CA_TADR_CTRL               0xe40\n#define EMC_TRAINING_SETTLE                 0xe44\n#define EMC_TRAINING_DEBUG_CTRL                 0xe48\n#define EMC_TRAINING_DEBUG_DQ0                  0xe4c\n#define EMC_TRAINING_DEBUG_DQ1                  0xe50\n#define EMC_TRAINING_DEBUG_DQ2                  0xe54\n#define EMC_TRAINING_DEBUG_DQ3                  0xe58\n#define EMC_TRAINING_MPC                    0xe5c\n#define EMC_TRAINING_PATRAM_CTRL                0xe60\n#define EMC_TRAINING_PATRAM_DQ                  0xe64\n#define EMC_TRAINING_PATRAM_DMI                 0xe68\n#define EMC_TRAINING_VREF_SETTLE                0xe6c\n#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE0         0xe70\n#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE1         0xe74\n#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE2         0xe78\n#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE3         0xe7c\n#define EMC_TRAINING_RW_EYE_CENTER_IB_MISC          0xe80\n#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE0         0xe84\n#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE1         0xe88\n#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE2         0xe8c\n#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE3         0xe90\n#define EMC_TRAINING_RW_EYE_CENTER_OB_MISC          0xe94\n#define EMC_TRAINING_RW_OFFSET_IB_BYTE0             0xe98\n#define EMC_TRAINING_RW_OFFSET_IB_BYTE1             0xe9c\n#define EMC_TRAINING_RW_OFFSET_IB_BYTE2             0xea0\n#define EMC_TRAINING_RW_OFFSET_IB_BYTE3             0xea4\n#define EMC_TRAINING_RW_OFFSET_IB_MISC              0xea8\n#define EMC_TRAINING_RW_OFFSET_OB_BYTE0             0xeac\n#define EMC_TRAINING_RW_OFFSET_OB_BYTE1             0xeb0\n#define EMC_TRAINING_RW_OFFSET_OB_BYTE2             0xeb4\n#define EMC_TRAINING_RW_OFFSET_OB_BYTE3             0xeb8\n#define EMC_TRAINING_RW_OFFSET_OB_MISC              0xebc\n#define EMC_TRAINING_OPT_CA_VREF                0xec0\n#define EMC_TRAINING_OPT_DQ_OB_VREF             0xec4\n#define EMC_TRAINING_OPT_DQ_IB_VREF_RANK0           0xec8\n#define EMC_TRAINING_OPT_DQ_IB_VREF_RANK1           0xecc\n#define EMC_TRAINING_QUSE_VREF_CTRL             0xed0\n#define EMC_TRAINING_OPT_DQS_IB_VREF_RANK0          0xed4\n#define EMC_TRAINING_OPT_DQS_IB_VREF_RANK1          0xed8\n#define EMC_TRAINING_DRAMC_TIMING               0xedc\n#define EMC_PMACRO_QUSE_DDLL_RANK0_0                0x600\n#define EMC_PMACRO_QUSE_DDLL_RANK0_1                0x604\n#define EMC_PMACRO_QUSE_DDLL_RANK0_2                0x608\n#define EMC_PMACRO_QUSE_DDLL_RANK0_3                0x60c\n#define EMC_PMACRO_QUSE_DDLL_RANK0_4                0x610\n#define EMC_PMACRO_QUSE_DDLL_RANK0_5                0x614\n#define EMC_PMACRO_QUSE_DDLL_RANK1_0                0x620\n#define EMC_PMACRO_QUSE_DDLL_RANK1_1                0x624\n#define EMC_PMACRO_QUSE_DDLL_RANK1_2                0x628\n#define EMC_PMACRO_QUSE_DDLL_RANK1_3                0x62c\n#define EMC_PMACRO_QUSE_DDLL_RANK1_4                0x630\n#define EMC_PMACRO_QUSE_DDLL_RANK1_5                0x634\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0          0x640\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE1_SHIFT \\\n    16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE1_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE1_SHIFT\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE0_SHIFT \\\n    0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE0_MASK \\\n    0x3ff <<                                \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE0_SHIFT\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1          0x644\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE3_SHIFT \\\n    16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE3_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE3_SHIFT\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE2_SHIFT \\\n    0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE2_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE2_SHIFT\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2          0x648\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE5_SHIFT  \\\n    16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE5_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE5_SHIFT\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE4_SHIFT \\\n    0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE4_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE4_SHIFT\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3          0x64c\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE7_SHIFT \\\n    16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE7_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE7_SHIFT\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE6_SHIFT \\\n    0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE6_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE6_SHIFT\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4          0x650\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5          0x654\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0          0x660\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE1_SHIFT \\\n    16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE1_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE1_SHIFT\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE0_SHIFT \\\n    0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE0_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE0_SHIFT\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1          0x664\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE3_SHIFT \\\n    16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE3_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE3_SHIFT\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE2_SHIFT \\\n    0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE2_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE2_SHIFT\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2          0x668\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE5_SHIFT \\\n    16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE5_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE5_SHIFT\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE4_SHIFT \\\n    0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE4_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE4_SHIFT\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3          0x66c\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE7_SHIFT \\\n    16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE7_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE7_SHIFT\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE6_SHIFT \\\n    0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE6_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE6_SHIFT\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4          0x670\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5          0x674\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0         0x680\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1         0x684\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2         0x688\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3         0x68c\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4         0x690\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5         0x694\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0         0x6a0\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1         0x6a4\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2         0x6a8\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3         0x6ac\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4         0x6b0\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5         0x6b4\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0         0x6c0\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1         0x6c4\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2         0x6c8\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3         0x6cc\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_4         0x6d0\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_5         0x6d4\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0         0x6e0\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1         0x6e4\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2         0x6e8\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3         0x6ec\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_4         0x6f0\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_5         0x6f4\n#define EMC_PMACRO_TX_PWRD_0                    0x720\n#define EMC_PMACRO_TX_PWRD_1                    0x724\n#define EMC_PMACRO_TX_PWRD_2                    0x728\n#define EMC_PMACRO_TX_PWRD_3                    0x72c\n#define EMC_PMACRO_TX_PWRD_4                    0x730\n#define EMC_PMACRO_TX_PWRD_5                    0x734\n#define EMC_PMACRO_TX_SEL_CLK_SRC_0             0x740\n#define EMC_PMACRO_TX_SEL_CLK_SRC_1             0x744\n#define EMC_PMACRO_TX_SEL_CLK_SRC_3             0x74c\n#define EMC_PMACRO_TX_SEL_CLK_SRC_2             0x748\n#define EMC_PMACRO_TX_SEL_CLK_SRC_4             0x750\n#define EMC_PMACRO_TX_SEL_CLK_SRC_5             0x754\n#define EMC_PMACRO_DDLL_BYPASS                  0x760\n#define EMC_PMACRO_DDLL_PWRD_0                  0x770\n#define EMC_PMACRO_DDLL_PWRD_1                  0x774\n#define EMC_PMACRO_DDLL_PWRD_2                  0x778\n#define EMC_PMACRO_CMD_CTRL_0                   0x780\n#define EMC_PMACRO_CMD_CTRL_1                   0x784\n#define EMC_PMACRO_CMD_CTRL_2                   0x788\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_0       0x800\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_1       0x804\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_2       0x808\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_3       0x80c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_0       0x810\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_1       0x814\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_2       0x818\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_3       0x81c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_0       0x820\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_1       0x824\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_2       0x828\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_3       0x82c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_0       0x830\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_1       0x834\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_2       0x838\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_3       0x83c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_0       0x840\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_1       0x844\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_2       0x848\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_3       0x84c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_0       0x850\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_1       0x854\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_2       0x858\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_3       0x85c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_0       0x860\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_1       0x864\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_2       0x868\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_3       0x86c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_0       0x870\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_1       0x874\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_2       0x878\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_3       0x87c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_0        0x880\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_1        0x884\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_2        0x888\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_3        0x88c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_0        0x890\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_1        0x894\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_2        0x898\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_3        0x89c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_0        0x8a0\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_1        0x8a4\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_2        0x8a8\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_3        0x8ac\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_0        0x8b0\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_1        0x8b4\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_2        0x8b8\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_3        0x8bc\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_0       0x900\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_1       0x904\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_2       0x908\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_3       0x90c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_0       0x910\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_1       0x914\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_2       0x918\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_3       0x91c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_0       0x920\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_1       0x924\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_2       0x928\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_3       0x92c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_0       0x930\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_1       0x934\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_2       0x938\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_3       0x93c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_0       0x940\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_1       0x944\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_2       0x948\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_3       0x94c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_0       0x950\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_1       0x954\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_2       0x958\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_3       0x95c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_0       0x960\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_1       0x964\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_2       0x968\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_3       0x96c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_0       0x970\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_1       0x974\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_2       0x978\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_3       0x97c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_0        0x980\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_1        0x984\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_2        0x988\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_3        0x98c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_0        0x990\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_1        0x994\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_2        0x998\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_3        0x99c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_0        0x9a0\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_1        0x9a4\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_2        0x9a8\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_3        0x9ac\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_0        0x9b0\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_1        0x9b4\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_2        0x9b8\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_3        0x9bc\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_0       0xa00\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_1       0xa04\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_2       0xa08\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_0       0xa10\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_1       0xa14\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_2       0xa18\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_0       0xa20\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_1       0xa24\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_2       0xa28\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_0       0xa30\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_1       0xa34\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_2       0xa38\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_0       0xa40\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_1       0xa44\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_2       0xa48\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_0       0xa50\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_1       0xa54\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_2       0xa58\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_0       0xa60\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_1       0xa64\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_2       0xa68\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_0       0xa70\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_1       0xa74\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_2       0xa78\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_0        0xa80\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_1        0xa84\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_2        0xa88\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_0        0xa90\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_1        0xa94\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_2        0xa98\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_0        0xaa0\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_1        0xaa4\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_2        0xaa8\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_0        0xab0\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_1        0xab4\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_2        0xab8\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_0       0xb00\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_1       0xb04\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_2       0xb08\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_0       0xb10\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_1       0xb14\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_2       0xb18\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_0       0xb20\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_1       0xb24\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_2       0xb28\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_0       0xb30\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_1       0xb34\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_2       0xb38\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_0       0xb40\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_1       0xb44\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_2       0xb48\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_0       0xb50\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_1       0xb54\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_2       0xb58\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_0       0xb60\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_1       0xb64\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_2       0xb68\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_0       0xb70\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_1       0xb74\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_2       0xb78\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_0        0xb80\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_1        0xb84\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_2        0xb88\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_0        0xb90\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_1        0xb94\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_2        0xb98\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_0        0xba0\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_1        0xba4\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_2        0xba8\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_0        0xbb0\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_1        0xbb4\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_2        0xbb8\n#define EMC_PMACRO_IB_VREF_DQ_0                 0xbe0\n#define EMC_PMACRO_IB_VREF_DQ_1                 0xbe4\n#define EMC_PMACRO_IB_VREF_DQ_2                 0xbe8\n#define EMC_PMACRO_IB_VREF_DQS_0                0xbf0\n#define EMC_PMACRO_IB_VREF_DQS_1                0xbf4\n#define EMC_PMACRO_IB_VREF_DQS_2                0xbf8\n#define EMC_PMACRO_IB_RXRT                  0xcf4\n#define EMC_PMACRO_DDLL_LONG_CMD_0              0xc00\n#define EMC_PMACRO_DDLL_LONG_CMD_1              0xc04\n#define EMC_PMACRO_DDLL_LONG_CMD_2              0xc08\n#define EMC_PMACRO_DDLL_LONG_CMD_3              0xc0c\n#define EMC_PMACRO_DDLL_LONG_CMD_4              0xc10\n#define EMC_PMACRO_DDLL_LONG_CMD_5              0xc14\n#define EMC_PMACRO_DDLL_SHORT_CMD_0             0xc20\n#define EMC_PMACRO_DDLL_SHORT_CMD_1             0xc24\n#define EMC_PMACRO_DDLL_SHORT_CMD_2             0xc28\n#define EMC_PMACRO_CFG_PM_GLOBAL_0              0xc30\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE0        (1 << 16)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE1        (1 << 17)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE2        (1 << 18)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE3        (1 << 19)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE4        (1 << 20)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE5        (1 << 21)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE6        (1 << 22)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE7        (1 << 23)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD0     (1 << 24)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD1     (1 << 25)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD2     (1 << 26)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD3     (1 << 27)\n\n#define EMC_PMACRO_VTTGEN_CTRL_0                0xc34\n#define EMC_PMACRO_VTTGEN_CTRL_1                0xc38\n#define EMC_PMACRO_VTTGEN_CTRL_2                0xcf0\n#define EMC_PMACRO_BG_BIAS_CTRL_0               0xc3c\n#define EMC_PMACRO_BG_BIAS_CTRL_0_BG_E_PWRD         (1 << 0)\n#define EMC_PMACRO_BG_BIAS_CTRL_0_BG_MODE           (1 << 1)\n#define EMC_PMACRO_BG_BIAS_CTRL_0_BGLP_E_PWRD           (1 << 2)\n\n#define EMC_PMACRO_PAD_CFG_CTRL                 0xc40\n#define EMC_PMACRO_CMD_PAD_RX_CTRL              0xc50\n#define EMC_PMACRO_DATA_PAD_RX_CTRL             0xc54\n#define EMC_PMACRO_CMD_RX_TERM_MODE             0xc58\n#define EMC_PMACRO_DATA_RX_TERM_MODE                0xc5c\n#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSN_RX_TERM_MODE_SHIFT 8\n#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSN_RX_TERM_MODE_MASK (0x3 << \\\n    EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSN_RX_TERM_MODE_SHIFT)\n#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSP_RX_TERM_MODE_SHIFT 4\n#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSP_RX_TERM_MODE_MASK (0x3 << \\\n    EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSP_RX_TERM_MODE_SHIFT)\n#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQ_RX_TERM_MODE_SHIFT   0\n#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQ_RX_TERM_MODE_MASK   (0x3 << \\\n    EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQ_RX_TERM_MODE_SHIFT)\n\n#define RX_TERM_MODE                            \\\n    ~(EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSN_RX_TERM_MODE_MASK |    \\\n      EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSP_RX_TERM_MODE_MASK |    \\\n      EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQ_RX_TERM_MODE_MASK)\n\n#define EMC_PMACRO_CMD_PAD_TX_CTRL              0xc60\n#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_DQ_TX_E_DCC      (1 << 1)\n#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_DQSP_TX_E_DCC        (1 << 9)\n#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_DQSN_TX_E_DCC        (1 << 16)\n#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_CMD_TX_E_DCC     (1 << 24)\n#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_DQ_TX_DRVFORCEON     (1 << 26)\n\n#define EMC_PMACRO_DATA_PAD_TX_CTRL             0xc64\n#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQ_E_IVREF     (1 << 0)\n#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQ_TX_E_DCC        (1 << 1)\n#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQS_E_IVREF        (1 << 8)\n#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQSP_TX_E_DCC      (1 << 9)\n#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQSN_TX_E_DCC      (1 << 16)\n#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_CMD_TX_E_DCC       (1 << 24)\n\n#define EMC_PMACRO_COMMON_PAD_TX_CTRL               0xc68\n#define EMC_PMACRO_BRICK_MAPPING_0              0xc80\n#define EMC_PMACRO_BRICK_MAPPING_1              0xc84\n#define EMC_PMACRO_BRICK_MAPPING_2              0xc88\n#define EMC_PMACRO_DDLLCAL_CAL                  0xce0\n#define EMC_PMACRO_DDLL_OFFSET                  0xce4\n#define EMC_PMACRO_DDLL_PERIODIC_OFFSET             0xce8\n#define EMC_PMACRO_BRICK_CTRL_RFU1              0x330\n#define EMC_PMACRO_BRICK_CTRL_RFU2              0x334\n#define EMC_PMACRO_CMD_BRICK_CTRL_FDPD              0x318\n#define EMC_PMACRO_DATA_BRICK_CTRL_FDPD             0x31c\n#define EMC_PMACRO_TRAINING_CTRL_0              0xcf8\n#define EMC_PMACRO_TRAINING_CTRL_0_CH0_TRAINING_E_WRPTR     (1 << 3)\n\n#define EMC_PMACRO_TRAINING_CTRL_1              0xcfc\n#define EMC_PMACRO_TRAINING_CTRL_1_CH1_TRAINING_E_WRPTR     (1 << 3)\n\n#define EMC_PMC_SCRATCH1                    0x440\n#define EMC_PMC_SCRATCH2                    0x444\n#define EMC_PMC_SCRATCH3                    0x448\n\n#endif"
  },
  {
    "path": "argon-first-stage/include/mem/heap.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 Guillem96\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _HEAP_H_\n#define _HEAP_H_\n\n#include \"utils/types.h\"\n\ntypedef struct _hnode\n{\n\tint used;\n\tu32 size;\n\tstruct _hnode *prev;\n\tstruct _hnode *next;\n} hnode_t;\n\ntypedef struct _heap\n{\n\tu32 start;\n\thnode_t *first;\n} heap_t;\n\nvoid heap_init(u32 base);\nvoid *malloc(u32 size);\nvoid *calloc(u32 num, u32 size);\nvoid free(void *buf);\nvoid *memalign(u32 align, u32 size);\nvoid *m_realloc(void* ptr, u32 current_size, u32 new_size);\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/mem/mc.h",
    "content": "#ifndef _MC_H_\n#define _MC_H_\n\n#include \"utils/types.h\"\n#include \"mem/mc_t210.h\"\n\n#define MAKE_MC_REG(n) MAKE_REG32(MC_BASE + n)\n\nvoid mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock);\nvoid mc_config_carveout();\nvoid mc_config_carveout_finalize();\nvoid mc_enable_ahb_redirect();\nvoid mc_disable_ahb_redirect();\nvoid mc_enable();\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/mem/mc_t210.h",
    "content": "/*\n * Copyright (c) 2014, NVIDIA Corporation. All rights reserved.\n *\n * This software is licensed under the terms of the GNU General Public\n * License version 2, as published by the Free Software Foundation, and\n * may be copied, distributed, and modified under those terms.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n */\n\n#ifndef _MC_T210_H_\n#define _MC_T210_H_\n\n#define MC_INTSTATUS                                            0x0\n#define MC_INTMASK                                              0x4\n#define MC_ERR_STATUS                                           0x8\n#define MC_ERR_ADR                                              0xc\n#define MC_PCFIFO_CLIENT_CONFIG0                                0xdd0\n#define MC_PCFIFO_CLIENT_CONFIG1                                0xdd4\n#define MC_PCFIFO_CLIENT_CONFIG2                                0xdd8\n#define MC_PCFIFO_CLIENT_CONFIG3                                0xddc\n#define MC_PCFIFO_CLIENT_CONFIG4                                0xde0\n#define MC_EMEM_CFG                                             0x50\n#define MC_EMEM_ADR_CFG                                         0x54\n#define MC_EMEM_ADR_CFG_DEV0                                    0x58\n#define MC_EMEM_ADR_CFG_DEV1                                    0x5c\n#define MC_EMEM_ADR_CFG_CHANNEL_MASK                            0x60\n#define MC_EMEM_ADR_CFG_BANK_MASK_0                             0x64\n#define MC_EMEM_ADR_CFG_BANK_MASK_1                             0x68\n#define MC_EMEM_ADR_CFG_BANK_MASK_2                             0x6c\n#define MC_SECURITY_CFG0                                        0x70\n#define MC_SECURITY_CFG1                                        0x74\n#define MC_SECURITY_CFG3                                        0x9bc\n#define MC_SECURITY_RSV                                         0x7c\n#define MC_EMEM_ARB_CFG                                         0x90\n#define MC_EMEM_ARB_OUTSTANDING_REQ                             0x94\n#define MC_EMEM_ARB_TIMING_RCD                                  0x98\n#define MC_EMEM_ARB_TIMING_RP                                   0x9c\n#define MC_EMEM_ARB_TIMING_RC                                   0xa0\n#define MC_EMEM_ARB_TIMING_RAS                                  0xa4\n#define MC_EMEM_ARB_TIMING_FAW                                  0xa8\n#define MC_EMEM_ARB_TIMING_RRD                                  0xac\n#define MC_EMEM_ARB_TIMING_RAP2PRE                              0xb0\n#define MC_EMEM_ARB_TIMING_WAP2PRE                              0xb4\n#define MC_EMEM_ARB_TIMING_R2R                                  0xb8\n#define MC_EMEM_ARB_TIMING_W2W                                  0xbc\n#define MC_EMEM_ARB_TIMING_R2W                                  0xc0\n#define MC_EMEM_ARB_TIMING_W2R                                  0xc4\n#define MC_EMEM_ARB_TIMING_RFCPB                                0x6c0\n#define MC_EMEM_ARB_TIMING_CCDMW                                0x6c4\n#define MC_EMEM_ARB_REFPB_HP_CTRL                               0x6f0\n#define MC_EMEM_ARB_REFPB_BANK_CTRL                             0x6f4\n#define MC_EMEM_ARB_DA_TURNS                                    0xd0\n#define MC_EMEM_ARB_DA_COVERS                                   0xd4\n#define MC_EMEM_ARB_MISC0                                       0xd8\n#define MC_EMEM_ARB_MISC1                                       0xdc\n#define MC_EMEM_ARB_MISC2                                       0xc8\n#define MC_EMEM_ARB_RING1_THROTTLE                              0xe0\n#define MC_EMEM_ARB_RING3_THROTTLE                              0xe4\n#define MC_EMEM_ARB_NISO_THROTTLE                               0x6b0\n#define MC_EMEM_ARB_OVERRIDE                                    0xe8\n#define MC_EMEM_ARB_RSV                                         0xec\n#define MC_CLKEN_OVERRIDE                                       0xf4\n#define MC_TIMING_CONTROL_DBG                                   0xf8\n#define MC_TIMING_CONTROL                                       0xfc\n#define MC_STAT_CONTROL                                         0x100\n#define MC_STAT_STATUS                                          0x104\n#define MC_STAT_EMC_CLOCK_LIMIT                                 0x108\n#define MC_STAT_EMC_CLOCK_LIMIT_MSBS                            0x10c\n#define MC_STAT_EMC_CLOCKS                                      0x110\n#define MC_STAT_EMC_CLOCKS_MSBS                                 0x114\n#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_LO                    0x118\n#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_LO                    0x158\n#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_HI                    0x11c\n#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_HI                    0x15c\n#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_UPPER                 0xa20\n#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_UPPER                 0xa24\n#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_LO            0x198\n#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_LO            0x1a8\n#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_HI            0x19c\n#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_HI            0x1ac\n#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_UPPER         0xa28\n#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_UPPER         0xa2c\n#define MC_STAT_EMC_FILTER_SET0_ASID                            0x1a0\n#define MC_STAT_EMC_FILTER_SET1_ASID                            0x1b0\n#define MC_STAT_EMC_FILTER_SET0_SLACK_LIMIT                     0x120\n#define MC_STAT_EMC_FILTER_SET1_SLACK_LIMIT                     0x160\n#define MC_STAT_EMC_FILTER_SET0_CLIENT_0                        0x128\n#define MC_STAT_EMC_FILTER_SET1_CLIENT_0                        0x168\n#define MC_STAT_EMC_FILTER_SET0_CLIENT_1                        0x12c\n#define MC_STAT_EMC_FILTER_SET1_CLIENT_1                        0x16c\n#define MC_STAT_EMC_FILTER_SET0_CLIENT_2                        0x130\n#define MC_STAT_EMC_FILTER_SET1_CLIENT_2                        0x170\n#define MC_STAT_EMC_FILTER_SET0_CLIENT_3                        0x134\n#define MC_STAT_EMC_FILTER_SET0_CLIENT_4                        0xb88\n#define MC_STAT_EMC_FILTER_SET1_CLIENT_3                        0x174\n#define MC_STAT_EMC_FILTER_SET1_CLIENT_4                        0xb8c\n#define MC_STAT_EMC_SET0_COUNT                                  0x138\n#define MC_STAT_EMC_SET0_COUNT_MSBS                             0x13c\n#define MC_STAT_EMC_SET1_COUNT                                  0x178\n#define MC_STAT_EMC_SET1_COUNT_MSBS                             0x17c\n#define MC_STAT_EMC_SET0_SLACK_ACCUM                            0x140\n#define MC_STAT_EMC_SET0_SLACK_ACCUM_MSBS                       0x144\n#define MC_STAT_EMC_SET1_SLACK_ACCUM                            0x180\n#define MC_STAT_EMC_SET1_SLACK_ACCUM_MSBS                       0x184\n#define MC_STAT_EMC_SET0_HISTO_COUNT                            0x148\n#define MC_STAT_EMC_SET0_HISTO_COUNT_MSBS                       0x14c\n#define MC_STAT_EMC_SET1_HISTO_COUNT                            0x188\n#define MC_STAT_EMC_SET1_HISTO_COUNT_MSBS                       0x18c\n#define MC_STAT_EMC_SET0_MINIMUM_SLACK_OBSERVED                 0x150\n#define MC_STAT_EMC_SET1_MINIMUM_SLACK_OBSERVED                 0x190\n#define MC_STAT_EMC_SET0_IDLE_CYCLE_COUNT                       0x1b8\n#define MC_STAT_EMC_SET0_IDLE_CYCL_COUNT_MSBS                   0x1bc\n#define MC_STAT_EMC_SET1_IDLE_CYCLE_COUNT                       0x1c8\n#define MC_STAT_EMC_SET1_IDLE_CYCL_COUNT_MSBS                   0x1cc\n#define MC_STAT_EMC_SET0_IDLE_CYCLE_PARTITION_SELECT            0x1c0\n#define MC_STAT_EMC_SET1_IDLE_CYCLE_PARTITION_SELECT            0x1d0\n#define MC_CLIENT_HOTRESET_CTRL                                 0x200\n#define MC_CLIENT_HOTRESET_CTRL_1                               0x970\n#define MC_CLIENT_HOTRESET_STATUS                               0x204\n#define MC_CLIENT_HOTRESET_STATUS_1                             0x974\n#define MC_EMEM_ARB_ISOCHRONOUS_0                               0x208\n#define MC_EMEM_ARB_ISOCHRONOUS_1                               0x20c\n#define MC_EMEM_ARB_ISOCHRONOUS_2                               0x210\n#define MC_EMEM_ARB_ISOCHRONOUS_3                               0x214\n#define MC_EMEM_ARB_ISOCHRONOUS_4                               0xb94\n#define MC_EMEM_ARB_HYSTERESIS_0                                0x218\n#define MC_EMEM_ARB_HYSTERESIS_1                                0x21c\n#define MC_EMEM_ARB_HYSTERESIS_2                                0x220\n#define MC_EMEM_ARB_HYSTERESIS_3                                0x224\n#define MC_EMEM_ARB_HYSTERESIS_4                                0xb84\n#define MC_EMEM_ARB_DHYSTERESIS_0                               0xbb0\n#define MC_EMEM_ARB_DHYSTERESIS_1                               0xbb4\n#define MC_EMEM_ARB_DHYSTERESIS_2                               0xbb8\n#define MC_EMEM_ARB_DHYSTERESIS_3                               0xbbc\n#define MC_EMEM_ARB_DHYSTERESIS_4                               0xbc0\n#define MC_EMEM_ARB_DHYST_CTRL                                  0xbcc\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0                        0xbd0\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1                        0xbd4\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2                        0xbd8\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3                        0xbdc\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4                        0xbe0\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5                        0xbe4\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6                        0xbe8\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7                        0xbec\n#define MC_RESERVED_RSV                                         0x3fc\n#define MC_DISB_EXTRA_SNAP_LEVELS                               0x408\n#define MC_APB_EXTRA_SNAP_LEVELS                                0x2a4\n#define MC_AHB_EXTRA_SNAP_LEVELS                                0x2a0\n#define MC_USBD_EXTRA_SNAP_LEVELS                               0xa18\n#define MC_ISP_EXTRA_SNAP_LEVELS                                0xa08\n#define MC_AUD_EXTRA_SNAP_LEVELS                                0xa10\n#define MC_MSE_EXTRA_SNAP_LEVELS                                0x40c\n#define MC_GK2_EXTRA_SNAP_LEVELS                                0xa40\n#define MC_A9AVPPC_EXTRA_SNAP_LEVELS                            0x414\n#define MC_FTOP_EXTRA_SNAP_LEVELS                               0x2bc\n#define MC_JPG_EXTRA_SNAP_LEVELS                                0xa3c\n#define MC_HOST_EXTRA_SNAP_LEVELS                               0xa14\n#define MC_SAX_EXTRA_SNAP_LEVELS                                0x2c0\n#define MC_DIS_EXTRA_SNAP_LEVELS                                0x2ac\n#define MC_VICPC_EXTRA_SNAP_LEVELS                              0xa1c\n#define MC_HDAPC_EXTRA_SNAP_LEVELS                              0xa48\n#define MC_AVP_EXTRA_SNAP_LEVELS                                0x2a8\n#define MC_USBX_EXTRA_SNAP_LEVELS                               0x404\n#define MC_PCX_EXTRA_SNAP_LEVELS                                0x2b8\n#define MC_SD_EXTRA_SNAP_LEVELS                                 0xa04\n#define MC_DFD_EXTRA_SNAP_LEVELS                                0xa4c\n#define MC_VE_EXTRA_SNAP_LEVELS                                 0x2d8\n#define MC_GK_EXTRA_SNAP_LEVELS                                 0xa00\n#define MC_VE2_EXTRA_SNAP_LEVELS                                0x410\n#define MC_SDM_EXTRA_SNAP_LEVELS                                0xa44\n#define MC_VIDEO_PROTECT_BOM                                    0x648\n#define MC_VIDEO_PROTECT_SIZE_MB                                0x64c\n#define MC_VIDEO_PROTECT_BOM_ADR_HI                             0x978\n#define MC_VIDEO_PROTECT_REG_CTRL                               0x650\n#define MC_ERR_VPR_STATUS                                       0x654\n#define MC_ERR_VPR_ADR                                          0x658\n#define MC_VIDEO_PROTECT_VPR_OVERRIDE                           0x418\n#define MC_VIDEO_PROTECT_VPR_OVERRIDE1                          0x590\n#define MC_IRAM_BOM                                             0x65c\n#define MC_IRAM_TOM                                             0x660\n#define MC_IRAM_ADR_HI                                          0x980\n#define MC_IRAM_REG_CTRL                                        0x964\n#define MC_EMEM_CFG_ACCESS_CTRL                                 0x664\n#define MC_TZ_SECURITY_CTRL                                     0x668\n#define MC_EMEM_ARB_OUTSTANDING_REQ_RING3                       0x66c\n#define MC_EMEM_ARB_OUTSTANDING_REQ_NISO                        0x6b4\n#define MC_EMEM_ARB_RING0_THROTTLE_MASK                         0x6bc\n#define MC_EMEM_ARB_NISO_THROTTLE_MASK                          0x6b8\n#define MC_EMEM_ARB_NISO_THROTTLE_MASK_1                        0xb80\n#define MC_SEC_CARVEOUT_BOM                                     0x670\n#define MC_SEC_CARVEOUT_SIZE_MB                                 0x674\n#define MC_SEC_CARVEOUT_ADR_HI                                  0x9d4\n#define MC_SEC_CARVEOUT_REG_CTRL                                0x678\n#define MC_ERR_SEC_STATUS                                       0x67c\n#define MC_ERR_SEC_ADR                                          0x680\n#define MC_PC_IDLE_CLOCK_GATE_CONFIG                            0x684\n#define MC_STUTTER_CONTROL                                      0x688\n#define MC_RESERVED_RSV_1                                       0x958\n#define MC_DVFS_PIPE_SELECT                                     0x95c\n#define MC_AHB_PTSA_MIN                                         0x4e0\n#define MC_AUD_PTSA_MIN                                         0x54c\n#define MC_MLL_MPCORER_PTSA_RATE                                0x44c\n#define MC_RING2_PTSA_RATE                                      0x440\n#define MC_USBD_PTSA_RATE                                       0x530\n#define MC_USBX_PTSA_MIN                                        0x528\n#define MC_USBD_PTSA_MIN                                        0x534\n#define MC_APB_PTSA_MAX                                         0x4f0\n#define MC_JPG_PTSA_RATE                                        0x584\n#define MC_DIS_PTSA_MIN                                         0x420\n#define MC_AVP_PTSA_MAX                                         0x4fc\n#define MC_AVP_PTSA_RATE                                        0x4f4\n#define MC_RING1_PTSA_MIN                                       0x480\n#define MC_DIS_PTSA_MAX                                         0x424\n#define MC_SD_PTSA_MAX                                          0x4d8\n#define MC_MSE_PTSA_RATE                                        0x4c4\n#define MC_VICPC_PTSA_MIN                                       0x558\n#define MC_PCX_PTSA_MAX                                         0x4b4\n#define MC_ISP_PTSA_RATE                                        0x4a0\n#define MC_A9AVPPC_PTSA_MIN                                     0x48c\n#define MC_RING2_PTSA_MAX                                       0x448\n#define MC_AUD_PTSA_RATE                                        0x548\n#define MC_HOST_PTSA_MIN                                        0x51c\n#define MC_MLL_MPCORER_PTSA_MAX                                 0x454\n#define MC_SD_PTSA_MIN                                          0x4d4\n#define MC_RING1_PTSA_RATE                                      0x47c\n#define MC_JPG_PTSA_MIN                                         0x588\n#define MC_HDAPC_PTSA_MIN                                       0x62c\n#define MC_AVP_PTSA_MIN                                         0x4f8\n#define MC_JPG_PTSA_MAX                                         0x58c\n#define MC_VE_PTSA_MAX                                          0x43c\n#define MC_DFD_PTSA_MAX                                         0x63c\n#define MC_VICPC_PTSA_RATE                                      0x554\n#define MC_GK_PTSA_MAX                                          0x544\n#define MC_VICPC_PTSA_MAX                                       0x55c\n#define MC_SDM_PTSA_MAX                                         0x624\n#define MC_SAX_PTSA_RATE                                        0x4b8\n#define MC_PCX_PTSA_MIN                                         0x4b0\n#define MC_APB_PTSA_MIN                                         0x4ec\n#define MC_GK2_PTSA_MIN                                         0x614\n#define MC_PCX_PTSA_RATE                                        0x4ac\n#define MC_RING1_PTSA_MAX                                       0x484\n#define MC_HDAPC_PTSA_RATE                                      0x628\n#define MC_MLL_MPCORER_PTSA_MIN                                 0x450\n#define MC_GK2_PTSA_MAX                                         0x618\n#define MC_AUD_PTSA_MAX                                         0x550\n#define MC_GK2_PTSA_RATE                                        0x610\n#define MC_ISP_PTSA_MAX                                         0x4a8\n#define MC_DISB_PTSA_RATE                                       0x428\n#define MC_VE2_PTSA_MAX                                         0x49c\n#define MC_DFD_PTSA_MIN                                         0x638\n#define MC_FTOP_PTSA_RATE                                       0x50c\n#define MC_A9AVPPC_PTSA_RATE                                    0x488\n#define MC_VE2_PTSA_MIN                                         0x498\n#define MC_USBX_PTSA_MAX                                        0x52c\n#define MC_DIS_PTSA_RATE                                        0x41c\n#define MC_USBD_PTSA_MAX                                        0x538\n#define MC_A9AVPPC_PTSA_MAX                                     0x490\n#define MC_USBX_PTSA_RATE                                       0x524\n#define MC_FTOP_PTSA_MAX                                        0x514\n#define MC_HDAPC_PTSA_MAX                                       0x630\n#define MC_SD_PTSA_RATE                                         0x4d0\n#define MC_DFD_PTSA_RATE                                        0x634\n#define MC_FTOP_PTSA_MIN                                        0x510\n#define MC_SDM_PTSA_RATE                                        0x61c\n#define MC_AHB_PTSA_RATE                                        0x4dc\n#define MC_SMMU_SMMU_PTSA_MAX                                   0x460\n#define MC_RING2_PTSA_MIN                                       0x444\n#define MC_SDM_PTSA_MIN                                         0x620\n#define MC_APB_PTSA_RATE                                        0x4e8\n#define MC_MSE_PTSA_MIN                                         0x4c8\n#define MC_HOST_PTSA_RATE                                       0x518\n#define MC_VE_PTSA_RATE                                         0x434\n#define MC_AHB_PTSA_MAX                                         0x4e4\n#define MC_SAX_PTSA_MIN                                         0x4bc\n#define MC_SMMU_SMMU_PTSA_MIN                                   0x45c\n#define MC_ISP_PTSA_MIN                                         0x4a4\n#define MC_HOST_PTSA_MAX                                        0x520\n#define MC_SAX_PTSA_MAX                                         0x4c0\n#define MC_VE_PTSA_MIN                                          0x438\n#define MC_GK_PTSA_MIN                                          0x540\n#define MC_MSE_PTSA_MAX                                         0x4cc\n#define MC_DISB_PTSA_MAX                                        0x430\n#define MC_DISB_PTSA_MIN                                        0x42c\n#define MC_SMMU_SMMU_PTSA_RATE                                  0x458\n#define MC_VE2_PTSA_RATE                                        0x494\n#define MC_GK_PTSA_RATE                                         0x53c\n#define MC_PTSA_GRANT_DECREMENT                                 0x960\n#define MC_LATENCY_ALLOWANCE_AVPC_0                             0x2e4\n#define MC_LATENCY_ALLOWANCE_AXIAP_0                            0x3a0\n#define MC_LATENCY_ALLOWANCE_XUSB_1                             0x380\n#define MC_LATENCY_ALLOWANCE_ISP2B_0                            0x384\n#define MC_LATENCY_ALLOWANCE_SDMMCAA_0                          0x3bc\n#define MC_LATENCY_ALLOWANCE_SDMMCA_0                           0x3b8\n#define MC_LATENCY_ALLOWANCE_ISP2_0                             0x370\n#define MC_LATENCY_ALLOWANCE_SE_0                               0x3e0\n#define MC_LATENCY_ALLOWANCE_ISP2_1                             0x374\n#define MC_LATENCY_ALLOWANCE_DC_0                               0x2e8\n#define MC_LATENCY_ALLOWANCE_VIC_0                              0x394\n#define MC_LATENCY_ALLOWANCE_DCB_1                              0x2f8\n#define MC_LATENCY_ALLOWANCE_NVDEC_0                            0x3d8\n#define MC_LATENCY_ALLOWANCE_DCB_2                              0x2fc\n#define MC_LATENCY_ALLOWANCE_TSEC_0                             0x390\n#define MC_LATENCY_ALLOWANCE_DC_2                               0x2f0\n#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0AB                  0x694\n#define MC_LATENCY_ALLOWANCE_PPCS_1                             0x348\n#define MC_LATENCY_ALLOWANCE_XUSB_0                             0x37c\n#define MC_LATENCY_ALLOWANCE_PPCS_0                             0x344\n#define MC_LATENCY_ALLOWANCE_TSECB_0                            0x3f0\n#define MC_LATENCY_ALLOWANCE_AFI_0                              0x2e0\n#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0B                   0x698\n#define MC_LATENCY_ALLOWANCE_DC_1                               0x2ec\n#define MC_LATENCY_ALLOWANCE_APE_0                              0x3dc\n#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0C                   0x6a0\n#define MC_LATENCY_ALLOWANCE_A9AVP_0                            0x3a4\n#define MC_LATENCY_ALLOWANCE_GPU2_0                             0x3e8\n#define MC_LATENCY_ALLOWANCE_DCB_0                              0x2f4\n#define MC_LATENCY_ALLOWANCE_HC_1                               0x314\n#define MC_LATENCY_ALLOWANCE_SDMMC_0                            0x3c0\n#define MC_LATENCY_ALLOWANCE_NVJPG_0                            0x3e4\n#define MC_LATENCY_ALLOWANCE_PTC_0                              0x34c\n#define MC_LATENCY_ALLOWANCE_ETR_0                              0x3ec\n#define MC_LATENCY_ALLOWANCE_MPCORE_0                           0x320\n#define MC_LATENCY_ALLOWANCE_VI2_0                              0x398\n#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0BB                  0x69c\n#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0CB                  0x6a4\n#define MC_LATENCY_ALLOWANCE_SATA_0                             0x350\n#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0A                   0x690\n#define MC_LATENCY_ALLOWANCE_HC_0                               0x310\n#define MC_LATENCY_ALLOWANCE_DC_3                               0x3c8\n#define MC_LATENCY_ALLOWANCE_GPU_0                              0x3ac\n#define MC_LATENCY_ALLOWANCE_SDMMCAB_0                          0x3c4\n#define MC_LATENCY_ALLOWANCE_ISP2B_1                            0x388\n#define MC_LATENCY_ALLOWANCE_NVENC_0                            0x328\n#define MC_LATENCY_ALLOWANCE_HDA_0                              0x318\n#define MC_MIN_LENGTH_APE_0                                     0xb34\n#define MC_MIN_LENGTH_DCB_2                                     0x8a8\n#define MC_MIN_LENGTH_A9AVP_0                                   0x950\n#define MC_MIN_LENGTH_TSEC_0                                    0x93c\n#define MC_MIN_LENGTH_DC_1                                      0x898\n#define MC_MIN_LENGTH_AXIAP_0                                   0x94c\n#define MC_MIN_LENGTH_ISP2B_0                                   0x930\n#define MC_MIN_LENGTH_VI2_0                                     0x944\n#define MC_MIN_LENGTH_DCB_0                                     0x8a0\n#define MC_MIN_LENGTH_DCB_1                                     0x8a4\n#define MC_MIN_LENGTH_PPCS_1                                    0x8f4\n#define MC_MIN_LENGTH_NVJPG_0                                   0xb3c\n#define MC_MIN_LENGTH_HDA_0                                     0x8c4\n#define MC_MIN_LENGTH_NVENC_0                                   0x8d4\n#define MC_MIN_LENGTH_SDMMC_0                                   0xb18\n#define MC_MIN_LENGTH_ISP2B_1                                   0x934\n#define MC_MIN_LENGTH_HC_1                                      0x8c0\n#define MC_MIN_LENGTH_DC_3                                      0xb20\n#define MC_MIN_LENGTH_AVPC_0                                    0x890\n#define MC_MIN_LENGTH_VIC_0                                     0x940\n#define MC_MIN_LENGTH_ISP2_0                                    0x91c\n#define MC_MIN_LENGTH_HC_0                                      0x8bc\n#define MC_MIN_LENGTH_SE_0                                      0xb38\n#define MC_MIN_LENGTH_NVDEC_0                                   0xb30\n#define MC_MIN_LENGTH_SATA_0                                    0x8fc\n#define MC_MIN_LENGTH_DC_0                                      0x894\n#define MC_MIN_LENGTH_XUSB_1                                    0x92c\n#define MC_MIN_LENGTH_DC_2                                      0x89c\n#define MC_MIN_LENGTH_SDMMCAA_0                                 0xb14\n#define MC_MIN_LENGTH_GPU_0                                     0xb04\n#define MC_MIN_LENGTH_ETR_0                                     0xb44\n#define MC_MIN_LENGTH_AFI_0                                     0x88c\n#define MC_MIN_LENGTH_PPCS_0                                    0x8f0\n#define MC_MIN_LENGTH_ISP2_1                                    0x920\n#define MC_MIN_LENGTH_XUSB_0                                    0x928\n#define MC_MIN_LENGTH_MPCORE_0                                  0x8cc\n#define MC_MIN_LENGTH_TSECB_0                                   0xb48\n#define MC_MIN_LENGTH_SDMMCA_0                                  0xb10\n#define MC_MIN_LENGTH_GPU2_0                                    0xb40\n#define MC_MIN_LENGTH_SDMMCAB_0                                 0xb1c\n#define MC_MIN_LENGTH_PTC_0                                     0x8f8\n#define MC_EMEM_ARB_OVERRIDE_1                                  0x968\n#define MC_VIDEO_PROTECT_GPU_OVERRIDE_0                         0x984\n#define MC_VIDEO_PROTECT_GPU_OVERRIDE_1                         0x988\n#define MC_EMEM_ARB_STATS_0                                     0x990\n#define MC_EMEM_ARB_STATS_1                                     0x994\n#define MC_MTS_CARVEOUT_BOM                                     0x9a0\n#define MC_MTS_CARVEOUT_SIZE_MB                                 0x9a4\n#define MC_MTS_CARVEOUT_ADR_HI                                  0x9a8\n#define MC_MTS_CARVEOUT_REG_CTRL                                0x9ac\n#define MC_ERR_MTS_STATUS                                       0x9b0\n#define MC_ERR_MTS_ADR                                          0x9b4\n#define MC_ERR_GENERALIZED_CARVEOUT_STATUS                      0xc00\n#define MC_ERR_GENERALIZED_CARVEOUT_ADR                         0xc04\n#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2     0xd74\n#define MC_SECURITY_CARVEOUT4_CFG0                              0xcf8\n#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2                    0xd10\n#define MC_SECURITY_CARVEOUT4_SIZE_128KB                        0xd04\n#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4                    0xc28\n#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1     0xc30\n#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4     0xc8c\n#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0     0xd1c\n#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1     0xd70\n#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0     0xc2c\n#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4     0xd7c\n#define MC_SECURITY_CARVEOUT3_SIZE_128KB                        0xcb4\n#define MC_SECURITY_CARVEOUT2_CFG0                              0xc58\n#define MC_SECURITY_CARVEOUT1_CFG0                              0xc08\n#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2     0xc84\n#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0                    0xc68\n#define MC_SECURITY_CARVEOUT3_BOM                               0xcac\n#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2                    0xc70\n#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3     0xd78\n#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0     0xc7c\n#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4                    0xd18\n#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1                    0xcbc\n#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3     0xc38\n#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2     0xc34\n#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2                    0xcc0\n#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2                    0xd60\n#define MC_SECURITY_CARVEOUT3_CFG0                              0xca8\n#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0                    0xcb8\n#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3     0xc88\n#define MC_SECURITY_CARVEOUT2_SIZE_128KB                        0xc64\n#define MC_SECURITY_CARVEOUT5_BOM_HI                            0xd50\n#define MC_SECURITY_CARVEOUT1_SIZE_128KB                        0xc14\n#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3                    0xd14\n#define MC_SECURITY_CARVEOUT1_BOM                               0xc0c\n#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4     0xd2c\n#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4                    0xd68\n#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4                    0xcc8\n#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0                    0xd58\n#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2     0xd24\n#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3                    0xcc4\n#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4                    0xc78\n#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1                    0xc1c\n#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0                    0xc18\n#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3     0xd28\n#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1                    0xd5c\n#define MC_SECURITY_CARVEOUT3_BOM_HI                            0xcb0\n#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3     0xcd8\n#define MC_SECURITY_CARVEOUT2_BOM_HI                            0xc60\n#define MC_SECURITY_CARVEOUT4_BOM_HI                            0xd00\n#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3                    0xd64\n#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4     0xcdc\n#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1     0xc80\n#define MC_SECURITY_CARVEOUT5_SIZE_128KB                        0xd54\n#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1     0xd20\n#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2     0xcd4\n#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1                    0xd0c\n#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3                    0xc74\n#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0     0xccc\n#define MC_SECURITY_CARVEOUT4_BOM                               0xcfc\n#define MC_SECURITY_CARVEOUT5_CFG0                              0xd48\n#define MC_SECURITY_CARVEOUT2_BOM                               0xc5c\n#define MC_SECURITY_CARVEOUT5_BOM                               0xd4c\n#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3                    0xc24\n#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0     0xd6c\n#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1     0xcd0\n#define MC_SECURITY_CARVEOUT1_BOM_HI                            0xc10\n#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2                    0xc20\n#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4     0xc3c\n#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1                    0xc6c\n#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0                    0xd08\n#define MC_ERR_APB_ASID_UPDATE_STATUS                           0x9d0\n#define MC_DA_CONFIG0                                           0x9dc\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/mem/sdram.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _SDRAM_H_\n#define _SDRAM_H_\n\nvoid sdram_init();\nconst void *sdram_get_params();\nu32 get_sdram_id();\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/mem/sdram_config_lz.inl",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 balika011\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\nstatic const u8 _dram_cfg_lz[1270] = {\n\t0x17, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00,\n\t0x00, 0x2C, 0x17, 0x04, 0x09, 0x00, 0x17, 0x04, 0x04, 0x17, 0x08, 0x08,\n\t0x17, 0x10, 0x10, 0x00, 0x00, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00,\n\t0x00, 0x04, 0xB4, 0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00,\n\t0x70, 0x17, 0x10, 0x24, 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40,\n\t0x00, 0x00, 0x00, 0x17, 0x04, 0x04, 0x17, 0x09, 0x18, 0xFF, 0xFF, 0x1F,\n\t0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77,\n\t0x00, 0x17, 0x04, 0x04, 0x17, 0x08, 0x08, 0x17, 0x08, 0x08, 0xA6, 0xA6,\n\t0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x04,\n\t0x04, 0x04, 0x17, 0x04, 0x04, 0x17, 0x04, 0x3C, 0x1F, 0x1F, 0x1F, 0x1F,\n\t0x17, 0x04, 0x04, 0x17, 0x06, 0x06, 0x00, 0x00, 0x04, 0x08, 0x17, 0x06,\n\t0x46, 0xA1, 0x01, 0x00, 0x00, 0x32, 0x17, 0x0B, 0x64, 0x01, 0x17, 0x04,\n\t0x7C, 0x17, 0x07, 0x0C, 0x03, 0x17, 0x04, 0x04, 0x00, 0x00, 0x00, 0x1E,\n\t0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13,\n\t0x17, 0x0B, 0x2C, 0x09, 0x00, 0x00, 0x00, 0x17, 0x05, 0x5D, 0x17, 0x07,\n\t0x10, 0x0B, 0x17, 0x07, 0x28, 0x08, 0x17, 0x07, 0x0C, 0x17, 0x04, 0x1C,\n\t0x20, 0x00, 0x00, 0x00, 0x06, 0x17, 0x04, 0x04, 0x17, 0x07, 0x08, 0x17,\n\t0x04, 0x50, 0x17, 0x04, 0x2C, 0x17, 0x04, 0x1C, 0x17, 0x04, 0x10, 0x17,\n\t0x08, 0x6C, 0x17, 0x04, 0x10, 0x17, 0x04, 0x38, 0x17, 0x04, 0x40, 0x05,\n\t0x17, 0x07, 0x1C, 0x17, 0x08, 0x58, 0x17, 0x04, 0x24, 0x17, 0x04, 0x18,\n\t0x17, 0x08, 0x64, 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14,\n\t0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x17, 0x09, 0x0C, 0x17, 0x05, 0x82,\n\t0x58, 0x17, 0x07, 0x61, 0xC1, 0x17, 0x07, 0x50, 0x17, 0x04, 0x04, 0x17,\n\t0x08, 0x81, 0x48, 0x17, 0x04, 0x04, 0x17, 0x04, 0x28, 0x17, 0x04, 0x60,\n\t0x17, 0x08, 0x54, 0x27, 0x17, 0x04, 0x04, 0x17, 0x07, 0x14, 0x17, 0x04,\n\t0x04, 0x04, 0x17, 0x07, 0x81, 0x58, 0x17, 0x0C, 0x0C, 0x1C, 0x03, 0x00,\n\t0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x17, 0x04, 0x5A, 0xF3, 0x0C,\n\t0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05,\n\t0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03,\n\t0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02,\n\t0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08,\n\t0x24, 0x06, 0x07, 0x9A, 0x12, 0x17, 0x05, 0x83, 0x41, 0x00, 0xFF, 0x17,\n\t0x10, 0x83, 0x6C, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00,\n\t0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00,\n\t0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x17, 0x04, 0x20, 0x08, 0x08,\n\t0x0D, 0x0C, 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x17, 0x06,\n\t0x2C, 0x11, 0x08, 0x17, 0x10, 0x84, 0x67, 0x15, 0x00, 0xCC, 0x00, 0x0A,\n\t0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00, 0xFF,\n\t0x0F, 0xFF, 0x0F, 0x17, 0x08, 0x83, 0x4C, 0x01, 0x03, 0x00, 0x70, 0x00,\n\t0x0C, 0x00, 0x01, 0x17, 0x04, 0x0C, 0x08, 0x44, 0x00, 0x10, 0x04, 0x04,\n\t0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x17, 0x04, 0x10, 0xA0, 0x00, 0x2C,\n\t0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x17, 0x06, 0x48, 0x08, 0x00,\n\t0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28,\n\t0x28, 0x28, 0x17, 0x04, 0x04, 0x11, 0x11, 0x11, 0x11, 0x17, 0x04, 0x04,\n\t0xBE, 0x00, 0x00, 0x17, 0x05, 0x58, 0x17, 0x08, 0x5C, 0x17, 0x22, 0x85,\n\t0x6A, 0x17, 0x1A, 0x1A, 0x14, 0x00, 0x12, 0x00, 0x10, 0x17, 0x05, 0x83,\n\t0x0A, 0x17, 0x16, 0x18, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x17, 0x05, 0x83, 0x0C, 0x17,\n\t0x04, 0x20, 0x17, 0x18, 0x18, 0x28, 0x00, 0x28, 0x17, 0x04, 0x04, 0x17,\n\t0x08, 0x08, 0x17, 0x10, 0x10, 0x00, 0x14, 0x17, 0x05, 0x5A, 0x17, 0x04,\n\t0x5C, 0x17, 0x04, 0x5E, 0x17, 0x04, 0x0E, 0x17, 0x0E, 0x78, 0x17, 0x09,\n\t0x82, 0x50, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51,\n\t0x17, 0x08, 0x18, 0x80, 0x01, 0x00, 0x00, 0x40, 0x17, 0x04, 0x20, 0x03,\n\t0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x17, 0x08, 0x82, 0x58,\n\t0x17, 0x0C, 0x38, 0x17, 0x1B, 0x81, 0x6C, 0x17, 0x08, 0x85, 0x60, 0x17,\n\t0x08, 0x86, 0x50, 0x17, 0x08, 0x86, 0x60, 0x17, 0x06, 0x83, 0x21, 0x22,\n\t0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x17, 0x0C, 0x86, 0x74, 0x17, 0x08, 0x2C,\n\t0x8B, 0xFF, 0x07, 0x17, 0x06, 0x81, 0x04, 0x32, 0x54, 0x76, 0x10, 0x47,\n\t0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75,\n\t0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45,\n\t0x32, 0x67, 0x17, 0x04, 0x24, 0x49, 0x92, 0x24, 0x17, 0x04, 0x04, 0x17,\n\t0x11, 0x7C, 0x1B, 0x17, 0x04, 0x04, 0x17, 0x13, 0x81, 0x14, 0x2F, 0x41,\n\t0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x17, 0x04, 0x7C, 0xFF, 0xFF, 0xFF,\n\t0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03,\n\t0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x17, 0x06, 0x86, 0x59,\n\t0x17, 0x0F, 0x89, 0x14, 0x37, 0x17, 0x07, 0x82, 0x72, 0x10, 0x17, 0x06,\n\t0x83, 0x0D, 0x00, 0x11, 0x01, 0x17, 0x05, 0x85, 0x39, 0x17, 0x04, 0x0E,\n\t0x0A, 0x17, 0x07, 0x89, 0x29, 0x17, 0x04, 0x1B, 0x17, 0x08, 0x86, 0x77,\n\t0x17, 0x09, 0x12, 0x20, 0x00, 0x00, 0x00, 0x81, 0x10, 0x09, 0x28, 0x93,\n\t0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x17, 0x18, 0x82, 0x2C, 0xFF,\n\t0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0x17, 0x04, 0x04, 0xDC, 0xDC,\n\t0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x17, 0x04, 0x04, 0x17, 0x04, 0x04,\n\t0x17, 0x05, 0x82, 0x24, 0x03, 0x07, 0x17, 0x04, 0x04, 0x00, 0x00, 0x24,\n\t0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10,\n\t0x9C, 0x4B, 0x17, 0x04, 0x64, 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00,\n\t0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x17, 0x06, 0x85, 0x60, 0x17,\n\t0x10, 0x82, 0x74, 0x17, 0x08, 0x08, 0x17, 0x08, 0x88, 0x00, 0x17, 0x04,\n\t0x10, 0x04, 0x17, 0x0B, 0x87, 0x6C, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02,\n\t0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x17, 0x08, 0x8B, 0x18,\n\t0x1F, 0x17, 0x09, 0x81, 0x73, 0x00, 0xFF, 0x00, 0xFF, 0x17, 0x05, 0x86,\n\t0x48, 0x17, 0x04, 0x0C, 0x17, 0x07, 0x86, 0x34, 0x00, 0x00, 0xF0, 0x17,\n\t0x09, 0x87, 0x54, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x17, 0x0C, 0x81,\n\t0x52, 0x17, 0x0A, 0x1C, 0x17, 0x10, 0x81, 0x6C, 0x17, 0x0A, 0x82, 0x21,\n\t0x17, 0x07, 0x82, 0x4D, 0x17, 0x0A, 0x8A, 0x1B, 0x17, 0x11, 0x2C, 0x76,\n\t0x0C, 0x17, 0x0A, 0x8A, 0x67, 0x17, 0x0F, 0x84, 0x28, 0x17, 0x06, 0x34,\n\t0x17, 0x17, 0x3A, 0x7E, 0x16, 0x40, 0x17, 0x0C, 0x8B, 0x1F, 0x17, 0x2A,\n\t0x38, 0x1E, 0x17, 0x0A, 0x38, 0x17, 0x13, 0x81, 0x28, 0x00, 0xC0, 0x17,\n\t0x17, 0x55, 0x46, 0x24, 0x17, 0x0A, 0x81, 0x28, 0x17, 0x14, 0x38, 0x17,\n\t0x18, 0x81, 0x60, 0x46, 0x2C, 0x17, 0x06, 0x38, 0xEC, 0x00, 0x00, 0x00,\n\t0x01, 0x77, 0x00, 0xFC, 0x00, 0x20, 0xCF, 0x22, 0x17, 0x10, 0x82, 0x3C,\n\t0x17, 0x82, 0x0C, 0x8E, 0x68, 0x17, 0x04, 0x24, 0x17, 0x5C, 0x8E, 0x68,\n\t0x17, 0x07, 0x82, 0x5F, 0x80, 0x17, 0x87, 0x01, 0x8E, 0x68, 0x02, 0x17,\n\t0x81, 0x4A, 0x8E, 0x68, 0x17, 0x0C, 0x87, 0x78, 0x17, 0x85, 0x28, 0x8E,\n\t0x68, 0x17, 0x8E, 0x68, 0x9D, 0x50, 0x17, 0x81, 0x24, 0x8E, 0x68, 0x17,\n\t0x04, 0x2C, 0x17, 0x28, 0x8E, 0x68, 0x17, 0x04, 0x30, 0x17, 0x85, 0x3C,\n\t0x8E, 0x68, 0x12, 0x17, 0x07, 0x85, 0x70, 0x17, 0x88, 0x74, 0x8E, 0x68,\n\t0x17, 0x87, 0x3E, 0x9D, 0x50, 0x0C, 0x17, 0x04, 0x04, 0x17, 0x12, 0x8E,\n\t0x68, 0x18, 0x17, 0x87, 0x12, 0xBB, 0x20, 0x17, 0x83, 0x04, 0x9D, 0x50,\n\t0x15, 0x17, 0x05, 0x8D, 0x76, 0x17, 0x0F, 0x8B, 0x49, 0x17, 0x0B, 0x18,\n\t0x32, 0x00, 0x2F, 0x00, 0x32, 0x00, 0x31, 0x00, 0x34, 0x00, 0x36, 0x00,\n\t0x2F, 0x00, 0x33, 0x17, 0x09, 0x84, 0x0C, 0x17, 0x18, 0x18, 0x17, 0x20,\n\t0x8E, 0x68, 0x15, 0x17, 0x07, 0x5A, 0x17, 0x06, 0x5E, 0x16, 0x00, 0x15,\n\t0x17, 0x82, 0x40, 0x9D, 0x50, 0x17, 0x86, 0x5F, 0xBB, 0x20, 0x3A, 0x00,\n\t0x00, 0x00, 0x1D, 0x17, 0x81, 0x4F, 0xAC, 0x38, 0x3B, 0x17, 0x04, 0x04,\n\t0x17, 0x86, 0x30, 0x8E, 0x68, 0x17, 0x81, 0x53, 0xAC, 0x38, 0x07, 0x17,\n\t0x0D, 0x8E, 0x68, 0xA3, 0x72, 0x17, 0x83, 0x10, 0x8E, 0x68\n};\n"
  },
  {
    "path": "argon-first-stage/include/mem/sdram_param_t210.h",
    "content": "/*\n * Copyright (c) 2015, NVIDIA CORPORATION.  All rights reserved.\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n *\n * See file CREDITS for list of people who contributed to this\n * project.\n */\n\n/**\n * Defines the SDRAM parameter structure.\n *\n * Note that PLLM is used by EMC.\n */\n\n#ifndef _SDRAM_PARAM_T210_H_\n#define _SDRAM_PARAM_T210_H_\n\n#define MEMORY_TYPE_NONE 0\n#define MEMORY_TYPE_DDR 0\n#define MEMORY_TYPE_LPDDR 0\n#define MEMORY_TYPE_DDR2 0\n#define MEMORY_TYPE_LPDDR2 1\n#define MEMORY_TYPE_DDR3 2\n#define MEMORY_TYPE_LPDDR4 3\n\n/**\n * Defines the SDRAM parameter structure\n */\ntypedef struct _sdram_params\n{\n\t/* Specifies the type of memory device */\n\tu32 memory_type;\n\n\t/* MC/EMC clock source configuration */\n\n\t/* Specifies the M value for PllM */\n\tu32 pllm_input_divider;\n\t/* Specifies the N value for PllM */\n\tu32 pllm_feedback_divider;\n\t/* Specifies the time to wait for PLLM to lock (in microseconds) */\n\tu32 pllm_stable_time;\n\t/* Specifies misc. control bits */\n\tu32 pllm_setup_control;\n\t/* Specifies the P value for PLLM */\n\tu32 pllm_post_divider;\n\t/* Specifies value for Charge Pump Gain Control */\n\tu32 pllm_kcp;\n\t/* Specifies VCO gain */\n\tu32 pllm_kvco;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare0;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare1;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare2;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare3;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare4;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare5;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare6;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare7;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare8;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare9;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare10;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare11;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare12;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare13;\n\n\t/* Defines EMC_2X_CLK_SRC, EMC_2X_CLK_DIVISOR, EMC_INVERT_DCD */\n\tu32 emc_clock_source;\n\tu32 emc_clock_source_dll;\n\n\t/* Defines possible override for PLLLM_MISC2 */\n\tu32 clk_rst_pllm_misc20_override;\n\t/* enables override for PLLLM_MISC2 */\n\tu32 clk_rst_pllm_misc20_override_enable;\n\t/* defines CLK_ENB_MC1 in register clk_rst_controller_clk_enb_w_clr */\n\tu32 clear_clock2_mc1;\n\n\t/* Auto-calibration of EMC pads */\n\n\t/* Specifies the value for EMC_AUTO_CAL_INTERVAL */\n\tu32 emc_auto_cal_interval;\n\t/*\n\t * Specifies the value for EMC_AUTO_CAL_CONFIG\n\t * Note: Trigger bits are set by the SDRAM code.\n\t */\n\tu32 emc_auto_cal_config;\n\n\t/* Specifies the value for EMC_AUTO_CAL_CONFIG2 */\n\tu32 emc_auto_cal_config2;\n\n\t/* Specifies the value for EMC_AUTO_CAL_CONFIG3 */\n\tu32 emc_auto_cal_config3;\n\n\tu32 emc_auto_cal_config4;\n\tu32 emc_auto_cal_config5;\n\tu32 emc_auto_cal_config6;\n\tu32 emc_auto_cal_config7;\n\tu32 emc_auto_cal_config8;\n\t/* Specifies the value for EMC_AUTO_CAL_VREF_SEL_0 */\n\tu32 emc_auto_cal_vref_sel0;\n\tu32 emc_auto_cal_vref_sel1;\n\n\t/* Specifies the value for EMC_AUTO_CAL_CHANNEL */\n\tu32 emc_auto_cal_channel;\n\n\t/* Specifies the value for EMC_PMACRO_AUTOCAL_CFG_0 */\n\tu32 emc_pmacro_auto_cal_cfg0;\n\tu32 emc_pmacro_auto_cal_cfg1;\n\tu32 emc_pmacro_auto_cal_cfg2;\n\n\tu32 emc_pmacro_rx_term;\n\tu32 emc_pmacro_dq_tx_drive;\n\tu32 emc_pmacro_ca_tx_drive;\n\tu32 emc_pmacro_cmd_tx_drive;\n\tu32 emc_pmacro_auto_cal_common;\n\tu32 emc_pmacro_zcrtl;\n\n\t/*\n\t * Specifies the time for the calibration\n\t * to stabilize (in microseconds)\n\t */\n\tu32 emc_auto_cal_wait;\n\n\tu32 emc_xm2_comp_pad_ctrl;\n\tu32 emc_xm2_comp_pad_ctrl2;\n\tu32 emc_xm2_comp_pad_ctrl3;\n\n\t/*\n\t * DRAM size information\n\t * Specifies the value for EMC_ADR_CFG\n\t */\n\tu32 emc_adr_cfg;\n\n\t/*\n\t * Specifies the time to wait after asserting pin\n\t * CKE (in microseconds)\n\t */\n\tu32 emc_pin_program_wait;\n\t/* Specifies the extra delay before/after pin RESET/CKE command */\n\tu32 emc_pin_extra_wait;\n\n\tu32 emc_pin_gpio_enable;\n\tu32 emc_pin_gpio;\n\n\t/*\n\t * Specifies the extra delay after the first writing\n\t * of EMC_TIMING_CONTROL\n\t */\n\tu32 emc_timing_control_wait;\n\n\t/* Timing parameters required for the SDRAM */\n\n\t/* Specifies the value for EMC_RC */\n\tu32 emc_rc;\n\t/* Specifies the value for EMC_RFC */\n\tu32 emc_rfc;\n\n\tu32 emc_rfc_pb;\n\tu32 emc_ref_ctrl2;\n\n\t/* Specifies the value for EMC_RFC_SLR */\n\tu32 emc_rfc_slr;\n\t/* Specifies the value for EMC_RAS */\n\tu32 emc_ras;\n\t/* Specifies the value for EMC_RP */\n\tu32 emc_rp;\n\t/* Specifies the value for EMC_R2R */\n\tu32 emc_r2r;\n\t/* Specifies the value for EMC_W2W */\n\tu32 emc_w2w;\n\t/* Specifies the value for EMC_R2W */\n\tu32 emc_r2w;\n\t/* Specifies the value for EMC_W2R */\n\tu32 emc_w2r;\n\t/* Specifies the value for EMC_R2P */\n\tu32 emc_r2p;\n\t/* Specifies the value for EMC_W2P */\n\tu32 emc_w2p;\n\t/* Specifies the value for EMC_RD_RCD */\n\n\tu32 emc_tppd;\n\tu32 emc_ccdmw;\n\n\tu32 emc_rd_rcd;\n\t/* Specifies the value for EMC_WR_RCD */\n\tu32 emc_wr_rcd;\n\t/* Specifies the value for EMC_RRD */\n\tu32 emc_rrd;\n\t/* Specifies the value for EMC_REXT */\n\tu32 emc_rext;\n\t/* Specifies the value for EMC_WEXT */\n\tu32 emc_wext;\n\t/* Specifies the value for EMC_WDV */\n\tu32 emc_wdv;\n\n\tu32 emc_wdv_chk;\n\tu32 emc_wsv;\n\tu32 emc_wev;\n\n\t/* Specifies the value for EMC_WDV_MASK */\n\tu32 emc_wdv_mask;\n\n\tu32 emc_ws_duration;\n\tu32 emc_we_duration;\n\n\t/* Specifies the value for EMC_QUSE */\n\tu32 emc_quse;\n\t/* Specifies the value for EMC_QUSE_WIDTH */\n\tu32 emc_quse_width;\n\t/* Specifies the value for EMC_IBDLY */\n\tu32 emc_ibdly;\n\n\tu32 emc_obdly;\n\n\t/* Specifies the value for EMC_EINPUT */\n\tu32 emc_einput;\n\t/* Specifies the value for EMC_EINPUT_DURATION */\n\tu32 emc_einput_duration;\n\t/* Specifies the value for EMC_PUTERM_EXTRA */\n\tu32 emc_puterm_extra;\n\t/* Specifies the value for EMC_PUTERM_WIDTH */\n\tu32 emc_puterm_width;\n\n\tu32 emc_qrst;\n\tu32 emc_qsafe;\n\tu32 emc_rdv;\n\tu32 emc_rdv_mask;\n\n\tu32 emc_rdv_early;\n\tu32 emc_rdv_early_mask;\n\n\t/* Specifies the value for EMC_QPOP */\n\tu32 emc_qpop;\n\n\t/* Specifies the value for EMC_REFRESH */\n\tu32 emc_refresh;\n\t/* Specifies the value for EMC_BURST_REFRESH_NUM */\n\tu32 emc_burst_refresh_num;\n\t/* Specifies the value for EMC_PRE_REFRESH_REQ_CNT */\n\tu32 emc_prerefresh_req_cnt;\n\t/* Specifies the value for EMC_PDEX2WR */\n\tu32 emc_pdex2wr;\n\t/* Specifies the value for EMC_PDEX2RD */\n\tu32 emc_pdex2rd;\n\t/* Specifies the value for EMC_PCHG2PDEN */\n\tu32 emc_pchg2pden;\n\t/* Specifies the value for EMC_ACT2PDEN */\n\tu32 emc_act2pden;\n\t/* Specifies the value for EMC_AR2PDEN */\n\tu32 emc_ar2pden;\n\t/* Specifies the value for EMC_RW2PDEN */\n\tu32 emc_rw2pden;\n\n\tu32 emc_cke2pden;\n\tu32 emc_pdex2che;\n\tu32 emc_pdex2mrr;\n\n\t/* Specifies the value for EMC_TXSR */\n\tu32 emc_txsr;\n\t/* Specifies the value for EMC_TXSRDLL */\n\tu32 emc_txsr_dll;\n\t/* Specifies the value for EMC_TCKE */\n\tu32 emc_tcke;\n\t/* Specifies the value for EMC_TCKESR */\n\tu32 emc_tckesr;\n\t/* Specifies the value for EMC_TPD */\n\tu32 emc_tpd;\n\t/* Specifies the value for EMC_TFAW */\n\tu32 emc_tfaw;\n\t/* Specifies the value for EMC_TRPAB */\n\tu32 emc_trpab;\n\t/* Specifies the value for EMC_TCLKSTABLE */\n\tu32 emc_tclkstable;\n\t/* Specifies the value for EMC_TCLKSTOP */\n\tu32 emc_tclkstop;\n\t/* Specifies the value for EMC_TREFBW */\n\tu32 emc_trefbw;\n\n\t/* FBIO configuration values */\n\n\t/* Specifies the value for EMC_FBIO_CFG5 */\n\tu32 emc_fbio_cfg5;\n\t/* Specifies the value for EMC_FBIO_CFG7 */\n\tu32 emc_fbio_cfg7;\n\tu32 emc_fbio_cfg8;\n\n\t/* Command mapping for CMD brick 0 */\n\tu32 emc_cmd_mapping_cmd0_0;\n\tu32 emc_cmd_mapping_cmd0_1;\n\tu32 emc_cmd_mapping_cmd0_2;\n\tu32 emc_cmd_mapping_cmd1_0;\n\tu32 emc_cmd_mapping_cmd1_1;\n\tu32 emc_cmd_mapping_cmd1_2;\n\tu32 emc_cmd_mapping_cmd2_0;\n\tu32 emc_cmd_mapping_cmd2_1;\n\tu32 emc_cmd_mapping_cmd2_2;\n\tu32 emc_cmd_mapping_cmd3_0;\n\tu32 emc_cmd_mapping_cmd3_1;\n\tu32 emc_cmd_mapping_cmd3_2;\n\tu32 emc_cmd_mapping_byte;\n\n\t/* Specifies the value for EMC_FBIO_SPARE */\n\tu32 emc_fbio_spare;\n\n\t/* Specifies the value for EMC_CFG_RSV */\n\tu32 emc_cfg_rsv;\n\n\t/* MRS command values */\n\n\t/* Specifies the value for EMC_MRS */\n\tu32 emc_mrs;\n\t/* Specifies the MP0 command to initialize mode registers */\n\tu32 emc_emrs;\n\t/* Specifies the MP2 command to initialize mode registers */\n\tu32 emc_emrs2;\n\t/* Specifies the MP3 command to initialize mode registers */\n\tu32 emc_emrs3;\n\t/* Specifies the programming to LPDDR2 Mode Register 1 at cold boot */\n\tu32 emc_mrw1;\n\t/* Specifies the programming to LPDDR2 Mode Register 2 at cold boot */\n\tu32 emc_mrw2;\n\t/* Specifies the programming to LPDDR2 Mode Register 3 at cold boot */\n\tu32 emc_mrw3;\n\t/* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */\n\tu32 emc_mrw4;\n\n\t/* Specifies the programming to LPDDR4 Mode Register 3 at cold boot */\n\tu32 emc_mrw6;\n\t/* Specifies the programming to LPDDR4 Mode Register 11 at cold boot */\n\tu32 emc_mrw8;\n\t/* Specifies the programming to LPDDR4 Mode Register 11 at cold boot */\n\tu32 emc_mrw9;\n\t/* Specifies the programming to LPDDR4 Mode Register 12 at cold boot */\n\tu32 emc_mrw10;\n\t/* Specifies the programming to LPDDR4 Mode Register 14 at cold boot */\n\tu32 emc_mrw12;\n\t/* Specifies the programming to LPDDR4 Mode Register 14 at cold boot */\n\tu32 emc_mrw13;\n\t/* Specifies the programming to LPDDR4 Mode Register 22 at cold boot */\n\tu32 emc_mrw14;\n\n\t/*\n\t * Specifies the programming to extra LPDDR2 Mode Register\n\t * at cold boot\n\t */\n\tu32 emc_mrw_extra;\n\t/*\n\t * Specifies the programming to extra LPDDR2 Mode Register\n\t * at warm boot\n\t */\n\tu32 emc_warm_boot_mrw_extra;\n\t/*\n\t * Specify the enable of extra Mode Register programming at\n\t * warm boot\n\t */\n\tu32 emc_warm_boot_extramode_reg_write_enable;\n\t/*\n\t * Specify the enable of extra Mode Register programming at\n\t * cold boot\n\t */\n\tu32 emc_extramode_reg_write_enable;\n\n\t/* Specifies the EMC_MRW reset command value */\n\tu32 emc_mrw_reset_command;\n\t/* Specifies the EMC Reset wait time (in microseconds) */\n\tu32 emc_mrw_reset_ninit_wait;\n\t/* Specifies the value for EMC_MRS_WAIT_CNT */\n\tu32 emc_mrs_wait_cnt;\n\t/* Specifies the value for EMC_MRS_WAIT_CNT2 */\n\tu32 emc_mrs_wait_cnt2;\n\n\t/* EMC miscellaneous configurations */\n\n\t/* Specifies the value for EMC_CFG */\n\tu32 emc_cfg;\n\t/* Specifies the value for EMC_CFG_2 */\n\tu32 emc_cfg2;\n\t/* Specifies the pipe bypass controls */\n\tu32 emc_cfg_pipe;\n\n\tu32 emc_cfg_pipe_clk;\n\tu32 emc_fdpd_ctrl_cmd_no_ramp;\n\tu32 emc_cfg_update;\n\n\t/* Specifies the value for EMC_DBG */\n\tu32 emc_dbg;\n\n\tu32 emc_dbg_write_mux;\n\n\t/* Specifies the value for EMC_CMDQ */\n\tu32 emc_cmd_q;\n\t/* Specifies the value for EMC_MC2EMCQ */\n\tu32 emc_mc2emc_q;\n\t/* Specifies the value for EMC_DYN_SELF_REF_CONTROL */\n\tu32 emc_dyn_self_ref_control;\n\n\t/* Specifies the value for MEM_INIT_DONE */\n\tu32 ahb_arbitration_xbar_ctrl_meminit_done;\n\n\t/* Specifies the value for EMC_CFG_DIG_DLL */\n\tu32 emc_cfg_dig_dll;\n\tu32 emc_cfg_dig_dll_1;\n\n\t/* Specifies the value for EMC_CFG_DIG_DLL_PERIOD */\n\tu32 emc_cfg_dig_dll_period;\n\t/* Specifies the value of *DEV_SELECTN of various EMC registers */\n\tu32 emc_dev_select;\n\n\t/* Specifies the value for EMC_SEL_DPD_CTRL */\n\tu32 emc_sel_dpd_ctrl;\n\n\t/* Pads trimmer delays */\n\tu32 emc_fdpd_ctrl_dq;\n\tu32 emc_fdpd_ctrl_cmd;\n\tu32 emc_pmacro_ib_vref_dq_0;\n\tu32 emc_pmacro_ib_vref_dq_1;\n\tu32 emc_pmacro_ib_vref_dqs_0;\n\tu32 emc_pmacro_ib_vref_dqs_1;\n\tu32 emc_pmacro_ib_rxrt;\n\tu32 emc_cfg_pipe1;\n\tu32 emc_cfg_pipe2;\n\n\t/* Specifies the value for EMC_PMACRO_QUSE_DDLL_RANK0_0 */\n\tu32 emc_pmacro_quse_ddll_rank0_0;\n\tu32 emc_pmacro_quse_ddll_rank0_1;\n\tu32 emc_pmacro_quse_ddll_rank0_2;\n\tu32 emc_pmacro_quse_ddll_rank0_3;\n\tu32 emc_pmacro_quse_ddll_rank0_4;\n\tu32 emc_pmacro_quse_ddll_rank0_5;\n\tu32 emc_pmacro_quse_ddll_rank1_0;\n\tu32 emc_pmacro_quse_ddll_rank1_1;\n\tu32 emc_pmacro_quse_ddll_rank1_2;\n\tu32 emc_pmacro_quse_ddll_rank1_3;\n\tu32 emc_pmacro_quse_ddll_rank1_4;\n\tu32 emc_pmacro_quse_ddll_rank1_5;\n\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_0;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_1;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_2;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_3;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_4;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_5;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_0;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_1;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_2;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_3;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_4;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_5;\n\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_0;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_1;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_2;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_3;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_4;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_5;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_0;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_1;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_2;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_3;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_4;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_5;\n\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank0_0;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank0_1;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank0_2;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank0_3;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank1_0;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank1_1;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank1_2;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank1_3;\n\n\tu32 emc_pmacro_ddll_long_cmd_0;\n\tu32 emc_pmacro_ddll_long_cmd_1;\n\tu32 emc_pmacro_ddll_long_cmd_2;\n\tu32 emc_pmacro_ddll_long_cmd_3;\n\tu32 emc_pmacro_ddll_long_cmd_4;\n\tu32 emc_pmacro_ddll_short_cmd_0;\n\tu32 emc_pmacro_ddll_short_cmd_1;\n\tu32 emc_pmacro_ddll_short_cmd_2;\n\n\t/*\n\t * Specifies the delay after asserting CKE pin during a WarmBoot0\n\t * sequence (in microseconds)\n\t */\n\tu32 warm_boot_wait;\n\n\t/* Specifies the value for EMC_ODT_WRITE */\n\tu32 emc_odt_write;\n\n\t/* Periodic ZQ calibration */\n\n\t/*\n\t * Specifies the value for EMC_ZCAL_INTERVAL\n\t * Value 0 disables ZQ calibration\n\t */\n\tu32 emc_zcal_interval;\n\t/* Specifies the value for EMC_ZCAL_WAIT_CNT */\n\tu32 emc_zcal_wait_cnt;\n\t/* Specifies the value for EMC_ZCAL_MRW_CMD */\n\tu32 emc_zcal_mrw_cmd;\n\n\t/* DRAM initialization sequence flow control */\n\n\t/* Specifies the MRS command value for resetting DLL */\n\tu32 emc_mrs_reset_dll;\n\t/* Specifies the command for ZQ initialization of device 0 */\n\tu32 emc_zcal_init_dev0;\n\t/* Specifies the command for ZQ initialization of device 1 */\n\tu32 emc_zcal_init_dev1;\n\t/*\n\t * Specifies the wait time after programming a ZQ initialization\n\t * command (in microseconds)\n\t */\n\tu32 emc_zcal_init_wait;\n\t/*\n\t * Specifies the enable for ZQ calibration at cold boot [bit 0]\n\t * and warm boot [bit 1]\n\t */\n\tu32 emc_zcal_warm_cold_boot_enables;\n\n\t/*\n\t * Specifies the MRW command to LPDDR2 for ZQ calibration\n\t * on warmboot\n\t */\n\t/* Is issued to both devices separately */\n\tu32 emc_mrw_lpddr2zcal_warm_boot;\n\t/*\n\t * Specifies the ZQ command to DDR3 for ZQ calibration on warmboot\n\t * Is issued to both devices separately\n\t */\n\tu32 emc_zqcal_ddr3_warm_boot;\n\n\tu32 emc_zqcal_lpddr4_warm_boot;\n\n\t/*\n\t * Specifies the wait time for ZQ calibration on warmboot\n\t * (in microseconds)\n\t */\n\tu32 emc_zcal_warm_boot_wait;\n\t/*\n\t * Specifies the enable for DRAM Mode Register programming\n\t * at warm boot\n\t */\n\tu32 emc_mrs_warm_boot_enable;\n\t/*\n\t * Specifies the wait time after sending an MRS DLL reset command\n\t * in microseconds)\n\t */\n\tu32 emc_mrs_reset_dll_wait;\n\t/* Specifies the extra MRS command to initialize mode registers */\n\tu32 emc_mrs_extra;\n\t/* Specifies the extra MRS command at warm boot */\n\tu32 emc_warm_boot_mrs_extra;\n\t/* Specifies the EMRS command to enable the DDR2 DLL */\n\tu32 emc_emrs_ddr2_dll_enable;\n\t/* Specifies the MRS command to reset the DDR2 DLL */\n\tu32 emc_mrs_ddr2_dll_reset;\n\t/* Specifies the EMRS command to set OCD calibration */\n\tu32 emc_emrs_ddr2_ocd_calib;\n\t/*\n\t * Specifies the wait between initializing DDR and setting OCD\n\t * calibration (in microseconds)\n\t */\n\tu32 emc_ddr2_wait;\n\t/* Specifies the value for EMC_CLKEN_OVERRIDE */\n\tu32 emc_clken_override;\n\t/*\n\t * Specifies LOG2 of the extra refresh numbers after booting\n\t * Program 0 to disable\n\t */\n\tu32 emc_extra_refresh_num;\n\t/* Specifies the master override for all EMC clocks */\n\tu32 emc_clken_override_allwarm_boot;\n\t/* Specifies the master override for all MC clocks */\n\tu32 mc_clken_override_allwarm_boot;\n\t/* Specifies digital dll period, choosing between 4 to 64 ms */\n\tu32 emc_cfg_dig_dll_period_warm_boot;\n\n\t/* Pad controls */\n\n\t/* Specifies the value for PMC_VDDP_SEL */\n\tu32 pmc_vddp_sel;\n\t/* Specifies the wait time after programming PMC_VDDP_SEL */\n\tu32 pmc_vddp_sel_wait;\n\t/* Specifies the value for PMC_DDR_PWR */\n\tu32 pmc_ddr_pwr;\n\t/* Specifies the value for PMC_DDR_CFG */\n\tu32 pmc_ddr_cfg;\n\t/* Specifies the value for PMC_IO_DPD3_REQ */\n\tu32 pmc_io_dpd3_req;\n\t/* Specifies the wait time after programming PMC_IO_DPD3_REQ */\n\tu32 pmc_io_dpd3_req_wait;\n\n\tu32 pmc_io_dpd4_req_wait;\n\n\t/* Specifies the value for PMC_REG_SHORT */\n\tu32 pmc_reg_short;\n\t/* Specifies the value for PMC_NO_IOPOWER */\n\tu32 pmc_no_io_power;\n\n\tu32 pmc_ddr_ctrl_wait;\n\tu32 pmc_ddr_ctrl;\n\n\t/* Specifies the value for EMC_ACPD_CONTROL */\n\tu32 emc_acpd_control;\n\n\t/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE0 */\n\tu32 emc_swizzle_rank0_byte0;\n\t/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE1 */\n\tu32 emc_swizzle_rank0_byte1;\n\t/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE2 */\n\tu32 emc_swizzle_rank0_byte2;\n\t/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE3 */\n\tu32 emc_swizzle_rank0_byte3;\n\t/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE0 */\n\tu32 emc_swizzle_rank1_byte0;\n\t/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE1 */\n\tu32 emc_swizzle_rank1_byte1;\n\t/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE2 */\n\tu32 emc_swizzle_rank1_byte2;\n\t/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE3 */\n\tu32 emc_swizzle_rank1_byte3;\n\n\t/* Specifies the value for EMC_TXDSRVTTGEN */\n\tu32 emc_txdsrvttgen;\n\n\t/* Specifies the value for EMC_DATA_BRLSHFT_0 */\n\tu32 emc_data_brlshft0;\n\tu32 emc_data_brlshft1;\n\n\tu32 emc_dqs_brlshft0;\n\tu32 emc_dqs_brlshft1;\n\n\tu32 emc_cmd_brlshft0;\n\tu32 emc_cmd_brlshft1;\n\tu32 emc_cmd_brlshft2;\n\tu32 emc_cmd_brlshft3;\n\n\tu32 emc_quse_brlshft0;\n\tu32 emc_quse_brlshft1;\n\tu32 emc_quse_brlshft2;\n\tu32 emc_quse_brlshft3;\n\n\tu32 emc_dll_cfg0;\n\tu32 emc_dll_cfg1;\n\n\tu32 emc_pmc_scratch1;\n\tu32 emc_pmc_scratch2;\n\tu32 emc_pmc_scratch3;\n\n\tu32 emc_pmacro_pad_cfg_ctrl;\n\n\tu32 emc_pmacro_vttgen_ctrl0;\n\tu32 emc_pmacro_vttgen_ctrl1;\n\tu32 emc_pmacro_vttgen_ctrl2;\n\n\tu32 emc_pmacro_brick_ctrl_rfu1;\n\tu32 emc_pmacro_cmd_brick_ctrl_fdpd;\n\tu32 emc_pmacro_brick_ctrl_rfu2;\n\tu32 emc_pmacro_data_brick_ctrl_fdpd;\n\tu32 emc_pmacro_bg_bias_ctrl0;\n\tu32 emc_pmacro_data_pad_rx_ctrl;\n\tu32 emc_pmacro_cmd_pad_rx_ctrl;\n\tu32 emc_pmacro_data_rx_term_mode;\n\tu32 emc_pmacro_cmd_rx_term_mode;\n\tu32 emc_pmacro_data_pad_tx_ctrl;\n\tu32 emc_pmacro_common_pad_tx_ctrl;\n\tu32 emc_pmacro_cmd_pad_tx_ctrl;\n\tu32 emc_cfg3;\n\n\tu32 emc_pmacro_tx_pwrd0;\n\tu32 emc_pmacro_tx_pwrd1;\n\tu32 emc_pmacro_tx_pwrd2;\n\tu32 emc_pmacro_tx_pwrd3;\n\tu32 emc_pmacro_tx_pwrd4;\n\tu32 emc_pmacro_tx_pwrd5;\n\n\tu32 emc_config_sample_delay;\n\n\tu32 emc_pmacro_brick_mapping0;\n\tu32 emc_pmacro_brick_mapping1;\n\tu32 emc_pmacro_brick_mapping2;\n\n\tu32 emc_pmacro_tx_sel_clk_src0;\n\tu32 emc_pmacro_tx_sel_clk_src1;\n\tu32 emc_pmacro_tx_sel_clk_src2;\n\tu32 emc_pmacro_tx_sel_clk_src3;\n\tu32 emc_pmacro_tx_sel_clk_src4;\n\tu32 emc_pmacro_tx_sel_clk_src5;\n\n\tu32 emc_pmacro_ddll_bypass;\n\n\tu32 emc_pmacro_ddll_pwrd0;\n\tu32 emc_pmacro_ddll_pwrd1;\n\tu32 emc_pmacro_ddll_pwrd2;\n\n\tu32 emc_pmacro_cmd_ctrl0;\n\tu32 emc_pmacro_cmd_ctrl1;\n\tu32 emc_pmacro_cmd_ctrl2;\n\n\t/* DRAM size information */\n\n\t/* Specifies the value for MC_EMEM_ADR_CFG */\n\tu32 mc_emem_adr_cfg;\n\t/* Specifies the value for MC_EMEM_ADR_CFG_DEV0 */\n\tu32 mc_emem_adr_cfg_dev0;\n\t/* Specifies the value for MC_EMEM_ADR_CFG_DEV1 */\n\tu32 mc_emem_adr_cfg_dev1;\n\n\tu32 mc_emem_adr_cfg_channel_mask;\n\n\t/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG0 */\n\tu32 mc_emem_adr_cfg_bank_mask0;\n\t/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG1 */\n\tu32 mc_emem_adr_cfg_bank_mask1;\n\t/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG2 */\n\tu32 mc_emem_adr_cfg_bank_mask2;\n\n\t/*\n\t * Specifies the value for MC_EMEM_CFG which holds the external memory\n\t * size (in KBytes)\n\t */\n\tu32 mc_emem_cfg;\n\n\t/* MC arbitration configuration */\n\n\t/* Specifies the value for MC_EMEM_ARB_CFG */\n\tu32 mc_emem_arb_cfg;\n\t/* Specifies the value for MC_EMEM_ARB_OUTSTANDING_REQ */\n\tu32 mc_emem_arb_outstanding_req;\n\n\tu32 emc_emem_arb_refpb_hp_ctrl;\n\tu32 emc_emem_arb_refpb_bank_ctrl;\n\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_RCD */\n\tu32 mc_emem_arb_timing_rcd;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_RP */\n\tu32 mc_emem_arb_timing_rp;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_RC */\n\tu32 mc_emem_arb_timing_rc;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_RAS */\n\tu32 mc_emem_arb_timing_ras;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_FAW */\n\tu32 mc_emem_arb_timing_faw;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_RRD */\n\tu32 mc_emem_arb_timing_rrd;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_RAP2PRE */\n\tu32 mc_emem_arb_timing_rap2pre;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_WAP2PRE */\n\tu32 mc_emem_arb_timing_wap2pre;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_R2R */\n\tu32 mc_emem_arb_timing_r2r;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_W2W */\n\tu32 mc_emem_arb_timing_w2w;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_R2W */\n\tu32 mc_emem_arb_timing_r2w;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_W2R */\n\tu32 mc_emem_arb_timing_w2r;\n\n\tu32 mc_emem_arb_timing_rfcpb;\n\n\t/* Specifies the value for MC_EMEM_ARB_DA_TURNS */\n\tu32 mc_emem_arb_da_turns;\n\t/* Specifies the value for MC_EMEM_ARB_DA_COVERS */\n\tu32 mc_emem_arb_da_covers;\n\t/* Specifies the value for MC_EMEM_ARB_MISC0 */\n\tu32 mc_emem_arb_misc0;\n\t/* Specifies the value for MC_EMEM_ARB_MISC1 */\n\tu32 mc_emem_arb_misc1;\n\tu32 mc_emem_arb_misc2;\n\n\t/* Specifies the value for MC_EMEM_ARB_RING1_THROTTLE */\n\tu32 mc_emem_arb_ring1_throttle;\n\t/* Specifies the value for MC_EMEM_ARB_OVERRIDE */\n\tu32 mc_emem_arb_override;\n\t/* Specifies the value for MC_EMEM_ARB_OVERRIDE_1 */\n\tu32 mc_emem_arb_override1;\n\t/* Specifies the value for MC_EMEM_ARB_RSV */\n\tu32 mc_emem_arb_rsv;\n\n\tu32 mc_da_cfg0;\n\tu32 mc_emem_arb_timing_ccdmw;\n\n\t/* Specifies the value for MC_CLKEN_OVERRIDE */\n\tu32 mc_clken_override;\n\n\t/* Specifies the value for MC_STAT_CONTROL */\n\tu32 mc_stat_control;\n\t/* Specifies the value for MC_VIDEO_PROTECT_BOM */\n\tu32 mc_video_protect_bom;\n\t/* Specifies the value for MC_VIDEO_PROTECT_BOM_ADR_HI */\n\tu32 mc_video_protect_bom_adr_hi;\n\t/* Specifies the value for MC_VIDEO_PROTECT_SIZE_MB */\n\tu32 mc_video_protect_size_mb;\n\t/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE */\n\tu32 mc_video_protect_vpr_override;\n\t/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE1 */\n\tu32 mc_video_protect_vpr_override1;\n\t/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_0 */\n\tu32 mc_video_protect_gpu_override0;\n\t/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_1 */\n\tu32 mc_video_protect_gpu_override1;\n\t/* Specifies the value for MC_SEC_CARVEOUT_BOM */\n\tu32 mc_sec_carveout_bom;\n\t/* Specifies the value for MC_SEC_CARVEOUT_ADR_HI */\n\tu32 mc_sec_carveout_adr_hi;\n\t/* Specifies the value for MC_SEC_CARVEOUT_SIZE_MB */\n\tu32 mc_sec_carveout_size_mb;\n\t/* Specifies the value for MC_VIDEO_PROTECT_REG_CTRL.VIDEO_PROTECT_WRITE_ACCESS */\n\tu32 mc_video_protect_write_access;\n\t/* Specifies the value for MC_SEC_CARVEOUT_REG_CTRL.SEC_CARVEOUT_WRITE_ACCESS */\n\tu32 mc_sec_carveout_protect_write_access;\n\n\tu32 mc_generalized_carveout1_bom;\n\tu32 mc_generalized_carveout1_bom_hi;\n\tu32 mc_generalized_carveout1_size_128kb;\n\tu32 mc_generalized_carveout1_access0;\n\tu32 mc_generalized_carveout1_access1;\n\tu32 mc_generalized_carveout1_access2;\n\tu32 mc_generalized_carveout1_access3;\n\tu32 mc_generalized_carveout1_access4;\n\tu32 mc_generalized_carveout1_force_internal_access0;\n\tu32 mc_generalized_carveout1_force_internal_access1;\n\tu32 mc_generalized_carveout1_force_internal_access2;\n\tu32 mc_generalized_carveout1_force_internal_access3;\n\tu32 mc_generalized_carveout1_force_internal_access4;\n\tu32 mc_generalized_carveout1_cfg0;\n\n\tu32 mc_generalized_carveout2_bom;\n\tu32 mc_generalized_carveout2_bom_hi;\n\tu32 mc_generalized_carveout2_size_128kb;\n\tu32 mc_generalized_carveout2_access0;\n\tu32 mc_generalized_carveout2_access1;\n\tu32 mc_generalized_carveout2_access2;\n\tu32 mc_generalized_carveout2_access3;\n\tu32 mc_generalized_carveout2_access4;\n\tu32 mc_generalized_carveout2_force_internal_access0;\n\tu32 mc_generalized_carveout2_force_internal_access1;\n\tu32 mc_generalized_carveout2_force_internal_access2;\n\tu32 mc_generalized_carveout2_force_internal_access3;\n\tu32 mc_generalized_carveout2_force_internal_access4;\n\tu32 mc_generalized_carveout2_cfg0;\n\n\tu32 mc_generalized_carveout3_bom;\n\tu32 mc_generalized_carveout3_bom_hi;\n\tu32 mc_generalized_carveout3_size_128kb;\n\tu32 mc_generalized_carveout3_access0;\n\tu32 mc_generalized_carveout3_access1;\n\tu32 mc_generalized_carveout3_access2;\n\tu32 mc_generalized_carveout3_access3;\n\tu32 mc_generalized_carveout3_access4;\n\tu32 mc_generalized_carveout3_force_internal_access0;\n\tu32 mc_generalized_carveout3_force_internal_access1;\n\tu32 mc_generalized_carveout3_force_internal_access2;\n\tu32 mc_generalized_carveout3_force_internal_access3;\n\tu32 mc_generalized_carveout3_force_internal_access4;\n\tu32 mc_generalized_carveout3_cfg0;\n\n\tu32 mc_generalized_carveout4_bom;\n\tu32 mc_generalized_carveout4_bom_hi;\n\tu32 mc_generalized_carveout4_size_128kb;\n\tu32 mc_generalized_carveout4_access0;\n\tu32 mc_generalized_carveout4_access1;\n\tu32 mc_generalized_carveout4_access2;\n\tu32 mc_generalized_carveout4_access3;\n\tu32 mc_generalized_carveout4_access4;\n\tu32 mc_generalized_carveout4_force_internal_access0;\n\tu32 mc_generalized_carveout4_force_internal_access1;\n\tu32 mc_generalized_carveout4_force_internal_access2;\n\tu32 mc_generalized_carveout4_force_internal_access3;\n\tu32 mc_generalized_carveout4_force_internal_access4;\n\tu32 mc_generalized_carveout4_cfg0;\n\n\tu32 mc_generalized_carveout5_bom;\n\tu32 mc_generalized_carveout5_bom_hi;\n\tu32 mc_generalized_carveout5_size_128kb;\n\tu32 mc_generalized_carveout5_access0;\n\tu32 mc_generalized_carveout5_access1;\n\tu32 mc_generalized_carveout5_access2;\n\tu32 mc_generalized_carveout5_access3;\n\tu32 mc_generalized_carveout5_access4;\n\tu32 mc_generalized_carveout5_force_internal_access0;\n\tu32 mc_generalized_carveout5_force_internal_access1;\n\tu32 mc_generalized_carveout5_force_internal_access2;\n\tu32 mc_generalized_carveout5_force_internal_access3;\n\tu32 mc_generalized_carveout5_force_internal_access4;\n\tu32 mc_generalized_carveout5_cfg0;\n\n\t/* Specifies enable for CA training */\n\tu32 emc_ca_training_enable;\n\t/* Set if bit 6 select is greater than bit 7 select; uses aremc.spec packet SWIZZLE_BIT6_GT_BIT7 */\n\tu32 swizzle_rank_byte_encode;\n\t/* Specifies enable and offset for patched boot rom write */\n\tu32 boot_rom_patch_control;\n\t/* Specifies data for patched boot rom write */\n\tu32 boot_rom_patch_data;\n\n\t/* Specifies the value for MC_MTS_CARVEOUT_BOM */\n\tu32 mc_mts_carveout_bom;\n\t/* Specifies the value for MC_MTS_CARVEOUT_ADR_HI */\n\tu32 mc_mts_carveout_adr_hi;\n\t/* Specifies the value for MC_MTS_CARVEOUT_SIZE_MB */\n\tu32 mc_mts_carveout_size_mb;\n\t/* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */\n\tu32 mc_mts_carveout_reg_ctrl;\n} sdram_params_t;\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/power/bq24193.h",
    "content": "/*\n * Battery charger driver for Nintendo Switch's TI BQ24193\n *\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef __BQ24193_H_\n#define __BQ24193_H_\n\n#define BQ24193_I2C_ADDR 0x6B\n\n// REG 0 masks.\n#define BQ24193_INCONFIG_INLIMIT_MASK (7<<0)\n#define BQ24193_INCONFIG_VINDPM_MASK   0x78\n#define BQ24193_INCONFIG_HIZ_EN_MASK  (1<<7)\n\n// REG 1 masks.\n#define BQ24193_PORCONFIG_BOOST_MASK       (1<<0)\n#define BQ24193_PORCONFIG_SYSMIN_MASK      (7<<1)\n#define BQ24193_PORCONFIG_CHGCONFIG_MASK   (3<<4)\n#define BQ24193_PORCONFIG_I2CWATCHDOG_MASK (1<<6)\n#define BQ24193_PORCONFIG_RESET_MASK       (1<<7)\n\n// REG 2 masks.\n#define BQ24193_CHRGCURR_20PCT_MASK (1<<0)\n#define BQ24193_CHRGCURR_ICHG_MASK   0xFC\n\n// REG 3 masks.\n#define BQ24193_PRECHRG_ITERM   0x0F\n#define BQ24193_PRECHRG_IPRECHG 0xF0\n\n// REG 4 masks.\n#define BQ24193_CHRGVOLT_VTHRES  (1<<0)\n#define BQ24193_CHRGVOLT_BATTLOW (1<<1)\n#define BQ24193_CHRGVOLT_VREG     0xFC\n\n// REG 5 masks.\n#define BQ24193_CHRGTERM_ISET_MASK     (1<<0)\n#define BQ24193_CHRGTERM_CHGTIMER_MASK (3<<1)\n#define BQ24193_CHRGTERM_ENTIMER_MASK  (1<<3)\n#define BQ24193_CHRGTERM_WATCHDOG_MASK (3<<4)\n#define BQ24193_CHRGTERM_TERM_ST_MASK  (1<<6)\n#define BQ24193_CHRGTERM_TERM_EN_MASK  (1<<7)\n\n// REG 6 masks.\n#define BQ24193_IRTHERMAL_THERM_MASK    (3<<0)\n#define BQ24193_IRTHERMAL_VCLAMP_MASK   (7<<2)\n#define BQ24193_IRTHERMAL_BATTCOMP_MASK (7<<5)\n\n// REG 7 masks.\n#define BQ24193_MISC_INT_MASK       (3<<0)\n#define BQ24193_MISC_VSET_MASK      (1<<4)\n#define BQ24193_MISC_BATFET_DI_MASK (1<<5)\n#define BQ24193_MISC_TMR2X_EN_MASK  (1<<6)\n#define BQ24193_MISC_DPDM_EN_MASK   (1<<7)\n\n// REG 8 masks.\n#define BQ24193_STATUS_VSYS_MASK  (1<<0)\n#define BQ24193_STATUS_THERM_MASK (1<<1)\n#define BQ24193_STATUS_PG_MASK    (1<<2)\n#define BQ24193_STATUS_DPM_MASK   (1<<3)\n#define BQ24193_STATUS_CHRG_MASK  (3<<4)\n#define BQ24193_STATUS_VBUS_MASK  (3<<6)\n\n// REG 9 masks.\n#define BQ24193_FAULT_THERM_MASK    (7<<0)\n#define BQ24193_FAULT_BATT_OVP_MASK (1<<3)\n#define BQ24193_FAULT_CHARGE_MASK   (3<<4)\n#define BQ24193_FAULT_BOOST_MASK    (1<<6)\n#define BQ24193_FAULT_WATCHDOG_MASK (1<<7)\n\n// REG A masks.\n#define BQ24193_VENDORPART_DEV_MASK (3<<0)\n#define BQ24193_VENDORPART_PN_MASK  (7<<3)\n\nenum BQ24193_reg {\n\tBQ24193_InputSource     = 0x00,\n\tBQ24193_PORConfig       = 0x01,\n\tBQ24193_ChrgCurr        = 0x02,\n\tBQ24193_PreChrgTerm     = 0x03,\n\tBQ24193_ChrgVolt        = 0x04,\n\tBQ24193_ChrgTermTimer   = 0x05,\n\tBQ24193_IRCompThermal   = 0x06,\n\tBQ24193_Misc            = 0x07,\n\tBQ24193_Status          = 0x08,\n\tBQ24193_FaultReg        = 0x09,\n\tBQ24193_VendorPart      = 0x0A,\n};\n\nenum BQ24193_reg_prop {\n\tBQ24193_InputVoltageLimit,      // REG 0.\n\tBQ24193_InputCurrentLimit,      // REG 0.\n\tBQ24193_SystemMinimumVoltage,   // REG 1.\n\tBQ24193_FastChargeCurrentLimit, // REG 2.\n\tBQ24193_ChargeVoltageLimit,     // REG 4.\n\tBQ24193_RechargeThreshold,      // REG 4.\n\tBQ24193_ThermalRegulation,      // REG 6.\n\tBQ24193_ChargeStatus,           // REG 8.\n\tBQ24193_TempStatus,             // REG 9.\n\tBQ24193_DevID,                  // REG A.\n\tBQ24193_ProductNumber,          // REG A.\n};\n\nint bq24193_get_property(enum BQ24193_reg_prop prop, int *value);\nvoid bq24193_fake_battery_removal();\n\n#endif /* __BQ24193_H_ */"
  },
  {
    "path": "argon-first-stage/include/power/max17050.h",
    "content": "/*\n * Fuel gauge driver for Nintendo Switch's Maxim 17050\n *  Note that Maxim 8966 and 8997 are mfd and this is its subdevice.\n *\n * Copyright (C) 2011 Samsung Electronics\n * MyungJoo Ham <myungjoo.ham@samsung.com>\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\n#ifndef __MAX17050_H_\n#define __MAX17050_H_\n\n#define MAX17050_STATUS_BattAbsent    (1 << 3)\n#define MAX17050_DEFAULT_SNS_RESISTOR 10000\n\n/* Consider RepCap which is less then 10 units below FullCAP full */\n#define MAX17050_FULL_THRESHOLD 10\n\n#define MAX17050_CHARACTERIZATION_DATA_SIZE 48\n\n#define MAXIM17050_I2C_ADDR 0x36\n\nenum MAX17050_reg {\n\tMAX17050_STATUS\t\t= 0x00,\n\tMAX17050_VALRT_Th\t= 0x01,\n\tMAX17050_TALRT_Th\t= 0x02,\n\tMAX17050_SALRT_Th\t= 0x03,\n\tMAX17050_AtRate\t\t= 0x04,\n\tMAX17050_RepCap\t\t= 0x05,\n\tMAX17050_RepSOC\t\t= 0x06,\n\tMAX17050_Age\t\t= 0x07,\n\tMAX17050_TEMP\t\t= 0x08,\n\tMAX17050_VCELL\t\t= 0x09,\n\tMAX17050_Current\t= 0x0A,\n\tMAX17050_AvgCurrent\t= 0x0B,\n\n\tMAX17050_SOC\t\t= 0x0D,\n\tMAX17050_AvSOC\t\t= 0x0E,\n\tMAX17050_RemCap\t\t= 0x0F,\n\tMAX17050_FullCAP\t= 0x10,\n\tMAX17050_TTE\t\t= 0x11,\n\tMAX17050_QRTbl00\t= 0x12,\n\tMAX17050_FullSOCThr\t= 0x13,\n\tMAX17050_RSLOW\t\t= 0x14,\n\n\tMAX17050_AvgTA\t\t= 0x16,\n\tMAX17050_Cycles\t\t= 0x17,\n\tMAX17050_DesignCap\t= 0x18,\n\tMAX17050_AvgVCELL\t= 0x19,\n\tMAX17050_MinMaxTemp\t= 0x1A,\n\tMAX17050_MinMaxVolt\t= 0x1B,\n\tMAX17050_MinMaxCurr\t= 0x1C,\n\tMAX17050_CONFIG\t\t= 0x1D,\n\tMAX17050_ICHGTerm\t= 0x1E,\n\tMAX17050_AvCap\t\t= 0x1F,\n\tMAX17050_ManName\t= 0x20,\n\tMAX17050_DevName\t= 0x21,\n\tMAX17050_QRTbl10\t= 0x22,\n\tMAX17050_FullCAPNom\t= 0x23,\n\tMAX17050_TempNom\t= 0x24,\n\tMAX17050_TempLim\t= 0x25,\n\tMAX17050_TempHot\t= 0x26,\n\tMAX17050_AIN\t\t= 0x27,\n\tMAX17050_LearnCFG\t= 0x28,\n\tMAX17050_FilterCFG\t= 0x29,\n\tMAX17050_RelaxCFG\t= 0x2A,\n\tMAX17050_MiscCFG\t= 0x2B,\n\tMAX17050_TGAIN\t\t= 0x2C,\n\tMAX17050_TOFF\t\t= 0x2D,\n\tMAX17050_CGAIN\t\t= 0x2E,\n\tMAX17050_COFF\t\t= 0x2F,\n\n\tMAX17050_QRTbl20\t= 0x32,\n\tMAX17050_SOC_empty\t= 0x33,\n\tMAX17050_T_empty\t= 0x34,\n\tMAX17050_FullCAP0\t= 0x35,\n\tMAX17050_LAvg_empty\t= 0x36,\n\tMAX17050_FCTC\t\t= 0x37,\n\tMAX17050_RCOMP0\t\t= 0x38,\n\tMAX17050_TempCo\t\t= 0x39,\n\tMAX17050_V_empty\t= 0x3A,\n\tMAX17050_K_empty0\t= 0x3B,\n\tMAX17050_TaskPeriod\t= 0x3C,\n\tMAX17050_FSTAT\t\t= 0x3D,\n\n\tMAX17050_SHDNTIMER\t= 0x3F,\n\tMAX17050_QRTbl30\t= 0x42,\n\tMAX17050_dQacc\t\t= 0x45,\n\tMAX17050_dPacc\t\t= 0x46,\n\n\tMAX17050_VFSOC0\t\t= 0x48,\n\n\tMAX17050_QH\t\t\t= 0x4D,\n\tMAX17050_QL\t\t\t= 0x4E,\n\n\tMAX17050_MinVolt\t= 0x50, // Custom ID. Not to be sent to i2c.\n\tMAX17050_MaxVolt\t= 0x51, // Custom ID. Not to be sent to i2c.\n\n\tMAX17050_VFSOC0Enable\t= 0x60,\n\n\tMAX17050_MODELChrTbl\t= 0x80,\n\n\tMAX17050_OCV\t\t\t= 0xEE,\n\n\tMAX17050_OCVInternal\t= 0xFB,\n\n\tMAX17050_VFSOC\t\t\t= 0xFF,\n};\n\nint max17050_get_property(enum MAX17050_reg reg, int *value);\nint max17050_fix_configuration();\n\n#endif /* __MAX17050_H_ */\n"
  },
  {
    "path": "argon-first-stage/include/power/max77620.h",
    "content": "/*\n * Defining registers address and its bit definitions of MAX77620 and MAX20024\n *\n * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n */\n#ifndef _MFD_MAX77620_H_\n#define _MFD_MAX77620_H_\n\n#define MAX77620_I2C_ADDR 0x3C\n\n/* GLOBAL, PMIC, GPIO, FPS, ONOFFC, CID Registers */\n#define MAX77620_REG_CNFGGLBL1      0x00\n#define  MAX77620_CNFGGLBL1_LBDAC_EN          (1 << 7)\n#define  MAX77620_CNFGGLBL1_MPPLD             (1 << 6)\n#define  MAX77620_CNFGGLBL1_LBHYST            ((1 << 5) | (1 << 4))\n#define  MAX77620_CNFGGLBL1_LBHYST_N          (1 << 4)\n#define  MAX77620_CNFGGLBL1_LBDAC             0x0E\n#define  MAX77620_CNFGGLBL1_LBDAC_N           (1 << 1)\n#define  MAX77620_CNFGGLBL1_LBRSTEN           (1 << 0)\n\n#define MAX77620_REG_CNFGGLBL2      0x01\n#define MAX77620_REG_CNFGGLBL3      0x02\n#define  MAX77620_WDTC_MASK                   0x3\n#define  MAX77620_WDTOFFC                     (1 << 4)\n#define  MAX77620_WDTSLPC                     (1 << 3)\n#define  MAX77620_WDTEN                       (1 << 2)\n#define  MAX77620_TWD_MASK                    0x3\n#define  MAX77620_TWD_2s                      0x0\n#define  MAX77620_TWD_16s                     0x1\n#define  MAX77620_TWD_64s                     0x2\n#define  MAX77620_TWD_128s                    0x3\n\n#define MAX77620_REG_CNFG1_32K      0x03\n#define  MAX77620_CNFG1_32K_OUT0_EN           (1 << 2)\n\n#define MAX77620_REG_CNFGBBC        0x04\n#define  MAX77620_CNFGBBC_ENABLE              (1 << 0)\n#define  MAX77620_CNFGBBC_CURRENT_MASK        0x06\n#define  MAX77620_CNFGBBC_CURRENT_SHIFT       1\n#define  MAX77620_CNFGBBC_VOLTAGE_MASK        0x18\n#define  MAX77620_CNFGBBC_VOLTAGE_SHIFT       3\n#define  MAX77620_CNFGBBC_LOW_CURRENT_DISABLE (1 << 5)\n#define  MAX77620_CNFGBBC_RESISTOR_MASK       0xC0\n#define  MAX77620_CNFGBBC_RESISTOR_SHIFT      6\n#define  MAX77620_CNFGBBC_RESISTOR_100        (0 << MAX77620_CNFGBBC_RESISTOR_SHIFT)\n#define  MAX77620_CNFGBBC_RESISTOR_1K         (1 << MAX77620_CNFGBBC_RESISTOR_SHIFT)\n#define  MAX77620_CNFGBBC_RESISTOR_3K         (2 << MAX77620_CNFGBBC_RESISTOR_SHIFT)\n#define  MAX77620_CNFGBBC_RESISTOR_6K         (3 << MAX77620_CNFGBBC_RESISTOR_SHIFT)\n\n#define MAX77620_REG_IRQTOP         0x05\n#define  MAX77620_IRQ_TOP_GLBL_MASK           (1 << 7)\n#define  MAX77620_IRQ_TOP_SD_MASK             (1 << 6)\n#define  MAX77620_IRQ_TOP_LDO_MASK            (1 << 5)\n#define  MAX77620_IRQ_TOP_GPIO_MASK           (1 << 4)\n#define  MAX77620_IRQ_TOP_RTC_MASK            (1 << 3)\n#define  MAX77620_IRQ_TOP_32K_MASK            (1 << 2)\n#define  MAX77620_IRQ_TOP_ONOFF_MASK          (1 << 1)\n\n#define MAX77620_REG_INTLBT         0x06\n#define MAX77620_REG_IRQTOPM        0x0D\n#define  MAX77620_IRQ_LBM_MASK                (1 << 3)\n#define  MAX77620_IRQ_TJALRM1_MASK            (1 << 2)\n#define  MAX77620_IRQ_TJALRM2_MASK            (1 << 1)\n\n#define MAX77620_REG_IRQSD          0x07\n#define MAX77620_REG_IRQ_LVL2_L0_7  0x08\n#define MAX77620_REG_IRQ_LVL2_L8    0x09\n#define MAX77620_REG_IRQ_LVL2_GPIO  0x0A\n#define MAX77620_REG_ONOFFIRQ       0x0B\n#define MAX77620_REG_NVERC          0x0C\n\n#define MAX77620_REG_INTENLBT       0x0E\n#define  MAX77620_GLBLM_MASK                  (1 << 0)\n\n#define MAX77620_REG_IRQMASKSD      0x0F\n#define MAX77620_REG_IRQ_MSK_L0_7   0x10\n#define MAX77620_REG_IRQ_MSK_L8     0x11\n#define MAX77620_REG_ONOFFIRQM      0x12\n#define MAX77620_REG_STATLBT        0x13\n#define MAX77620_REG_STATSD         0x14\n#define MAX77620_REG_ONOFFSTAT      0x15\n\n/* SD and LDO Registers */\n#define MAX77620_REG_SD0            0x16\n#define MAX77620_REG_SD1            0x17\n#define MAX77620_REG_SD2            0x18\n#define MAX77620_REG_SD3            0x19\n#define MAX77620_REG_SD4            0x1A\n#define  MAX77620_SDX_VOLT_MASK               0xFF\n#define  MAX77620_SD0_VOLT_MASK               0x3F\n#define  MAX77620_SD1_VOLT_MASK               0x7F\n#define  MAX77620_LDO_VOLT_MASK               0x3F\n#define MAX77620_REG_DVSSD0         0x1B\n#define MAX77620_REG_DVSSD1         0x1C\n#define MAX77620_REG_SD0_CFG        0x1D\n#define MAX77620_REG_SD1_CFG        0x1E\n#define MAX77620_REG_SD2_CFG        0x1F\n#define MAX77620_REG_SD3_CFG        0x20\n#define MAX77620_REG_SD4_CFG        0x21\n#define MAX77620_REG_SD_CFG2        0x22\n#define MAX77620_REG_LDO0_CFG       0x23\n#define MAX77620_REG_LDO0_CFG2      0x24\n#define MAX77620_REG_LDO1_CFG       0x25\n#define MAX77620_REG_LDO1_CFG2      0x26\n#define MAX77620_REG_LDO2_CFG       0x27\n#define MAX77620_REG_LDO2_CFG2      0x28\n#define MAX77620_REG_LDO3_CFG       0x29\n#define MAX77620_REG_LDO3_CFG2      0x2A\n#define MAX77620_REG_LDO4_CFG       0x2B\n#define MAX77620_REG_LDO4_CFG2      0x2C\n#define MAX77620_REG_LDO5_CFG       0x2D\n#define MAX77620_REG_LDO5_CFG2      0x2E\n#define MAX77620_REG_LDO6_CFG       0x2F\n#define MAX77620_REG_LDO6_CFG2      0x30\n#define MAX77620_REG_LDO7_CFG       0x31\n#define MAX77620_REG_LDO7_CFG2      0x32\n#define MAX77620_REG_LDO8_CFG       0x33\n#define MAX77620_REG_LDO8_CFG2      0x34\n#define  MAX77620_LDO_POWER_MODE_MASK         0xC0\n#define  MAX77620_LDO_POWER_MODE_SHIFT        6\n#define  MAX77620_POWER_MODE_NORMAL\t          3\n#define  MAX77620_POWER_MODE_LPM              2\n#define  MAX77620_POWER_MODE_GLPM             1\n#define  MAX77620_POWER_MODE_DISABLE          0\n#define  MAX20024_LDO_CFG2_MPOK_MASK          (1 << 2)\n#define  MAX77620_LDO_CFG2_ADE_MASK           (1 << 1)\n#define  MAX77620_LDO_CFG2_ADE_DISABLE        0\n#define  MAX77620_LDO_CFG2_ADE_ENABLE         (1 << 1)\n#define  MAX77620_LDO_CFG2_SS_MASK            (1 << 0)\n#define  MAX77620_LDO_CFG2_SS_FAST            (1 << 0)\n#define  MAX77620_LDO_CFG2_SS_SLOW            0\n\n#define MAX77620_REG_LDO_CFG3       0x35\n#define  MAX77620_TRACK4_MASK                 (1 << 5)\n#define  MAX77620_TRACK4_SHIFT                5\n\n#define MAX77620_LDO_SLEW_RATE_MASK 0x1\n\n#define MAX77620_REG_GPIO0          0x36\n#define MAX77620_REG_GPIO1          0x37\n#define MAX77620_REG_GPIO2          0x38\n#define MAX77620_REG_GPIO3          0x39\n#define MAX77620_REG_GPIO4          0x3A\n#define MAX77620_REG_GPIO5          0x3B\n#define MAX77620_REG_GPIO6          0x3C\n#define MAX77620_REG_GPIO7          0x3D\n#define MAX77620_REG_PUE_GPIO       0x3E\n#define MAX77620_REG_PDE_GPIO       0x3F\n#define MAX77620_REG_AME_GPIO       0x40\n\n#define MAX77620_REG_ONOFFCNFG1     0x41\n#define  MAX77620_ONOFFCNFG1_SFT_RST          (1 << 7)\n#define  MAX77620_ONOFFCNFG1_MRT_MASK         0x38\n#define  MAX77620_ONOFFCNFG1_MRT_SHIFT        0x3\n#define  MAX77620_ONOFFCNFG1_SLPEN            (1 << 2)\n#define  MAX77620_ONOFFCNFG1_PWR_OFF          (1 << 1)\n#define  MAX20024_ONOFFCNFG1_CLRSE            0x18\n\n#define MAX77620_REG_ONOFFCNFG2     0x42\n#define  MAX77620_ONOFFCNFG2_SFT_RST_WK       (1 << 7)\n#define  MAX77620_ONOFFCNFG2_WD_RST_WK        (1 << 6)\n#define  MAX77620_ONOFFCNFG2_SLP_LPM_MSK      (1 << 5)\n#define  MAX77620_ONOFFCNFG2_WK_ALARM1        (1 << 2)\n#define  MAX77620_ONOFFCNFG2_WK_EN0           (1 << 0)\n\n/* FPS Registers */\n#define MAX77620_REG_FPS_CFG0       0x43\n#define MAX77620_REG_FPS_CFG1       0x44\n#define MAX77620_REG_FPS_CFG2       0x45\n#define MAX77620_REG_FPS_LDO0       0x46\n#define MAX77620_REG_FPS_LDO1       0x47\n#define MAX77620_REG_FPS_LDO2       0x48\n#define MAX77620_REG_FPS_LDO3       0x49\n#define MAX77620_REG_FPS_LDO4       0x4A\n#define MAX77620_REG_FPS_LDO5       0x4B\n#define MAX77620_REG_FPS_LDO6       0x4C\n#define MAX77620_REG_FPS_LDO7       0x4D\n#define MAX77620_REG_FPS_LDO8       0x4E\n#define MAX77620_REG_FPS_SD0        0x4F\n#define MAX77620_REG_FPS_SD1        0x50\n#define MAX77620_REG_FPS_SD2        0x51\n#define MAX77620_REG_FPS_SD3        0x52\n#define MAX77620_REG_FPS_SD4        0x53\n#define MAX77620_REG_FPS_NONE       0\n#define  MAX77620_FPS_SRC_MASK                0xC0\n#define  MAX77620_FPS_SRC_SHIFT               6\n#define  MAX77620_FPS_PU_PERIOD_MASK          0x38\n#define  MAX77620_FPS_PU_PERIOD_SHIFT         3\n#define  MAX77620_FPS_PD_PERIOD_MASK          0x07\n#define  MAX77620_FPS_PD_PERIOD_SHIFT         0\n\n/* Minimum and maximum FPS period time (in microseconds) are\n * different for MAX77620 and Max20024.\n */\n#define MAX77620_FPS_COUNT 3\n\n#define MAX77620_FPS_PERIOD_MIN_US 40\n#define MAX20024_FPS_PERIOD_MIN_US 20\n\n#define MAX77620_FPS_PERIOD_MAX_US 2560\n#define MAX20024_FPS_PERIOD_MAX_US 5120\n\n#define MAX77620_REG_FPS_GPIO1      0x54\n#define MAX77620_REG_FPS_GPIO2      0x55\n#define MAX77620_REG_FPS_GPIO3      0x56\n#define  MAX77620_FPS_TIME_PERIOD_MASK        0x38\n#define  MAX77620_FPS_TIME_PERIOD_SHIFT       3\n#define  MAX77620_FPS_EN_SRC_MASK             0x06\n#define  MAX77620_FPS_EN_SRC_SHIFT            1\n#define  MAX77620_FPS_ENFPS_SW_MASK           0x01\n#define  MAX77620_FPS_ENFPS_SW                0x01\n\n#define MAX77620_REG_FPS_RSO        0x57\n#define MAX77620_REG_CID0           0x58\n#define MAX77620_REG_CID1           0x59\n#define MAX77620_REG_CID2           0x5A\n#define MAX77620_REG_CID3           0x5B\n#define MAX77620_REG_CID4           0x5C\n#define MAX77620_REG_CID5           0x5D\n\n#define MAX77620_REG_DVSSD4         0x5E\n#define MAX20024_REG_MAX_ADD        0x70\n\n#define MAX77620_CID_DIDM_MASK                0xF0\n#define MAX77620_CID_DIDM_SHIFT               4\n\n/* CNCG2SD */\n#define MAX77620_SD_CNF2_ROVS_EN_SD1          (1 << 1)\n#define MAX77620_SD_CNF2_ROVS_EN_SD0          (1 << 2)\n\n/* Device Identification Metal */\n#define MAX77620_CID5_DIDM(n) (((n) >> 4) & 0xF)\n/* Device Indentification OTP */\n#define MAX77620_CID5_DIDO(n) ((n) & 0xF)\n\n/* SD CNFG1 */\n#define MAX77620_SD_SR_MASK                   0xC0\n#define MAX77620_SD_SR_SHIFT                  6\n#define MAX77620_SD_POWER_MODE_MASK           0x30\n#define MAX77620_SD_POWER_MODE_SHIFT          4\n#define MAX77620_SD_CFG1_ADE_MASK             (1 << 3)\n#define MAX77620_SD_CFG1_ADE_DISABLE          0\n#define MAX77620_SD_CFG1_ADE_ENABLE           (1 << 3)\n#define MAX77620_SD_FPWM_MASK                 0x04\n#define MAX77620_SD_FPWM_SHIFT                2\n#define MAX77620_SD_FSRADE_MASK               0x01\n#define MAX77620_SD_FSRADE_SHIFT              0\n#define MAX77620_SD_CFG1_FPWM_SD_MASK         (1 << 2)\n#define MAX77620_SD_CFG1_FPWM_SD_SKIP         0\n#define MAX77620_SD_CFG1_FPWM_SD_FPWM         (1 << 2)\n#define MAX20024_SD_CFG1_MPOK_MASK            (1 << 1)\n#define MAX77620_SD_CFG1_FSRADE_SD_MASK       (1 << 0)\n#define MAX77620_SD_CFG1_FSRADE_SD_DISABLE    0\n#define MAX77620_SD_CFG1_FSRADE_SD_ENABLE     (1 << 0)\n\n#define MAX77620_CNFG_GPIO_DRV_MASK           (1 << 0)\n#define MAX77620_CNFG_GPIO_DRV_PUSHPULL       (1 << 0)\n#define MAX77620_CNFG_GPIO_DRV_OPENDRAIN      0\n#define MAX77620_CNFG_GPIO_DIR_MASK           (1 << 1)\n#define MAX77620_CNFG_GPIO_DIR_INPUT          (1 << 1)\n#define MAX77620_CNFG_GPIO_DIR_OUTPUT         0\n#define MAX77620_CNFG_GPIO_INPUT_VAL_MASK     (1 << 2)\n#define MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK    (1 << 3)\n#define MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH    (1 << 3)\n#define MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW     0\n#define MAX77620_CNFG_GPIO_INT_MASK           (0x3 << 4)\n#define MAX77620_CNFG_GPIO_INT_FALLING        (1 << 4)\n#define MAX77620_CNFG_GPIO_INT_RISING         (1 << 5)\n#define MAX77620_CNFG_GPIO_DBNC_MASK          (0x3 << 6)\n#define MAX77620_CNFG_GPIO_DBNC_None          (0x0 << 6)\n#define MAX77620_CNFG_GPIO_DBNC_8ms           (0x1 << 6)\n#define MAX77620_CNFG_GPIO_DBNC_16ms          (0x2 << 6)\n#define MAX77620_CNFG_GPIO_DBNC_32ms          (0x3 << 6)\n\n#define MAX77620_IRQ_LVL2_GPIO_EDGE0          (1 << 0)\n#define MAX77620_IRQ_LVL2_GPIO_EDGE1          (1 << 1)\n#define MAX77620_IRQ_LVL2_GPIO_EDGE2          (1 << 2)\n#define MAX77620_IRQ_LVL2_GPIO_EDGE3          (1 << 3)\n#define MAX77620_IRQ_LVL2_GPIO_EDGE4          (1 << 4)\n#define MAX77620_IRQ_LVL2_GPIO_EDGE5          (1 << 5)\n#define MAX77620_IRQ_LVL2_GPIO_EDGE6          (1 << 6)\n#define MAX77620_IRQ_LVL2_GPIO_EDGE7          (1 << 7)\n\n/* Interrupts */\nenum {\n\tMAX77620_IRQ_TOP_GLBL,\t\t/* Low-Battery */\n\tMAX77620_IRQ_TOP_SD,\t\t/* SD power fail */\n\tMAX77620_IRQ_TOP_LDO,\t\t/* LDO power fail */\n\tMAX77620_IRQ_TOP_GPIO,\t\t/* TOP GPIO internal int to MAX77620 */\n\tMAX77620_IRQ_TOP_RTC,\t\t/* RTC */\n\tMAX77620_IRQ_TOP_32K,\t\t/* 32kHz oscillator */\n\tMAX77620_IRQ_TOP_ONOFF,\t\t/* ON/OFF oscillator */\n\tMAX77620_IRQ_LBT_MBATLOW,\t/* Thermal alarm status, > 120C */\n\tMAX77620_IRQ_LBT_TJALRM1,\t/* Thermal alarm status, > 120C */\n\tMAX77620_IRQ_LBT_TJALRM2,\t/* Thermal alarm status, > 140C */\n};\n\n/* GPIOs */\nenum {\n\tMAX77620_GPIO0,\n\tMAX77620_GPIO1,\n\tMAX77620_GPIO2,\n\tMAX77620_GPIO3,\n\tMAX77620_GPIO4,\n\tMAX77620_GPIO5,\n\tMAX77620_GPIO6,\n\tMAX77620_GPIO7,\n\tMAX77620_GPIO_NR,\n};\n\n/* FPS Source */\nenum max77620_fps_src {\n\tMAX77620_FPS_SRC_0,\n\tMAX77620_FPS_SRC_1,\n\tMAX77620_FPS_SRC_2,\n\tMAX77620_FPS_SRC_NONE,\n\tMAX77620_FPS_SRC_DEF,\n};\n\nenum max77620_chip_id {\n\tMAX77620,\n\tMAX20024,\n};\n\n#endif /* _MFD_MAX77620_H_ */\n"
  },
  {
    "path": "argon-first-stage/include/power/max7762x.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2019 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _MAX7762X_H_\n#define _MAX7762X_H_\n\n#include \"../utils/types.h\"\n\n/*\n* Switch Power domains (max77620):\n* Name  | Usage         | uV step | uV min | uV default | uV max  | Init\n*-------+---------------+---------+--------+------------+---------+------------------\n*  sd0  | core          | 12500   | 600000 |  625000    | 1400000 | 1.125V (pkg1.1)\n*  sd1  | SDRAM         | 12500   | 600000 | 1125000    | 1125000 | 1.1V   (pkg1.1)\n*  sd2  | ldo{0-1, 7-8} | 12500   | 600000 | 1325000    | 1350000 | 1.325V (pcv)\n*  sd3  | 1.8V general  | 12500   | 600000 | 1800000    | 1800000 |\n*  ldo0 | Display Panel | 25000   | 800000 | 1200000    | 1200000 | 1.2V   (pkg1.1)\n*  ldo1 | XUSB, PCIE    | 25000   | 800000 | 1050000    | 1050000 | 1.05V  (pcv)\n*  ldo2 | SDMMC1        | 50000   | 800000 | 1800000    | 3300000 |\n*  ldo3 | GC ASIC       | 50000   | 800000 | 3100000    | 3100000 | 3.1V  (pcv)\n*  ldo4 | RTC           | 12500   | 800000 |  850000    |  850000 |\n*  ldo5 | GC ASIC       | 50000   | 800000 | 1800000    | 1800000 | 1.8V  (pcv)\n*  ldo6 | Touch, ALS    | 50000   | 800000 | 2900000    | 2900000 | 2.9V\n*  ldo7 | XUSB          | 50000   | 800000 | 1050000    | 1050000 |\n*  ldo8 | XUSB, DC      | 50000   | 800000 | 1050000    | 1050000 |\n*/\n\n/*\n* MAX77620_AME_GPIO: control GPIO modes (bits 0 - 7 correspond to GPIO0 - GPIO7); 0 -> GPIO, 1 -> alt-mode\n* MAX77620_REG_GPIOx: 0x9 sets output and enable\n*/\n\n/*! MAX77620 partitions. */\n#define REGULATOR_SD0 0\n#define REGULATOR_SD1 1\n#define REGULATOR_SD2 2\n#define REGULATOR_SD3 3\n#define REGULATOR_LDO0 4\n#define REGULATOR_LDO1 5\n#define REGULATOR_LDO2 6\n#define REGULATOR_LDO3 7\n#define REGULATOR_LDO4 8\n#define REGULATOR_LDO5 9\n#define REGULATOR_LDO6 10\n#define REGULATOR_LDO7 11\n#define REGULATOR_LDO8 12\n#define REGULATOR_MAX 12\n\n#define MAX77621_CPU_I2C_ADDR 0x1B\n#define MAX77621_GPU_I2C_ADDR 0x1C\n\n#define MAX77621_VOUT_REG 0\n#define MAX77621_VOUT_DVC_REG 1\n#define MAX77621_CONTROL1_REG 2\n#define MAX77621_CONTROL2_REG 3\n\n/* MAX77621_VOUT */\n#define MAX77621_VOUT_ENABLE  (1 << 7)\n#define MAX77621_VOUT_MASK    0x7F\n\n/* MAX77621_VOUT_DVC_DVS */\n#define MAX77621_DVS_VOUT_MASK 0x7F\n\n/* MAX77621_CONTROL1 */\n#define MAX77621_SNS_ENABLE        (1 << 7)\n#define MAX77621_FPWM_EN_M         (1 << 6)\n#define MAX77621_NFSR_ENABLE       (1 << 5)\n#define MAX77621_AD_ENABLE         (1 << 4)\n#define MAX77621_BIAS_ENABLE       (1 << 3)\n#define MAX77621_FREQSHIFT_9PER    (1 << 2)\n\n#define MAX77621_RAMP_12mV_PER_US  0x0\n#define MAX77621_RAMP_25mV_PER_US  0x1\n#define MAX77621_RAMP_50mV_PER_US  0x2\n#define MAX77621_RAMP_200mV_PER_US 0x3\n#define MAX77621_RAMP_MASK         0x3\n\n/* MAX77621_CONTROL2 */\n#define MAX77621_WDTMR_ENABLE    (1 << 6)\n#define MAX77621_DISCH_ENBABLE   (1 << 5)\n#define MAX77621_FT_ENABLE\t\t (1 << 4)\n#define MAX77621_T_JUNCTION_120\t (1 << 7)\n\n#define MAX77621_CKKADV_TRIP_DISABLE              0xC\n#define MAX77621_CKKADV_TRIP_75mV_PER_US          0x0\n#define MAX77621_CKKADV_TRIP_150mV_PER_US         0x4\n#define MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS 0x8\n\n#define MAX77621_INDUCTOR_MIN_30_PER  0x0\n#define MAX77621_INDUCTOR_NOMINAL     0x1\n#define MAX77621_INDUCTOR_PLUS_30_PER 0x2\n#define MAX77621_INDUCTOR_PLUS_60_PER 0x3\n\nint max77620_regulator_get_status(u32 id);\nint max77620_regulator_config_fps(u32 id);\nint max77620_regulator_set_voltage(u32 id, u32 mv);\nint max77620_regulator_enable(u32 id, int enable);\nint max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags);\nvoid max77620_config_default();\nvoid max77620_low_battery_monitor_config();\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/sec/se.h",
    "content": "/*\n* Copyright (c) 2018 naehrwert\n*\n* This program is free software; you can redistribute it and/or modify it\n* under the terms and conditions of the GNU General Public License,\n* version 2, as published by the Free Software Foundation.\n*\n* This program is distributed in the hope it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _SE_H_\n#define _SE_H_\n\n#include \"../utils/types.h\"\n\nvoid se_rsa_acc_ctrl(u32 rs, u32 flags);\nvoid se_key_acc_ctrl(u32 ks, u32 flags);\nvoid se_aes_key_set(u32 ks, void *key, u32 size);\nvoid se_aes_key_clear(u32 ks);\nint se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input);\nint se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src);\nint se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr);\nint se_calc_sha256(void *dst, const void *src, u32 src_size);\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/sec/se_t210.h",
    "content": "/*\n* Driver for Tegra Security Engine\n*\n* Copyright (c) 2011-2013, NVIDIA Corporation. All Rights Reserved.\n*\n* This program is free software; you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation; either version 2 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License along\n* with this program; if not, write to the Free Software Foundation, Inc.,\n* 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\n*/\n\n#ifndef _CRYPTO_TEGRA_SE_H\n#define _CRYPTO_TEGRA_SE_H\n\n#include \"../utils/types.h\"\n\n#define TEGRA_SE_CRA_PRIORITY\t300\n#define TEGRA_SE_COMPOSITE_PRIORITY 400\n#define TEGRA_SE_CRYPTO_QUEUE_LENGTH 50\n#define SE_MAX_SRC_SG_COUNT\t\t50\n#define SE_MAX_DST_SG_COUNT\t\t50\n\n#define TEGRA_SE_KEYSLOT_COUNT\t\t16\n#define SE_MAX_LAST_BLOCK_SIZE\t0xFFFFF\n\n/* SE register definitions */\n#define SE_SECURITY_0 0x000\n#define SE_KEY_SCHED_READ_SHIFT 3\n\n#define SE_CONFIG_REG_OFFSET\t\t0x014\n#define SE_CONFIG_ENC_ALG_SHIFT\t\t12\n#define SE_CONFIG_DEC_ALG_SHIFT\t\t8\n#define ALG_AES_ENC\t\t1\n#define ALG_RNG\t\t\t2\n#define ALG_SHA\t\t\t3\n#define ALG_RSA\t\t\t4\n#define ALG_NOP\t\t\t0\n#define ALG_AES_DEC\t\t1\n#define SE_CONFIG_ENC_ALG(x)\t\t(x << SE_CONFIG_ENC_ALG_SHIFT)\n#define SE_CONFIG_DEC_ALG(x)\t\t(x << SE_CONFIG_DEC_ALG_SHIFT)\n#define SE_CONFIG_DST_SHIFT\t\t\t2\n#define DST_MEMORY\t\t0\n#define DST_HASHREG\t\t1\n#define DST_KEYTAB\t\t2\n#define DST_SRK\t\t\t3\n#define DST_RSAREG\t\t4\n#define SE_CONFIG_DST(x)\t\t\t(x << SE_CONFIG_DST_SHIFT)\n#define SE_CONFIG_ENC_MODE_SHIFT\t24\n#define SE_CONFIG_DEC_MODE_SHIFT\t16\n#define MODE_KEY128\t\t0\n#define MODE_KEY192\t\t1\n#define MODE_KEY256\t\t2\n#define MODE_SHA1\t\t0\n#define MODE_SHA224\t\t4\n#define MODE_SHA256\t\t5\n#define MODE_SHA384\t\t6\n#define MODE_SHA512\t\t7\n#define SE_CONFIG_ENC_MODE(x)\t\t(x << SE_CONFIG_ENC_MODE_SHIFT)\n#define SE_CONFIG_DEC_MODE(x)\t\t(x << SE_CONFIG_DEC_MODE_SHIFT)\n\n#define SE_RNG_CONFIG_REG_OFFSET\t\t0x340\n#define DRBG_MODE_SHIFT\t0\n#define DRBG_MODE_NORMAL\t0\n#define DRBG_MODE_FORCE_INSTANTION\t1\n#define DRBG_MODE_FORCE_RESEED\t\t2\n#define SE_RNG_CONFIG_MODE(x)\t\t(x << DRBG_MODE_SHIFT)\n\n#define SE_RNG_SRC_CONFIG_REG_OFFSET\t0x344\n#define DRBG_RO_ENT_SRC_SHIFT\t1\n#define DRBG_RO_ENT_SRC_ENABLE\t1\n#define DRBG_RO_ENT_SRC_DISABLE\t0\n#define SE_RNG_SRC_CONFIG_RO_ENT_SRC(x)\t(x << DRBG_RO_ENT_SRC_SHIFT)\n#define DRBG_RO_ENT_SRC_LOCK_SHIFT\t0\n#define DRBG_RO_ENT_SRC_LOCK_ENABLE\t1\n#define DRBG_RO_ENT_SRC_LOCK_DISABLE\t0\n#define SE_RNG_SRC_CONFIG_RO_ENT_SRC_LOCK(x) (x << DRBG_RO_ENT_SRC_LOCK_SHIFT)\n\n#define DRBG_SRC_SHIFT\t2\n#define DRBG_SRC_NONE\t0\n#define DRBG_SRC_ENTROPY\t1\n#define DRBG_SRC_LFSR\t2\n#define SE_RNG_CONFIG_SRC(x)\t\t(x << DRBG_SRC_SHIFT)\n\n#define SE_RNG_RESEED_INTERVAL_REG_OFFSET\t\t0x348\n\n#define SE_KEYTABLE_REG_OFFSET\t\t0x31c\n#define SE_KEYTABLE_SLOT_SHIFT\t\t4\n#define SE_KEYTABLE_SLOT(x)\t\t\t(x << SE_KEYTABLE_SLOT_SHIFT)\n#define SE_KEYTABLE_QUAD_SHIFT\t\t2\n#define QUAD_KEYS_128\t0\n#define QUAD_KEYS_192\t1\n#define QUAD_KEYS_256\t1\n#define QUAD_ORG_IV\t\t2\n#define QUAD_UPDTD_IV\t3\n#define SE_KEYTABLE_QUAD(x)\t\t\t(x << SE_KEYTABLE_QUAD_SHIFT)\n#define SE_KEYTABLE_OP_TYPE_SHIFT\t9\n#define OP_READ\t\t\t0\n#define OP_WRITE\t\t1\n#define SE_KEYTABLE_OP_TYPE(x)\t\t(x << SE_KEYTABLE_OP_TYPE_SHIFT)\n#define SE_KEYTABLE_TABLE_SEL_SHIFT\t\t8\n#define TABLE_KEYIV\t\t0\n#define TABLE_SCHEDULE\t1\n#define SE_KEYTABLE_TABLE_SEL(x)\t(x << SE_KEYTABLE_TABLE_SEL_SHIFT)\n#define SE_KEYTABLE_PKT_SHIFT\t\t0\n#define SE_KEYTABLE_PKT(x)\t\t\t(x << SE_KEYTABLE_PKT_SHIFT)\n\n#define SE_OP_DONE_SHIFT\t4\n#define OP_DONE\t1\n#define SE_OP_DONE(x, y)\t((x) && (y << SE_OP_DONE_SHIFT))\n\n#define SE_CRYPTO_REG_OFFSET\t\t0x304\n#define SE_CRYPTO_HASH_SHIFT\t\t0\n#define HASH_DISABLE\t0\n#define HASH_ENABLE\t\t1\n#define SE_CRYPTO_HASH(x)\t\t\t(x << SE_CRYPTO_HASH_SHIFT)\n#define SE_CRYPTO_XOR_POS_SHIFT\t\t1\n#define XOR_BYPASS\t\t0\n#define XOR_TOP\t\t\t2\n#define XOR_BOTTOM\t\t3\n#define SE_CRYPTO_XOR_POS(x)\t\t(x << SE_CRYPTO_XOR_POS_SHIFT)\n#define SE_CRYPTO_INPUT_SEL_SHIFT\t3\n#define INPUT_AHB\t\t0\n#define INPUT_RANDOM\t1\n#define INPUT_AESOUT\t2\n#define INPUT_LNR_CTR\t3\n#define SE_CRYPTO_INPUT_SEL(x)\t\t(x << SE_CRYPTO_INPUT_SEL_SHIFT)\n#define SE_CRYPTO_VCTRAM_SEL_SHIFT\t5\n#define VCTRAM_AHB\t\t0\n#define VCTRAM_AESOUT\t2\n#define VCTRAM_PREVAHB\t3\n#define SE_CRYPTO_VCTRAM_SEL(x)\t\t(x << SE_CRYPTO_VCTRAM_SEL_SHIFT)\n#define SE_CRYPTO_IV_SEL_SHIFT\t\t7\n#define IV_ORIGINAL\t\t0\n#define IV_UPDATED\t\t1\n#define SE_CRYPTO_IV_SEL(x)\t\t\t(x << SE_CRYPTO_IV_SEL_SHIFT)\n#define SE_CRYPTO_CORE_SEL_SHIFT\t8\n#define CORE_DECRYPT\t0\n#define CORE_ENCRYPT\t1\n#define SE_CRYPTO_CORE_SEL(x)\t\t(x << SE_CRYPTO_CORE_SEL_SHIFT)\n#define SE_CRYPTO_CTR_VAL_SHIFT\t\t11\n#define SE_CRYPTO_CTR_VAL(x)\t\t(x << SE_CRYPTO_CTR_VAL_SHIFT)\n#define SE_CRYPTO_KEY_INDEX_SHIFT\t24\n#define SE_CRYPTO_KEY_INDEX(x)\t\t(x << SE_CRYPTO_KEY_INDEX_SHIFT)\n#define SE_CRYPTO_CTR_CNTN_SHIFT\t11\n#define SE_CRYPTO_CTR_CNTN(x)\t\t(x << SE_CRYPTO_CTR_CNTN_SHIFT)\n\n#define SE_CRYPTO_CTR_REG_COUNT\t\t4\n#define SE_CRYPTO_CTR_REG_OFFSET\t0x308\n\n#define SE_OPERATION_REG_OFFSET\t\t0x008\n#define SE_OPERATION_SHIFT\t\t\t0\n#define OP_ABORT\t\t0\n#define OP_START\t\t1\n#define OP_RESTART\t\t2\n#define OP_CTX_SAVE\t\t3\n#define OP_RESTART_IN\t4\n#define SE_OPERATION(x)\t\t\t\t(x << SE_OPERATION_SHIFT)\n\n#define SE_CONTEXT_SAVE_CONFIG_REG_OFFSET\t\t0x070\n#define SE_CONTEXT_SAVE_WORD_QUAD_SHIFT\t\t0\n#define KEYS_0_3\t\t0\n#define KEYS_4_7\t\t1\n#define ORIG_IV\t\t2\n#define UPD_IV\t\t3\n#define SE_CONTEXT_SAVE_WORD_QUAD(x)\t(x << SE_CONTEXT_SAVE_WORD_QUAD_SHIFT)\n\n#define SE_CONTEXT_SAVE_KEY_INDEX_SHIFT\t\t8\n#define SE_CONTEXT_SAVE_KEY_INDEX(x)\t(x << SE_CONTEXT_SAVE_KEY_INDEX_SHIFT)\n\n#define SE_CONTEXT_SAVAE_STICKY_WORD_QUAD_SHIFT\t24\n#define STICKY_0_3\t\t0\n#define STICKY_4_7\t\t1\n#define SE_CONTEXT_SAVE_STICKY_WORD_QUAD(x)\t\t\\\n\t\t(x << SE_CONTEXT_SAVAE_STICKY_WORD_QUAD_SHIFT)\n\n#define SE_CONTEXT_SAVE_SRC_SHIFT\t\t29\n#define STICKY_BITS\t\t0\n#define KEYTABLE\t\t2\n#define MEM\t\t4\n#define SRK\t\t6\n\n#define RSA_KEYTABLE\t1\n#define SE_CONTEXT_SAVE_SRC(x)\t\t(x << SE_CONTEXT_SAVE_SRC_SHIFT)\n\n#define SE_CONTEXT_SAVE_RSA_KEY_INDEX_SHIFT\t16\n#define SE_CONTEXT_SAVE_RSA_KEY_INDEX(x)\t\t\\\n\t\t(x << SE_CONTEXT_SAVE_RSA_KEY_INDEX_SHIFT)\n\n#define SE_CONTEXT_RSA_WORD_QUAD_SHIFT\t12\n#define SE_CONTEXT_RSA_WORD_QUAD(x)\t\t\\\n\t\t(x << SE_CONTEXT_RSA_WORD_QUAD_SHIFT)\n\n#define SE_INT_ENABLE_REG_OFFSET\t0x00c\n#define SE_INT_STATUS_REG_OFFSET\t0x010\n#define INT_DISABLE\t\t0\n#define INT_ENABLE\t\t1\n#define INT_UNSET\t\t0\n#define INT_SET\t\t\t1\n#define SE_INT_OP_DONE_SHIFT\t\t4\n#define SE_INT_OP_DONE(x)\t\t\t(x << SE_INT_OP_DONE_SHIFT)\n#define SE_INT_ERROR_SHIFT\t\t16\n#define SE_INT_ERROR(x)\t\t\t(x << SE_INT_ERROR_SHIFT)\n#define SE_STATUS_0 0x800\n#define SE_ERR_STATUS_0\t\t\t0x804\n\n#define SE_CRYPTO_KEYTABLE_DST_REG_OFFSET\t0X330\n#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT\t\t0\n#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD(x)\t\t\\\n\t\t(x << SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT)\n\n#define SE_KEY_INDEX_SHIFT\t\t8\n#define SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(x)\t(x << SE_KEY_INDEX_SHIFT)\n\n#define SE_IN_LL_ADDR_REG_OFFSET\t0x018\n#define SE_OUT_LL_ADDR_REG_OFFSET\t0x024\n\n#define SE_KEYTABLE_DATA0_REG_OFFSET\t0x320\n#define SE_KEYTABLE_REG_MAX_DATA\t\t16\n\n#define SE_BLOCK_COUNT_REG_OFFSET\t0x318\n\n#define SE_SPARE_0_REG_OFFSET\t\t0x80c\n\n#define SE_SHA_CONFIG_REG_OFFSET\t0x200\n#define SHA_DISABLE\t\t0\n#define SHA_ENABLE\t\t1\n\n#define SE_SHA_MSG_LENGTH_REG_OFFSET\t0x204\n#define SE_SHA_MSG_LEFT_REG_OFFSET\t\t0x214\n\n#define SE_HASH_RESULT_REG_COUNT\t16\n#define SE_HASH_RESULT_REG_OFFSET\t0x030\n#define TEGRA_SE_KEY_256_SIZE\t\t32\n#define TEGRA_SE_KEY_192_SIZE\t\t24\n#define TEGRA_SE_KEY_128_SIZE\t\t16\n#define TEGRA_SE_AES_BLOCK_SIZE\t\t16\n#define TEGRA_SE_AES_MIN_KEY_SIZE\t16\n#define TEGRA_SE_AES_MAX_KEY_SIZE\t32\n#define TEGRA_SE_AES_IV_SIZE\t\t16\n#define TEGRA_SE_RNG_IV_SIZE\t\t16\n#define TEGRA_SE_RNG_DT_SIZE\t\t16\n#define TEGRA_SE_RNG_KEY_SIZE\t\t16\n#define TEGRA_SE_RNG_SEED_SIZE\t\t(TEGRA_SE_RNG_IV_SIZE + \\\n\t\t\t\t\t\tTEGRA_SE_RNG_KEY_SIZE + \\\n\t\t\t\t\t\tTEGRA_SE_RNG_DT_SIZE)\n\n#define TEGRA_SE_AES_CMAC_DIGEST_SIZE\t16\n#define TEGRA_SE_RSA512_DIGEST_SIZE\t64\n#define TEGRA_SE_RSA1024_DIGEST_SIZE\t128\n#define TEGRA_SE_RSA1536_DIGEST_SIZE\t192\n#define TEGRA_SE_RSA2048_DIGEST_SIZE\t256\n\n#define SE_KEY_TABLE_ACCESS_LOCK_OFFSET\t0x280\n#define SE_KEY_TABLE_ACCESS_REG_OFFSET\t0x284\n#define SE_KEY_READ_DISABLE_SHIFT\t\t0\n#define SE_KEY_UPDATE_DISABLE_SHIFT\t\t1\n\n#define SE_CONTEXT_BUFER_SIZE\t1072\n#define SE_CONTEXT_DRBG_BUFER_SIZE\t2112\n\n#define SE_CONTEXT_SAVE_RANDOM_DATA_OFFSET\t0\n#define SE_CONTEXT_SAVE_RANDOM_DATA_SIZE\t16\n#define SE_CONTEXT_SAVE_STICKY_BITS_OFFSET\t\\\n\t(SE_CONTEXT_SAVE_RANDOM_DATA_OFFSET + SE_CONTEXT_SAVE_RANDOM_DATA_SIZE)\n#define SE_CONTEXT_SAVE_STICKY_BITS_SIZE\t16\n\n#define SE_CONTEXT_SAVE_KEYS_OFFSET\t(SE_CONTEXT_SAVE_STICKY_BITS_OFFSET + \\\n\t\t\t\t\tSE_CONTEXT_SAVE_STICKY_BITS_SIZE)\n#define SE11_CONTEXT_SAVE_KEYS_OFFSET\t(SE_CONTEXT_SAVE_STICKY_BITS_OFFSET + \\\n\t\t\t\t\tSE_CONTEXT_SAVE_STICKY_BITS_SIZE + \\\n\t\t\t\t\tSE_CONTEXT_SAVE_STICKY_BITS_SIZE)\n\n#define SE_CONTEXT_SAVE_KEY_LENGTH\t512\n#define SE_CONTEXT_ORIGINAL_IV_OFFSET\t(SE_CONTEXT_SAVE_KEYS_OFFSET + \\\n\t\t\tSE_CONTEXT_SAVE_KEY_LENGTH)\n#define SE11_CONTEXT_ORIGINAL_IV_OFFSET\t(SE11_CONTEXT_SAVE_KEYS_OFFSET + \\\n\t\t\tSE_CONTEXT_SAVE_KEY_LENGTH)\n\n#define SE_CONTEXT_ORIGINAL_IV_LENGTH\t256\n\n#define SE_CONTEXT_UPDATED_IV_OFFSET\t(SE_CONTEXT_ORIGINAL_IV_OFFSET + \\\n\t\t\tSE_CONTEXT_ORIGINAL_IV_LENGTH)\n#define SE11_CONTEXT_UPDATED_IV_OFFSET\t(SE11_CONTEXT_ORIGINAL_IV_OFFSET + \\\n\t\t\tSE_CONTEXT_ORIGINAL_IV_LENGTH)\n\n#define SE_CONTEXT_UPDATED_IV_LENGTH\t256\n\n#define SE_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET (SE_CONTEXT_UPDATED_IV_OFFSET + \\\n\t\t\t\t\tSE_CONTEXT_UPDATED_IV_LENGTH)\n#define SE11_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET \\\n\t\t\t\t\t(SE11_CONTEXT_UPDATED_IV_OFFSET + \\\n\t\t\t\t\tSE_CONTEXT_UPDATED_IV_LENGTH)\n\n#define SE_CONTEXT_SAVE_RSA_KEYS_OFFSET\tSE11_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET\n\n#define SE_CONTEXT_SAVE_RSA_KEY_LENGTH\t1024\n\n#define SE_CONTEXT_SAVE_RSA_KNOWN_PATTERN_OFFSET\t\\\n\t(SE_CONTEXT_SAVE_RSA_KEYS_OFFSET + SE_CONTEXT_SAVE_RSA_KEY_LENGTH)\n\n#define SE_CONTEXT_KNOWN_PATTERN_SIZE\t16\n\n#define TEGRA_SE_RSA_KEYSLOT_COUNT\t\t2\n\n#define SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET\t0x40C\n#define SE_RSA_KEYTABLE_ACCESS_REG_OFFSET\t0x410\n\n#define SE_RSA_KEYTABLE_ADDR\t0x420\n#define SE_RSA_KEYTABLE_DATA\t0x424\n#define SE_RSA_OUTPUT 0x428\n\n#define RSA_KEY_READ\t0\n#define RSA_KEY_WRITE\t1\n#define SE_RSA_KEY_OP_SHIFT\t10\n#define SE_RSA_KEY_OP(x)\t(x << SE_RSA_KEY_OP_SHIFT)\n\n#define RSA_KEY_INPUT_MODE_REG\t0\n#define RSA_KEY_INPUT_MODE_DMA\t1\n#define RSA_KEY_INPUT_MODE_SHIFT\t8\n#define RSA_KEY_INPUT_MODE(x)\t(x << RSA_KEY_INPUT_MODE_SHIFT)\n\n#define RSA_KEY_SLOT_ONE\t0\n#define RSA_KEY_SLOT_TW0\t1\n#define RSA_KEY_NUM_SHIFT\t7\n#define RSA_KEY_NUM(x)\t(x << RSA_KEY_NUM_SHIFT)\n\n#define RSA_KEY_TYPE_EXP\t0\n#define RSA_KEY_TYPE_MOD\t1\n#define RSA_KEY_TYPE_SHIFT\t6\n#define RSA_KEY_TYPE(x)\t(x << RSA_KEY_TYPE_SHIFT)\n\n#define SE_RSA_KEY_SIZE_REG_OFFSET\t0x404\n#define SE_RSA_EXP_SIZE_REG_OFFSET\t0x408\n\n#define RSA_KEY_SLOT_SHIFT\t24\n#define RSA_KEY_SLOT(x)\t(x << RSA_KEY_SLOT_SHIFT)\n#define SE_RSA_CONFIG\t0x400\n\n#define RSA_KEY_PKT_WORD_ADDR_SHIFT\t0\n#define RSA_KEY_PKT_WORD_ADDR(x)\t(x << RSA_KEY_PKT_WORD_ADDR_SHIFT)\n\n#define RSA_KEY_WORD_ADDR_SHIFT\t0\n#define RSA_KEY_WORD_ADDR(x)\t(x << RSA_KEY_WORD_ADDR_SHIFT)\n\n#define SE_RSA_KEYTABLE_PKT_SHIFT\t0\n#define SE_RSA_KEYTABLE_PKT(x)\t(x << SE_RSA_KEYTABLE_PKT_SHIFT)\n\n#endif /* _CRYPTO_TEGRA_SE_H */\n"
  },
  {
    "path": "argon-first-stage/include/soc/bpmp.h",
    "content": "/*\n * BPMP-Lite Cache/MMU and Frequency driver for Tegra X1\n *\n * Copyright (c) 2019 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _BPMP_H_\n#define _BPMP_H_\n\n#include \"utils/types.h\"\n\n#define BPMP_MMU_MAINT_CLEAN_WAY   17\n#define BPMP_MMU_MAINT_INVALID_WAY 18\n#define BPMP_MMU_MAINT_CLN_INV_WAY 19\n\ntypedef struct _bpmp_mmu_entry_t\n{\n\tu32 min_addr;\n\tu32 max_addr;\n\tu32 attr;\n\tu32 enable;\n} bpmp_mmu_entry_t;\n\ntypedef enum\n{\n\tBPMP_CLK_NORMAL,      // 408MHz  0% - 136MHz APB.\n\tBPMP_CLK_LOW_BOOST,   // 544MHz 33% - 136MHz APB.\n\tBPMP_CLK_MID_BOOST,   // 576MHz 41% - 144MHz APB.\n\tBPMP_CLK_SUPER_BOOST, // 608MHz 49% - 152MHz APB.\n\tBPMP_CLK_MAX\n} bpmp_freq_t;\n\nvoid bpmp_mmu_maintenance(u32 op);\nvoid bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply);\nvoid bpmp_mmu_enable();\nvoid bpmp_mmu_disable();\nvoid bpmp_clk_rate_set(bpmp_freq_t fid);\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/soc/clock.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _CLOCK_H_\n#define _CLOCK_H_\n\n#include \"utils/types.h\"\n\n/*! Clock registers. */\n#define CLK_RST_CONTROLLER_RST_SOURCE 0x0\n#define CLK_RST_CONTROLLER_RST_DEVICES_L 0x4\n#define CLK_RST_CONTROLLER_RST_DEVICES_H 0x8\n#define CLK_RST_CONTROLLER_RST_DEVICES_U 0xC\n#define CLK_RST_CONTROLLER_CLK_OUT_ENB_L 0x10\n#define CLK_RST_CONTROLLER_CLK_OUT_ENB_H 0x14\n#define CLK_RST_CONTROLLER_CLK_OUT_ENB_U 0x18\n#define CLK_RST_CONTROLLER_CCLK_BURST_POLICY 0x20\n#define CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER 0x24\n#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY 0x28\n#define CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER 0x2C\n#define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE 0x30\n#define CLK_RST_CONTROLLER_MISC_CLK_ENB 0x48\n#define CLK_RST_CONTROLLER_OSC_CTRL 0x50\n#define CLK_RST_CONTROLLER_PLLC_BASE 0x80\n#define CLK_RST_CONTROLLER_PLLC_MISC 0x88\n#define CLK_RST_CONTROLLER_PLLM_BASE 0x90\n#define CLK_RST_CONTROLLER_PLLM_MISC1 0x98\n#define CLK_RST_CONTROLLER_PLLM_MISC2 0x9C\n#define CLK_RST_CONTROLLER_PLLP_BASE 0xA0\n#define CLK_RST_CONTROLLER_PLLD_BASE 0xD0\n#define CLK_RST_CONTROLLER_PLLX_BASE 0xE0\n#define CLK_RST_CONTROLLER_PLLX_MISC 0xE4\n#define CLK_RST_CONTROLLER_PLLE_BASE 0xE8\n#define CLK_RST_CONTROLLER_PLLE_MISC 0xEC\n#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA 0xF8\n#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB 0xFC\n#define CLK_RST_CONTROLLER_CLK_SOURCE_PWM 0x110\n#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C1 0x124\n#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C5 0x128\n#define CLK_RST_CONTROLLER_CLK_SOURCE_VI 0x148\n#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1 0x150\n#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2 0x154\n#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4 0x164\n#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTA 0x178\n#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTB 0x17C\n#define CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X 0x180\n#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTC 0x1A0\n#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C3 0x1B8\n#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3 0x1BC\n#define CLK_RST_CONTROLLER_CLK_SOURCE_CSITE 0x1D4\n#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC 0x19C\n#define CLK_RST_CONTROLLER_CLK_SOURCE_TSEC 0x1F4\n#define CLK_RST_CONTROLLER_CLK_OUT_ENB_X 0x280\n#define CLK_RST_CONTROLLER_CLK_ENB_X_SET 0x284\n#define CLK_RST_CONTROLLER_CLK_ENB_X_CLR 0x288\n#define CLK_RST_CONTROLLER_RST_DEVICES_X 0x28C\n#define CLK_RST_CONTROLLER_RST_DEV_X_SET 0x290\n#define CLK_RST_CONTROLLER_RST_DEV_X_CLR 0x294\n#define CLK_RST_CONTROLLER_CLK_OUT_ENB_Y 0x298\n#define CLK_RST_CONTROLLER_CLK_ENB_Y_SET 0x29C\n#define CLK_RST_CONTROLLER_CLK_ENB_Y_CLR 0x2A0\n#define CLK_RST_CONTROLLER_RST_DEVICES_Y 0x2A4\n#define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2A8\n#define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2AC\n#define CLK_RST_CONTROLLER_RST_DEV_L_SET 0x300\n#define CLK_RST_CONTROLLER_RST_DEV_L_CLR 0x304\n#define CLK_RST_CONTROLLER_RST_DEV_H_SET 0x308\n#define CLK_RST_CONTROLLER_RST_DEV_H_CLR 0x30C\n#define CLK_RST_CONTROLLER_RST_DEV_U_SET 0x310\n#define CLK_RST_CONTROLLER_RST_DEV_U_CLR 0x314\n#define CLK_RST_CONTROLLER_CLK_ENB_L_SET 0x320\n#define CLK_RST_CONTROLLER_CLK_ENB_L_CLR 0x324\n#define CLK_RST_CONTROLLER_CLK_ENB_H_SET 0x328\n#define CLK_RST_CONTROLLER_CLK_ENB_H_CLR 0x32C\n#define CLK_RST_CONTROLLER_CLK_ENB_U_SET 0x330\n#define CLK_RST_CONTROLLER_CLK_ENB_U_CLR 0x334\n#define CLK_RST_CONTROLLER_RST_DEVICES_V 0x358\n#define CLK_RST_CONTROLLER_RST_DEVICES_W 0x35C\n#define CLK_RST_CONTROLLER_CLK_OUT_ENB_V 0x360\n#define CLK_RST_CONTROLLER_CLK_OUT_ENB_W 0x364\n#define CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2 0x388\n#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC 0x3A0\n#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD 0x3A4\n#define CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT 0x3B4\n#define CLK_RST_CONTROLLER_CLK_SOURCE_SOR1 0x410\n#define CLK_RST_CONTROLLER_CLK_SOURCE_SE 0x42C\n#define CLK_RST_CONTROLLER_CLK_ENB_V_SET 0x440\n//#define CLK_RST_CONTROLLER_CLK_ENB_V_CLR 0x444\n#define CLK_RST_CONTROLLER_CLK_ENB_W_SET 0x448\n#define CLK_RST_CONTROLLER_CLK_ENB_W_CLR 0x44C\n#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET 0x450\n#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR 0x454\n#define CLK_RST_CONTROLLER_UTMIP_PLL_CFG2 0x488\n#define CLK_RST_CONTROLLER_PLLE_AUX 0x48C\n#define CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_I2S0 0x4A0\n#define CLK_RST_CONTROLLER_PLLX_MISC_3 0x518\n#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE 0x554\n#define CLK_RST_CONTROLLER_SPARE_REG0 0x55C\n#define CLK_RST_CONTROLLER_PLLC4_BASE 0x5A4\n#define CLK_RST_CONTROLLER_PLLC4_MISC 0x5A8\n#define CLK_RST_CONTROLLER_PLLC4_OUT 0x5E4\n#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8\n#define CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP 0x620\n//#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 0x65C\n#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664\n#define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIP_CAL 0x66C\n#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM 0x694\n#define CLK_RST_CONTROLLER_CLK_SOURCE_NVENC 0x6A0\n#define CLK_RST_CONTROLLER_SE_SUPER_CLK_DIVIDER 0x704\n\n#define CLK_NO_SOURCE 0x0\n\n/*! Generic clock descriptor. */\ntypedef struct _clock_t\n{\n\tu32 reset;\n\tu32 enable;\n\tu32 source;\n\tu8 index;\n\tu8 clk_src;\n\tu8 clk_div;\n} clock_t;\n\n/*! Generic clock enable/disable. */\nvoid clock_enable(const clock_t *clk);\nvoid clock_disable(const clock_t *clk);\n\n/*! Clock control for specific hardware portions. */\nvoid clock_enable_fuse(bool enable);\nvoid clock_enable_uart(u32 idx);\nvoid clock_enable_i2c(u32 idx);\nvoid clock_disable_i2c(u32 idx);\nvoid clock_enable_se();\nvoid clock_enable_tzram();\nvoid clock_enable_host1x();\nvoid clock_disable_host1x();\nvoid clock_enable_tsec();\nvoid clock_disable_tsec();\nvoid clock_enable_sor_safe();\nvoid clock_disable_sor_safe();\nvoid clock_enable_sor0();\nvoid clock_disable_sor0();\nvoid clock_enable_sor1();\nvoid clock_disable_sor1();\nvoid clock_enable_kfuse();\nvoid clock_disable_kfuse();\nvoid clock_enable_cl_dvfs();\nvoid clock_disable_cl_dvfs();\nvoid clock_enable_coresight();\nvoid clock_disable_coresight();\nvoid clock_enable_pwm();\nvoid clock_disable_pwm();\nvoid clock_sdmmc_config_clock_source(u32 *pout, u32 id, u32 val);\nvoid clock_sdmmc_get_params(u32 *pout, u16 *pdivisor, u32 type);\nint clock_sdmmc_is_not_reset_and_enabled(u32 id);\nvoid clock_sdmmc_enable(u32 id, u32 val);\nvoid clock_sdmmc_disable(u32 id);\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/soc/cluster.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _CLUSTER_H_\n#define _CLUSTER_H_\n\n#include \"utils/types.h\"\n\n/*! Flow controller registers. */\n#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0\n#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14\n#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C\n#define FLOW_CTLR_HALT_CPU3_EVENTS 0x24\n#define FLOW_CTLR_HALT_COP_EVENTS 0x4\n#define FLOW_CTLR_CPU0_CSR 0x8\n#define FLOW_CTLR_CPU1_CSR 0x18\n#define FLOW_CTLR_CPU2_CSR 0x20\n#define FLOW_CTLR_CPU3_CSR 0x28\n#define FLOW_CTLR_RAM_REPAIR 0x40\n#define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98\n\nvoid cluster_boot_cpu0(u32 entry);\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/soc/fuse.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 shuffle2\n * Copyright (c) 2018 balika011\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _FUSE_H_\n#define _FUSE_H_\n\n#include \"utils/types.h\"\n\n/*! Fuse registers. */\n#define FUSE_CTRL 0x0\n#define FUSE_ADDR 0x4\n#define FUSE_RDATA 0x8\n#define FUSE_WDATA 0xC\n#define FUSE_TIME_RD1 0x10\n#define FUSE_TIME_RD2 0x14\n#define FUSE_TIME_PGM1 0x18\n#define FUSE_TIME_PGM2 0x1C\n#define FUSE_PRIV2INTFC 0x20\n#define FUSE_FUSEBYPASS 0x24\n#define FUSE_PRIVATEKEYDISABLE 0x28\n#define FUSE_DISABLEREGPROGRAM 0x2C\n#define FUSE_WRITE_ACCESS_SW 0x30\n#define FUSE_PWR_GOOD_SW 0x34\n#define FUSE_SKU_INFO 0x110\n#define FUSE_FIRST_BOOTROM_PATCH_SIZE 0x19c\n#define FUSE_PRIVATE_KEY0 0x1A4\n#define FUSE_PRIVATE_KEY1 0x1A8\n#define FUSE_PRIVATE_KEY2 0x1AC\n#define FUSE_PRIVATE_KEY3 0x1B0\n\n/*! Fuse commands. */\n#define FUSE_READ 0x1\n#define FUSE_WRITE 0x2\n#define FUSE_SENSE 0x3\n#define FUSE_CMD_MASK 0x3\n\n/*! Fuse cache registers. */\n#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))\n\nvoid fuse_disable_program();\nu32 fuse_read_odm(u32 idx);\nvoid fuse_wait_idle();\nint fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value));\nint fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len);\nvoid read_raw_ipatch_fuses(u32 *words);\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/soc/gpio.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _GPIO_H_\n#define _GPIO_H_\n\n#include \"utils/types.h\"\n\n#define GPIO_MODE_SPIO 0\n#define GPIO_MODE_GPIO 1\n#define GPIO_OUTPUT_DISABLE 0\n#define GPIO_OUTPUT_ENABLE 1\n#define GPIO_LOW 0\n#define GPIO_HIGH 1\n\n/*! GPIO pins (0-7 for each port). */\n#define GPIO_PIN_0 (1 << 0)\n#define GPIO_PIN_1 (1 << 1)\n#define GPIO_PIN_2 (1 << 2)\n#define GPIO_PIN_3 (1 << 3)\n#define GPIO_PIN_4 (1 << 4)\n#define GPIO_PIN_5 (1 << 5)\n#define GPIO_PIN_6 (1 << 6)\n#define GPIO_PIN_7 (1 << 7)\n\n/*! GPIO ports (A-EE). */\n#define GPIO_PORT_A 0\n#define GPIO_PORT_B 1\n#define GPIO_PORT_C 2\n#define GPIO_PORT_D 3\n#define GPIO_PORT_E 4\n#define GPIO_PORT_F 5\n#define GPIO_PORT_G 6\n#define GPIO_PORT_H 7\n#define GPIO_PORT_I 8\n#define GPIO_PORT_J 9\n#define GPIO_PORT_K 10\n#define GPIO_PORT_L 11\n#define GPIO_PORT_M 12\n#define GPIO_PORT_N 13\n#define GPIO_PORT_O 14\n#define GPIO_PORT_P 15\n#define GPIO_PORT_Q 16\n#define GPIO_PORT_R 17\n#define GPIO_PORT_S 18\n#define GPIO_PORT_T 19\n#define GPIO_PORT_U 20\n#define GPIO_PORT_V 21\n#define GPIO_PORT_W 22\n#define GPIO_PORT_X 23\n#define GPIO_PORT_Y 24\n#define GPIO_PORT_Z 25\n#define GPIO_PORT_AA 26\n#define GPIO_PORT_BB 27\n#define GPIO_PORT_CC 28\n#define GPIO_PORT_DD 29\n#define GPIO_PORT_EE 30\n\nvoid gpio_config(u32 port, u32 pins, int mode);\nvoid gpio_output_enable(u32 port, u32 pins, int enable);\nvoid gpio_write(u32 port, u32 pins, int high);\nint gpio_read(u32 port, u32 pins);\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/soc/hw_init.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _HW_INIT_H_\n#define _HW_INIT_H_\n\n#include \"utils/types.h\"\n\nvoid config_hw();\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/soc/i2c.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _I2C_H_\n#define _I2C_H_\n\n#include \"utils/types.h\"\n\n#define I2C_1 0\n#define I2C_2 1\n#define I2C_3 2\n#define I2C_4 3\n#define I2C_5 4\n#define I2C_6 5\n\n#define I2C_CNFG        0x00\n#define I2C_CMD_ADDR0   0x01\n#define I2C_CMD_DATA1   0x03\n#define I2C_CMD_DATA2   0x04\n#define I2C_STATUS 0x07\n#define INTERRUPT_STATUS_REGISTER 0x1A\n#define I2C_CLK_DIVISOR_REGISTER 0x1B\n#define I2C_BUS_CLEAR_CONFIG 0x21\n#define I2C_BUS_CLEAR_STATUS 0x22\n#define I2C_CONFIG_LOAD 0x23\n\nvoid i2c_init(u32 idx);\nint i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size);\nint i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y);\nint i2c_send_byte(u32 idx, u32 x, u32 y, u8 b);\nu8 i2c_recv_byte(u32 idx, u32 x, u32 y);\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/soc/pinmux.h",
    "content": "#ifndef _PINMUX_H_\n#define _PINMUX_H_\n\n#include \"utils/types.h\"\n\n/*! APB MISC registers. */\n#define APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL 0x8D4\n#define APB_MISC_GP_SDMMC3_CLK_LPBK_CONTROL 0x8D8\n#define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL   0xA98\n#define APB_MISC_GP_VGPIO_GPIO_MUX_SEL      0xB74\n\n/*! Pinmux registers. */\n#define PINMUX_AUX_SDMMC1_CLK      0x00\n#define PINMUX_AUX_SDMMC1_CMD      0x04\n#define PINMUX_AUX_SDMMC1_DAT3     0x08\n#define PINMUX_AUX_SDMMC1_DAT2     0x0C\n#define PINMUX_AUX_SDMMC1_DAT1     0x10\n#define PINMUX_AUX_SDMMC1_DAT0     0x14\n#define PINMUX_AUX_SDMMC3_CLK      0x1C\n#define PINMUX_AUX_SDMMC3_CMD      0x20\n#define PINMUX_AUX_SDMMC3_DAT0     0x24\n#define PINMUX_AUX_SDMMC3_DAT1     0x28\n#define PINMUX_AUX_SDMMC3_DAT2     0x2C\n#define PINMUX_AUX_SDMMC3_DAT3     0x30\n#define PINMUX_AUX_SATA_LED_ACTIVE 0x4C\n#define PINMUX_AUX_DMIC3_CLK       0xB4\n#define PINMUX_AUX_DMIC3_DAT       0xB8\n#define PINMUX_AUX_CAM_I2C_SCL     0xD4\n#define PINMUX_AUX_CAM_I2C_SDA     0xD8\n#define PINMUX_AUX_UART2_TX        0xF4\n#define PINMUX_AUX_UART3_TX        0x104\n#define PINMUX_AUX_DAP4_DIN        0x148\n#define PINMUX_AUX_USB_VBUS_EN0    0x1A8\n#define PINMUX_AUX_WIFI_EN         0x1B4\n#define PINMUX_AUX_WIFI_RST        0x1B8\n#define PINMUX_AUX_DAP4_SCLK       0x150\n#define PINMUX_AUX_GPIO_X1_AUD     0x18C\n#define PINMUX_AUX_GPIO_X3_AUD     0x190\n#define PINMUX_AUX_SPDIF_IN        0x1A4\n#define PINMUX_AUX_AP_WAKE_NFC     0x1CC\n#define PINMUX_AUX_NFC_EN          0x1D0\n#define PINMUX_AUX_NFC_INT         0x1D4\n#define PINMUX_AUX_CAM1_PWDN       0x1EC\n#define PINMUX_AUX_LCD_BL_PWM      0x1FC\n#define PINMUX_AUX_LCD_BL_EN       0x200\n#define PINMUX_AUX_LCD_RST         0x204\n#define PINMUX_AUX_LCD_GPIO2       0x20C\n#define PINMUX_AUX_TOUCH_INT       0x220\n#define PINMUX_AUX_MOTION_INT      0x224\n#define PINMUX_AUX_GPIO_PE6        0x248\n#define PINMUX_AUX_GPIO_PH6        0x250\n#define PINMUX_AUX_GPIO_PZ1        0x280\n/*! 0:UART-A, 1:UART-B, 3:UART-C, 3:UART-D */\n#define PINMUX_AUX_UARTX_TX(x)  (0xE4 + 0x10 * (x))\n#define PINMUX_AUX_UARTX_RX(x)  (0xE8 + 0x10 * (x))\n#define PINMUX_AUX_UARTX_RTS(x) (0xEC + 0x10 * (x))\n#define PINMUX_AUX_UARTX_CTS(x) (0xF0 + 0x10 * (x))\n/*! 0:GEN1, 1:GEN2, 2:GEN3, 3:CAM, 4:PWR */\n#define PINMUX_AUX_X_I2C_SCL(x) (0xBC + 8 * (x))\n#define PINMUX_AUX_X_I2C_SDA(x) (0xC0 + 8 * (x))\n\n#define PINMUX_FUNC_MASK    (3 << 0)\n\n#define PINMUX_PULL_MASK    (3 << 2)\n#define PINMUX_PULL_NONE    (0 << 2)\n#define PINMUX_PULL_DOWN    (1 << 2)\n#define PINMUX_PULL_UP      (2 << 2)\n\n#define PINMUX_TRISTATE     (1 << 4)\n#define PINMUX_PARKED       (1 << 5)\n#define PINMUX_INPUT_ENABLE (1 << 6)\n#define PINMUX_LOCK         (1 << 7)\n#define PINMUX_LPDR         (1 << 8)\n#define PINMUX_HSM          (1 << 9)\n\n#define PINMUX_IO_HV        (1 << 10)\n#define PINMUX_OPEN_DRAIN   (1 << 11)\n#define PINMUX_SCHMT        (1 << 12)\n\n#define PINMUX_DRIVE_1X     (0 << 13) \n#define PINMUX_DRIVE_2X     (1 << 13)\n#define PINMUX_DRIVE_3X     (2 << 13)\n#define PINMUX_DRIVE_4X     (3 << 13)\n\nvoid pinmux_config_uart(u32 idx);\nvoid pinmux_config_i2c(u32 idx);\n\n#endif"
  },
  {
    "path": "argon-first-stage/include/soc/pmc.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 st4rk\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _PMC_H_\n#define _PMC_H_\n\n/*! PMC registers. */\n#define APBDEV_PMC_CNTRL 0x0\n#define  PMC_CNTRL_MAIN_RST (1 << 4)\n#define APBDEV_PMC_SEC_DISABLE 0x4\n#define APBDEV_PMC_PWRGATE_TOGGLE 0x30\n#define APBDEV_PMC_PWRGATE_STATUS 0x38\n#define APBDEV_PMC_NO_IOPOWER 0x44\n#define APBDEV_PMC_SCRATCH0 0x50\n#define APBDEV_PMC_SCRATCH1 0x54\n#define APBDEV_PMC_SCRATCH20 0xA0\n#define APBDEV_PMC_PWR_DET_VAL 0xE4\n#define  PMC_PWR_DET_SDMMC1_IO_EN (1 << 12)\n#define APBDEV_PMC_DDR_PWR 0xE8\n#define APBDEV_PMC_CRYPTO_OP 0xF4\n#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4\n#define APBDEV_PMC_RST_STATUS 0x1B4\n#define APBDEV_PMC_IO_DPD_REQ 0x1B8\n#define APBDEV_PMC_IO_DPD2_REQ 0x1C0\n#define APBDEV_PMC_VDDP_SEL 0x1CC\n#define APBDEV_PMC_DDR_CFG 0x1D0\n#define APBDEV_PMC_SCRATCH49 0x244\n#define APBDEV_PMC_TSC_MULT 0x2B4\n#define APBDEV_PMC_SEC_DISABLE2 0x2C4\n#define APBDEV_PMC_WEAK_BIAS 0x2C8\n#define APBDEV_PMC_REG_SHORT 0x2CC\n#define APBDEV_PMC_SEC_DISABLE3 0x2D8\n#define APBDEV_PMC_SECURE_SCRATCH21 0x334\n#define APBDEV_PMC_SECURE_SCRATCH32 0x360\n#define APBDEV_PMC_SECURE_SCRATCH49 0x3A4\n#define APBDEV_PMC_CNTRL2 0x440\n#define APBDEV_PMC_IO_DPD3_REQ 0x45C\n#define APBDEV_PMC_IO_DPD4_REQ 0x464\n#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4\n#define APBDEV_PMC_UTMIP_PAD_CFG3 0x4CC\n#define APBDEV_PMC_DDR_CNTRL 0x4E4\n#define APBDEV_PMC_SEC_DISABLE4 0x5B0\n#define APBDEV_PMC_SEC_DISABLE5 0x5B4\n#define APBDEV_PMC_SEC_DISABLE6 0x5B8\n#define APBDEV_PMC_SEC_DISABLE7 0x5BC\n#define APBDEV_PMC_SEC_DISABLE8 0x5C0\n#define APBDEV_PMC_SCRATCH188 0x810\n#define APBDEV_PMC_SCRATCH190 0x818\n#define APBDEV_PMC_SCRATCH200 0x840\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/soc/pmc_lp0_t210.h",
    "content": "/*\n * Copyright (c) 2010-2015, NVIDIA CORPORATION.  All rights reserved.\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n */\n\n#ifndef _TEGRA210_PMC_H_\n#define _TEGRA210_PMC_H_\n\n#include \"utils/types.h\"\n\nstruct tegra_pmc_regs\n{\n\tu32 cntrl;\n\tu32 sec_disable;\n\tu32 pmc_swrst;\n\tu32 wake_mask;\n\tu32 wake_lvl;\n\tu32 wake_status;\n\tu32 sw_wake_status;\n\tu32 dpd_pads_oride;\n\tu32 dpd_sample;\n\tu32 dpd_enable;\n\tu32 pwrgate_timer_off;\n\tu32 clamp_status;\n\tu32 pwrgate_toggle;\n\tu32 remove_clamping_cmd;\n\tu32 pwrgate_status;\n\tu32 pwrgood_timer;\n\tu32 blink_timer;\n\tu32 no_iopower;\n\tu32 pwr_det;\n\tu32 pwr_det_latch;\n\tu32 scratch0;\n\tu32 scratch1;\n\tu32 scratch2;\n\tu32 scratch3;\n\tu32 scratch4;\n\tu32 scratch5;\n\tu32 scratch6;\n\tu32 scratch7;\n\tu32 scratch8;\n\tu32 scratch9;\n\tu32 scratch10;\n\tu32 scratch11;\n\tu32 scratch12;\n\tu32 scratch13;\n\tu32 scratch14;\n\tu32 scratch15;\n\tu32 scratch16;\n\tu32 scratch17;\n\tu32 scratch18;\n\tu32 scratch19;\n\tu32 odmdata;\n\tu32 scratch21;\n\tu32 scratch22;\n\tu32 scratch23;\n\tu32 secure_scratch0;\n\tu32 secure_scratch1;\n\tu32 secure_scratch2;\n\tu32 secure_scratch3;\n\tu32 secure_scratch4;\n\tu32 secure_scratch5;\n\tu32 cpupwrgood_timer;\n\tu32 cpupwroff_timer;\n\tu32 pg_mask;\n\tu32 pg_mask_1;\n\tu32 auto_wake_lvl;\n\tu32 auto_wake_lvl_mask;\n\tu32 wake_delay;\n\tu32 pwr_det_val;\n\tu32 ddr_pwr;\n\tu32 usb_debounce_del;\n\tu32 usb_a0;\n\tu32 crypto_op;\n\tu32 pllp_wb0_override;\n\tu32 scratch24;\n\tu32 scratch25;\n\tu32 scratch26;\n\tu32 scratch27;\n\tu32 scratch28;\n\tu32 scratch29;\n\tu32 scratch30;\n\tu32 scratch31;\n\tu32 scratch32;\n\tu32 scratch33;\n\tu32 scratch34;\n\tu32 scratch35;\n\tu32 scratch36;\n\tu32 scratch37;\n\tu32 scratch38;\n\tu32 scratch39;\n\tu32 scratch40;\n\tu32 scratch41;\n\tu32 scratch42;\n\tu32 bondout_mirror[3];\n\tu32 sys_33v_en;\n\tu32 bondout_mirror_access;\n\tu32 gate;\n\tu32 wake2_mask;\n\tu32 wake2_lvl;\n\tu32 wake2_status;\n\tu32 sw_wake2_status;\n\tu32 auto_wake2_lvl_mask;\n\tu32 pg_mask_2;\n\tu32 pg_mask_ce1;\n\tu32 pg_mask_ce2;\n\tu32 pg_mask_ce3;\n\tu32 pwrgate_timer_ce[7];\n\tu32 pcx_edpd_cntrl;\n\tu32 osc_edpd_over;\n\tu32 clk_out_cntrl;\n\tu32 sata_pwrgt;\n\tu32 sensor_ctrl;\n\tu32 rst_status;\n\tu32 io_dpd_req;\n\tu32 io_dpd_status;\n\tu32 io_dpd2_req;\n\tu32 io_dpd2_status;\n\tu32 sel_dpd_tim;\n\tu32 vddp_sel;\n\tu32 ddr_cfg;\n\tu32 e_no_vttgen;\n\tu8 _rsv0[4];\n\tu32 pllm_wb0_override_freq;\n\tu32 test_pwrgate;\n\tu32 pwrgate_timer_mult;\n\tu32 dis_sel_dpd;\n\tu32 utmip_uhsic_triggers;\n\tu32 utmip_uhsic_saved_state;\n\tu32 utmip_pad_cfg;\n\tu32 utmip_term_pad_cfg;\n\tu32 utmip_uhsic_sleep_cfg;\n\tu32 utmip_uhsic_sleepwalk_cfg;\n\tu32 utmip_sleepwalk_p[3];\n\tu32 uhsic_sleepwalk_p0;\n\tu32 utmip_uhsic_status;\n\tu32 utmip_uhsic_fake;\n\tu32 bondout_mirror3[5 - 3];\n\tu32 secure_scratch6;\n\tu32 secure_scratch7;\n\tu32 scratch43;\n\tu32 scratch44;\n\tu32 scratch45;\n\tu32 scratch46;\n\tu32 scratch47;\n\tu32 scratch48;\n\tu32 scratch49;\n\tu32 scratch50;\n\tu32 scratch51;\n\tu32 scratch52;\n\tu32 scratch53;\n\tu32 scratch54;\n\tu32 scratch55;\n\tu32 scratch0_eco;\n\tu32 por_dpd_ctrl;\n\tu32 scratch2_eco;\n\tu32 utmip_uhsic_line_wakeup;\n\tu32 utmip_bias_master_cntrl;\n\tu32 utmip_master_config;\n\tu32 td_pwrgate_inter_part_timer;\n\tu32 utmip_uhsic2_triggers;\n\tu32 utmip_uhsic2_saved_state;\n\tu32 utmip_uhsic2_sleep_cfg;\n\tu32 utmip_uhsic2_sleepwalk_cfg;\n\tu32 uhsic2_sleepwalk_p1;\n\tu32 utmip_uhsic2_status;\n\tu32 utmip_uhsic2_fake;\n\tu32 utmip_uhsic2_line_wakeup;\n\tu32 utmip_master2_config;\n\tu32 utmip_uhsic_rpd_cfg;\n\tu32 pg_mask_ce0;\n\tu32 pg_mask3[5 - 3];\n\tu32 pllm_wb0_override2;\n\tu32 tsc_mult;\n\tu32 cpu_vsense_override;\n\tu32 glb_amap_cfg;\n\tu32 sticky_bits;\n\tu32 sec_disable2;\n\tu32 weak_bias;\n\tu32 reg_short;\n\tu32 pg_mask_andor;\n\tu8 _rsv1[0x2c];\n\tu32 secure_scratch8;\t/* offset 0x300 */\n\tu32 secure_scratch9;\n\tu32 secure_scratch10;\n\tu32 secure_scratch11;\n\tu32 secure_scratch12;\n\tu32 secure_scratch13;\n\tu32 secure_scratch14;\n\tu32 secure_scratch15;\n\tu32 secure_scratch16;\n\tu32 secure_scratch17;\n\tu32 secure_scratch18;\n\tu32 secure_scratch19;\n\tu32 secure_scratch20;\n\tu32 secure_scratch21;\n\tu32 secure_scratch22;\n\tu32 secure_scratch23;\n\tu32 secure_scratch24;\n\tu32 secure_scratch25;\n\tu32 secure_scratch26;\n\tu32 secure_scratch27;\n\tu32 secure_scratch28;\n\tu32 secure_scratch29;\n\tu32 secure_scratch30;\n\tu32 secure_scratch31;\n\tu32 secure_scratch32;\n\tu32 secure_scratch33;\n\tu32 secure_scratch34;\n\tu32 secure_scratch35;\n\tu32 secure_scratch36;\n\tu32 secure_scratch37;\n\tu32 secure_scratch38;\n\tu32 secure_scratch39;\n\tu32 secure_scratch40;\n\tu32 secure_scratch41;\n\tu32 secure_scratch42;\n\tu32 secure_scratch43;\n\tu32 secure_scratch44;\n\tu32 secure_scratch45;\n\tu32 secure_scratch46;\n\tu32 secure_scratch47;\n\tu32 secure_scratch48;\n\tu32 secure_scratch49;\n\tu32 secure_scratch50;\n\tu32 secure_scratch51;\n\tu32 secure_scratch52;\n\tu32 secure_scratch53;\n\tu32 secure_scratch54;\n\tu32 secure_scratch55;\n\tu32 secure_scratch56;\n\tu32 secure_scratch57;\n\tu32 secure_scratch58;\n\tu32 secure_scratch59;\n\tu32 secure_scratch60;\n\tu32 secure_scratch61;\n\tu32 secure_scratch62;\n\tu32 secure_scratch63;\n\tu32 secure_scratch64;\n\tu32 secure_scratch65;\n\tu32 secure_scratch66;\n\tu32 secure_scratch67;\n\tu32 secure_scratch68;\n\tu32 secure_scratch69;\n\tu32 secure_scratch70;\n\tu32 secure_scratch71;\n\tu32 secure_scratch72;\n\tu32 secure_scratch73;\n\tu32 secure_scratch74;\n\tu32 secure_scratch75;\n\tu32 secure_scratch76;\n\tu32 secure_scratch77;\n\tu32 secure_scratch78;\n\tu32 secure_scratch79;\n\tu32 _rsv0x420[8];\n\tu32 cntrl2;\t\t\t/* 0x440 */\n\tu32 _rsv0x444[2];\n\tu32 event_counter;\t/* 0x44C */\n\tu32 fuse_control;\n\tu32 scratch1_eco;\n\tu32 _rsv0x458[1];\n\tu32 io_dpd3_req;\t/* 0x45C */\n\tu32 io_dpd3_status;\n\tu32 io_dpd4_req;\n\tu32 io_dpd4_status;\n\tu32 _rsv0x46C[30];\n\tu32 ddr_cntrl;\t\t/* 0x4E4 */\n\tu32 _rsv0x4E8[70];\n\tu32 scratch56;\t\t/* 0x600 */\n\tu32 scratch57;\n\tu32 scratch58;\n\tu32 scratch59;\n\tu32 scratch60;\n\tu32 scratch61;\n\tu32 scratch62;\n\tu32 scratch63;\n\tu32 scratch64;\n\tu32 scratch65;\n\tu32 scratch66;\n\tu32 scratch67;\n\tu32 scratch68;\n\tu32 scratch69;\n\tu32 scratch70;\n\tu32 scratch71;\n\tu32 scratch72;\n\tu32 scratch73;\n\tu32 scratch74;\n\tu32 scratch75;\n\tu32 scratch76;\n\tu32 scratch77;\n\tu32 scratch78;\n\tu32 scratch79;\n\tu32 scratch80;\n\tu32 scratch81;\n\tu32 scratch82;\n\tu32 scratch83;\n\tu32 scratch84;\n\tu32 scratch85;\n\tu32 scratch86;\n\tu32 scratch87;\n\tu32 scratch88;\n\tu32 scratch89;\n\tu32 scratch90;\n\tu32 scratch91;\n\tu32 scratch92;\n\tu32 scratch93;\n\tu32 scratch94;\n\tu32 scratch95;\n\tu32 scratch96;\n\tu32 scratch97;\n\tu32 scratch98;\n\tu32 scratch99;\n\tu32 scratch100;\n\tu32 scratch101;\n\tu32 scratch102;\n\tu32 scratch103;\n\tu32 scratch104;\n\tu32 scratch105;\n\tu32 scratch106;\n\tu32 scratch107;\n\tu32 scratch108;\n\tu32 scratch109;\n\tu32 scratch110;\n\tu32 scratch111;\n\tu32 scratch112;\n\tu32 scratch113;\n\tu32 scratch114;\n\tu32 scratch115;\n\tu32 scratch116;\n\tu32 scratch117;\n\tu32 scratch118;\n\tu32 scratch119;\n\tu32 scratch120;\t\t/* 0x700 */\n\tu32 scratch121;\n\tu32 scratch122;\n\tu32 scratch123;\n\tu32 scratch124;\n\tu32 scratch125;\n\tu32 scratch126;\n\tu32 scratch127;\n\tu32 scratch128;\n\tu32 scratch129;\n\tu32 scratch130;\n\tu32 scratch131;\n\tu32 scratch132;\n\tu32 scratch133;\n\tu32 scratch134;\n\tu32 scratch135;\n\tu32 scratch136;\n\tu32 scratch137;\n\tu32 scratch138;\n\tu32 scratch139;\n\tu32 scratch140;\n\tu32 scratch141;\n\tu32 scratch142;\n\tu32 scratch143;\n\tu32 scratch144;\n\tu32 scratch145;\n\tu32 scratch146;\n\tu32 scratch147;\n\tu32 scratch148;\n\tu32 scratch149;\n\tu32 scratch150;\n\tu32 scratch151;\n\tu32 scratch152;\n\tu32 scratch153;\n\tu32 scratch154;\n\tu32 scratch155;\n\tu32 scratch156;\n\tu32 scratch157;\n\tu32 scratch158;\n\tu32 scratch159;\n\tu32 scratch160;\n\tu32 scratch161;\n\tu32 scratch162;\n\tu32 scratch163;\n\tu32 scratch164;\n\tu32 scratch165;\n\tu32 scratch166;\n\tu32 scratch167;\n\tu32 scratch168;\n\tu32 scratch169;\n\tu32 scratch170;\n\tu32 scratch171;\n\tu32 scratch172;\n\tu32 scratch173;\n\tu32 scratch174;\n\tu32 scratch175;\n\tu32 scratch176;\n\tu32 scratch177;\n\tu32 scratch178;\n\tu32 scratch179;\n\tu32 scratch180;\n\tu32 scratch181;\n\tu32 scratch182;\n\tu32 scratch183;\n\tu32 scratch184;\n\tu32 scratch185;\n\tu32 scratch186;\n\tu32 scratch187;\n\tu32 scratch188;\n\tu32 scratch189;\n\tu32 scratch190;\n\tu32 scratch191;\n\tu32 scratch192;\n\tu32 scratch193;\n\tu32 scratch194;\n\tu32 scratch195;\n\tu32 scratch196;\n\tu32 scratch197;\n\tu32 scratch198;\n\tu32 scratch199;\n\tu32 scratch200;\n\tu32 scratch201;\n\tu32 scratch202;\n\tu32 scratch203;\n\tu32 scratch204;\n\tu32 scratch205;\n\tu32 scratch206;\n\tu32 scratch207;\n\tu32 scratch208;\n\tu32 scratch209;\n\tu32 scratch210;\n\tu32 scratch211;\n\tu32 scratch212;\n\tu32 scratch213;\n\tu32 scratch214;\n\tu32 scratch215;\n\tu32 scratch216;\n\tu32 scratch217;\n\tu32 scratch218;\n\tu32 scratch219;\n\tu32 scratch220;\n\tu32 scratch221;\n\tu32 scratch222;\n\tu32 scratch223;\n\tu32 scratch224;\n\tu32 scratch225;\n\tu32 scratch226;\n\tu32 scratch227;\n\tu32 scratch228;\n\tu32 scratch229;\n\tu32 scratch230;\n\tu32 scratch231;\n\tu32 scratch232;\n\tu32 scratch233;\n\tu32 scratch234;\n\tu32 scratch235;\n\tu32 scratch236;\n\tu32 scratch237;\n\tu32 scratch238;\n\tu32 scratch239;\n\tu32 scratch240;\n\tu32 scratch241;\n\tu32 scratch242;\n\tu32 scratch243;\n\tu32 scratch244;\n\tu32 scratch245;\n\tu32 scratch246;\n\tu32 scratch247;\n\tu32 scratch248;\n\tu32 scratch249;\n\tu32 scratch250;\n\tu32 scratch251;\n\tu32 scratch252;\n\tu32 scratch253;\n\tu32 scratch254;\n\tu32 scratch255;\n\tu32 scratch256;\n\tu32 scratch257;\n\tu32 scratch258;\n\tu32 scratch259;\n\tu32 scratch260;\n\tu32 scratch261;\n\tu32 scratch262;\n\tu32 scratch263;\n\tu32 scratch264;\n\tu32 scratch265;\n\tu32 scratch266;\n\tu32 scratch267;\n\tu32 scratch268;\n\tu32 scratch269;\n\tu32 scratch270;\n\tu32 scratch271;\n\tu32 scratch272;\n\tu32 scratch273;\n\tu32 scratch274;\n\tu32 scratch275;\n\tu32 scratch276;\n\tu32 scratch277;\n\tu32 scratch278;\n\tu32 scratch279;\n\tu32 scratch280;\n\tu32 scratch281;\n\tu32 scratch282;\n\tu32 scratch283;\n\tu32 scratch284;\n\tu32 scratch285;\n\tu32 scratch286;\n\tu32 scratch287;\n\tu32 scratch288;\n\tu32 scratch289;\n\tu32 scratch290;\n\tu32 scratch291;\n\tu32 scratch292;\n\tu32 scratch293;\n\tu32 scratch294;\n\tu32 scratch295;\n\tu32 scratch296;\n\tu32 scratch297;\n\tu32 scratch298;\n\tu32 scratch299;\t\t\t/* 0x9CC */\n\tu32 _rsv0x9D0[50];\n\tu32 secure_scratch80;\t/* 0xa98 */\n\tu32 secure_scratch81;\n\tu32 secure_scratch82;\n\tu32 secure_scratch83;\n\tu32 secure_scratch84;\n\tu32 secure_scratch85;\n\tu32 secure_scratch86;\n\tu32 secure_scratch87;\n\tu32 secure_scratch88;\n\tu32 secure_scratch89;\n\tu32 secure_scratch90;\n\tu32 secure_scratch91;\n\tu32 secure_scratch92;\n\tu32 secure_scratch93;\n\tu32 secure_scratch94;\n\tu32 secure_scratch95;\n\tu32 secure_scratch96;\n\tu32 secure_scratch97;\n\tu32 secure_scratch98;\n\tu32 secure_scratch99;\n\tu32 secure_scratch100;\n\tu32 secure_scratch101;\n\tu32 secure_scratch102;\n\tu32 secure_scratch103;\n\tu32 secure_scratch104;\n\tu32 secure_scratch105;\n\tu32 secure_scratch106;\n\tu32 secure_scratch107;\n\tu32 secure_scratch108;\n\tu32 secure_scratch109;\n\tu32 secure_scratch110;\n\tu32 secure_scratch111;\n\tu32 secure_scratch112;\n\tu32 secure_scratch113;\n\tu32 secure_scratch114;\n\tu32 secure_scratch115;\n\tu32 secure_scratch116;\n\tu32 secure_scratch117;\n\tu32 secure_scratch118;\n\tu32 secure_scratch119;\n};\n\n#endif\t/* _TEGRA210_PMC_H_ */\n"
  },
  {
    "path": "argon-first-stage/include/soc/smmu.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"utils/types.h\"\n\n#define SMMU_HEAP_ADDR 0xA0000000\n\n#define MC_INTSTATUS                 0x0\n#define MC_INTMASK                   0x4\n#define MC_ERR_STATUS                0x8\n#define MC_ERR_ADR                   0xc\n#define MC_SMMU_CONFIG               0x10\n#define MC_SMMU_TLB_CONFIG           0x14\n#define MC_SMMU_PTC_CONFIG           0x18\n#define MC_SMMU_PTB_ASID             0x1c\n#define MC_SMMU_PTB_DATA             0x20\n#define MC_SMMU_TLB_FLUSH            0x30\n#define MC_SMMU_PTC_FLUSH            0x34\n#define MC_SMMU_ASID_SECURITY        0x38\n#define MC_SMMU_TSEC_ASID            0x294\n#define MC_SMMU_TRANSLATION_ENABLE_0 0x228\n#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c\n#define MC_SMMU_TRANSLATION_ENABLE_2 0x230\n#define MC_SMMU_TRANSLATION_ENABLE_3 0x234\n#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98\n\n#define SMMU_PDE_NEXT_SHIFT 28\n#define MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT 29\n#define MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT  30\n#define MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT  31\n#define SMMU_PAGE_SHIFT 12\n#define SMMU_PAGE_SIZE  (1 << SMMU_PAGE_SHIFT)\n#define SMMU_PDIR_COUNT 1024\n#define SMMU_PDIR_SIZE  (sizeof(u32) * SMMU_PDIR_COUNT)\n#define SMMU_PTBL_COUNT 1024\n#define SMMU_PTBL_SIZE  (sizeof(u32) * SMMU_PTBL_COUNT)\n#define SMMU_PDIR_SHIFT 12\n#define SMMU_PDE_SHIFT  12\n#define SMMU_PTE_SHIFT  12\n#define SMMU_PFN_MASK   0x000FFFFF\n#define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12)\n#define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22)\n#define SMMU_PDN_TO_ADDR(addr) ((pdn) << 22)\n#define _READABLE  (1 << MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT)\n#define _WRITABLE  (1 << MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT)\n#define _NONSECURE (1 << MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT)\n#define _PDE_NEXT  (1 << SMMU_PDE_NEXT_SHIFT)\n#define _MASK_ATTR (_READABLE | _WRITABLE | _NONSECURE)\n#define _PDIR_ATTR (_READABLE | _WRITABLE | _NONSECURE)\n#define _PDE_ATTR  (_READABLE | _WRITABLE | _NONSECURE)\n#define _PDE_VACANT(pdn) (((pdn) << 10) | _PDE_ATTR)\n#define _PTE_ATTR  (_READABLE | _WRITABLE | _NONSECURE)\n#define _PTE_VACANT(addr) (((addr) >> SMMU_PAGE_SHIFT) | _PTE_ATTR)\n#define SMMU_MK_PDIR(page, attr) (((page) >> SMMU_PDIR_SHIFT) | (attr))\n#define SMMU_MK_PDE(page, attr)  (((page) >> SMMU_PDE_SHIFT) | (attr))\n\nvoid *page_alloc(u32 num);\nu32 *smmu_alloc_pdir();\nvoid smmu_flush_regs();\nvoid smmu_flush_all();\nvoid smmu_init(u32 secmon_base);\nvoid smmu_enable();\nbool smmu_is_used();\nvoid smmu_exit();\nu32 *smmu_init_domain4(u32 dev_base, u32 asid);\nu32 *smmu_get_pte(u32 *pdir, u32 iova);\nvoid smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr);\nu32 *smmu_init_for_tsec();\nvoid smmu_deinit_for_tsec();\n"
  },
  {
    "path": "argon-first-stage/include/soc/t210.h",
    "content": "/*\n* Copyright (c) 2018 naehrwert\n*\n* This program is free software; you can redistribute it and/or modify it\n* under the terms and conditions of the GNU General Public License,\n* version 2, as published by the Free Software Foundation.\n*\n* This program is distributed in the hope it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _T210_H_\n#define _T210_H_\n\n#include \"utils/types.h\"\n\n#define BOOTROM_BASE 0x100000\n#define HOST1X_BASE 0x50000000\n#define BPMP_CACHE_BASE 0x50040000\n#define DISPLAY_A_BASE 0x54200000\n#define DSI_BASE 0x54300000\n#define VIC_BASE 0x54340000\n#define TSEC_BASE 0x54500000\n#define SOR1_BASE 0x54580000\n#define TMR_BASE 0x60005000\n#define CLOCK_BASE 0x60006000\n#define FLOW_CTLR_BASE 0x60007000\n#define SYSREG_BASE 0x6000C000\n#define SB_BASE (SYSREG_BASE + 0x200)\n#define GPIO_BASE 0x6000D000\n#define GPIO_1_BASE (GPIO_BASE)\n#define GPIO_2_BASE (GPIO_BASE + 0x100)\n#define GPIO_3_BASE (GPIO_BASE + 0x200)\n#define GPIO_4_BASE (GPIO_BASE + 0x300)\n#define GPIO_5_BASE (GPIO_BASE + 0x400)\n#define GPIO_6_BASE (GPIO_BASE + 0x500)\n#define GPIO_7_BASE (GPIO_BASE + 0x600)\n#define GPIO_8_BASE (GPIO_BASE + 0x700)\n#define EXCP_VEC_BASE 0x6000F000\n#define IPATCH_BASE 0x6001DC00\n#define APB_MISC_BASE 0x70000000\n#define PINMUX_AUX_BASE 0x70003000\n#define UART_BASE 0x70006000\n#define PWM_BASE 0x7000A000\n#define RTC_BASE 0x7000E000\n#define PMC_BASE 0x7000E400\n#define SYSCTR0_BASE 0x700F0000\n#define FUSE_BASE 0x7000F800\n#define KFUSE_BASE 0x7000FC00\n#define SE_BASE 0x70012000\n#define MC_BASE 0x70019000\n#define EMC_BASE 0x7001B000\n#define MIPI_CAL_BASE 0x700E3000\n#define CL_DVFS_BASE 0x70110000\n#define I2S_BASE 0x702D1000\n#define TZRAM_BASE 0x7C010000\n\n#define _REG(base, off) *(vu32 *)((base) + (off))\n\n#define HOST1X(off) _REG(HOST1X_BASE, off)\n#define BPMP_CACHE_CTRL(off) _REG(BPMP_CACHE_BASE, off)\n#define DISPLAY_A(off) _REG(DISPLAY_A_BASE, off)\n#define DSI(off) _REG(DSI_BASE, off)\n#define VIC(off) _REG(VIC_BASE, off)\n#define TSEC(off) _REG(TSEC_BASE, off)\n#define SOR1(off) _REG(SOR1_BASE, off)\n#define TMR(off) _REG(TMR_BASE, off)\n#define CLOCK(off) _REG(CLOCK_BASE, off)\n#define FLOW_CTLR(off) _REG(FLOW_CTLR_BASE, off)\n#define SYSREG(off) _REG(SYSREG_BASE, off)\n#define SB(off) _REG(SB_BASE, off)\n#define GPIO(off) _REG(GPIO_BASE, off)\n#define GPIO_1(off) _REG(GPIO_1_BASE, off)\n#define GPIO_2(off) _REG(GPIO_2_BASE, off)\n#define GPIO_3(off) _REG(GPIO_3_BASE, off)\n#define GPIO_4(off) _REG(GPIO_4_BASE, off)\n#define GPIO_5(off) _REG(GPIO_5_BASE, off)\n#define GPIO_6(off) _REG(GPIO_6_BASE, off)\n#define GPIO_7(off) _REG(GPIO_7_BASE, off)\n#define GPIO_8(off) _REG(GPIO_8_BASE, off)\n#define EXCP_VEC(off) _REG(EXCP_VEC_BASE, off)\n#define APB_MISC(off) _REG(APB_MISC_BASE, off)\n#define PINMUX_AUX(off) _REG(PINMUX_AUX_BASE, off)\n#define PWM(off) _REG(PWM_BASE, off)\n#define RTC(off) _REG(RTC_BASE, off)\n#define PMC(off) _REG(PMC_BASE, off)\n#define SYSCTR0(off) _REG(SYSCTR0_BASE, off)\n#define FUSE(off) _REG(FUSE_BASE, off)\n#define KFUSE(off) _REG(KFUSE_BASE, off)\n#define SE(off) _REG(SE_BASE, off)\n#define MC(off) _REG(MC_BASE, off)\n#define EMC(off) _REG(EMC_BASE, off)\n#define MIPI_CAL(off) _REG(MIPI_CAL_BASE, off)\n#define I2S(off) _REG(I2S_BASE, off)\n#define CL_DVFS(off) _REG(CL_DVFS_BASE, off)\n#define TEST_REG(off) _REG(0x0, off)\n\n/*! EVP registers. */\n#define EVP_CPU_RESET_VECTOR 0x100\n\n/*! Misc registers. */\n#define APB_MISC_PP_STRAPPING_OPT_A 0x08\n#define APB_MISC_PP_PINMUX_GLOBAL 0x40\n#define APB_MISC_GP_LCD_BL_PWM_CFGPADCTRL 0xA34\n#define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL 0xA98\n#define APB_MISC_GP_EMMC4_PAD_CFGPADCTRL 0xAB4\n#define APB_MISC_GP_WIFI_EN_CFGPADCTRL 0xB64\n#define APB_MISC_GP_WIFI_RST_CFGPADCTRL 0xB68\n\n/*! System registers. */\n#define AHB_ARBITRATION_XBAR_CTRL 0xE0\n#define AHB_AHB_SPARE_REG 0x110\n\n/*! Secure boot registers. */\n#define SB_CSR 0x0\n#define SB_AA64_RESET_LOW  0x30\n#define SB_AA64_RESET_HIGH 0x34\n\n/*! SOR registers. */\n#define SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB   0x1E8\n#define SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB 0x21C\n#define SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB   0x208\n#define SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB   0x20C\n\n/*! RTC registers. */\n#define APBDEV_RTC_SECONDS        0x8\n#define APBDEV_RTC_SHADOW_SECONDS 0xC\n#define APBDEV_RTC_MILLI_SECONDS  0x10\n\n/*! SYSCTR0 registers. */\n#define SYSCTR0_CNTFID0     0x20\n#define SYSCTR0_CNTCR       0x00\n#define SYSCTR0_COUNTERID0  0xFE0\n#define SYSCTR0_COUNTERID1  0xFE4\n#define SYSCTR0_COUNTERID2  0xFE8\n#define SYSCTR0_COUNTERID3  0xFEC\n#define SYSCTR0_COUNTERID4  0xFD0\n#define SYSCTR0_COUNTERID5  0xFD4\n#define SYSCTR0_COUNTERID6  0xFD8\n#define SYSCTR0_COUNTERID7  0xFDC\n#define SYSCTR0_COUNTERID8  0xFF0\n#define SYSCTR0_COUNTERID9  0xFF4\n#define SYSCTR0_COUNTERID10 0xFF8 \n#define SYSCTR0_COUNTERID11 0xFFC\n\n/*! TMR registers. */\n#define TIMERUS_CNTR_1US          (0x10 + 0x0)\n#define TIMERUS_USEC_CFG          (0x10 + 0x4)\n#define TIMER_TMR9_TMR_PTV        0x80\n#define  TIMER_EN     (1 << 31)\n#define  TIMER_PER_EN (1 << 30)\n#define TIMER_WDT4_CONFIG         (0x100 + 0x80)\n#define  TIMER_SRC(TMR) (TMR & 0xF)\n#define  TIMER_PER(PER) ((PER & 0xFF) << 4)\n#define  TIMER_SYSRESET_EN (1 << 14)\n#define  TIMER_PMCRESET_EN (1 << 15)\n#define TIMER_WDT4_COMMAND        (0x108 + 0x80)\n#define  TIMER_START_CNT   (1 << 0)\n#define  TIMER_CNT_DISABLE (1 << 1)\n#define TIMER_WDT4_UNLOCK_PATTERN (0x10C + 0x80)\n#define  TIMER_MAGIC_PTRN 0xC45A\n\n/*! I2S registers. */\n#define I2S1_CG   0x88\n#define I2S1_CTRL 0xA0\n#define I2S2_CG   0x188\n#define I2S2_CTRL 0x1A0\n#define I2S3_CG   0x288\n#define I2S3_CTRL 0x2A0\n#define I2S4_CG   0x388\n#define I2S4_CTRL 0x3A0\n#define I2S5_CG   0x488\n#define I2S5_CTRL 0x4A0\n#define  I2S_CG_SLCG_ENABLE (1 << 0)\n#define  I2S_CTRL_MASTER_EN (1 << 10)\n\n/*! PWM registers. */\n#define PWM_CONTROLLER_PWM_CSR_0 0x00\n#define PWM_CONTROLLER_PWM_CSR_1 0x10\n\n/*! Special registers. */\n#define EMC_SCRATCH0 0x324\n#define  EMC_HEKA_UPD (1 << 30)\n#define  EMC_SEPT_RUN (1 << 31)\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/soc/uart.h",
    "content": "/*\n* Copyright (c) 2018 naehrwert\n*\n* This program is free software; you can redistribute it and/or modify it\n* under the terms and conditions of the GNU General Public License,\n* version 2, as published by the Free Software Foundation.\n*\n* This program is distributed in the hope it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _UART_H_\n#define _UART_H_\n\n#include \"utils/types.h\"\n\n#define UART_A 0\n#define UART_B 1\n#define UART_C 2\n//TODO: define clock inits for those.\n/*#define UART_D 3\n#define UART_E 4*/\n\n#define BAUD_115200 115200\n\n#define UART_TX_IDLE 0x1\n#define UART_RX_IDLE 0x2\n\n#define UART_TX_FIFO_FULL 0x100\n#define UART_RX_FIFO_EMPTY 0x200\n\n#define UART_LCR_DLAB 0x80\n#define UART_LCR_WORD_LENGTH_8 0x3\n#define UART_LSR_RDR 0x1\n#define UART_LSR_THRE 0x20\n#define UART_LSR_TMTY 0x40\n#define UART_IIR_FCR_TX_CLR 0x4\n#define UART_IIR_FCR_RX_CLR 0x2\n#define UART_IIR_FCR_EN_FIFO 0x1\n\ntypedef struct _uart_t\n{\n\t/* 0x00 */ vu32 UART_THR_DLAB;\n\t/* 0x04 */ vu32 UART_IER_DLAB;\n\t/* 0x08 */ vu32 UART_IIR_FCR;\n\t/* 0x0C */ vu32 UART_LCR;\n\t/* 0x10 */ vu32 UART_MCR;\n\t/* 0x14 */ vu32 UART_LSR;\n\t/* 0x18 */ vu32 UART_MSR;\n\t/* 0x1C */ vu32 UART_SPR;\n\t/* 0x20 */ vu32 UART_IRDA_CSR;\n\t/* 0x24 */ vu32 UART_RX_FIFO_CFG;\n\t/* 0x28 */ vu32 UART_MIE;\n\t/* 0x2C */ vu32 UART_VENDOR_STATUS;\n\t/* 0x30 */ u8 _pad_30[0xC];\n\t/* 0x3C */ vu32 UART_ASR;\n} uart_t;\n\nvoid uart_init(u32 idx, u32 baud);\nvoid uart_wait_idle(u32 idx, u32 which);\nvoid uart_send(u32 idx, u8 *buf, u32 len);\nvoid uart_recv(u32 idx, u8 *buf, u32 len);\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/storage/mmc.h",
    "content": "/*\n * Header for MultiMediaCard (MMC)\n *\n * Copyright 2002 Hewlett-Packard Company\n *\n * Use consistent with the GNU GPL is permitted,\n * provided that this copyright notice is\n * preserved in its entirety in all copies and derived works.\n *\n * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,\n * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS\n * FITNESS FOR ANY PARTICULAR PURPOSE.\n *\n * Many thanks to Alessandro Rubini and Jonathan Corbet!\n *\n * Based strongly on code by:\n *\n * Author: Yong-iL Joh <tolkien@mizi.com>\n *\n * Author:  Andrew Christian\n *          15 May 2002\n */\n\n#ifndef LINUX_MMC_MMC_H\n#define LINUX_MMC_MMC_H\n\n/* Standard MMC commands (4.1)           type  argument     response */\n/* class 1 */\n#define MMC_GO_IDLE_STATE         0   /* bc                          */\n#define MMC_SEND_OP_COND          1   /* bcr  [31:0] OCR         R3  */\n#define MMC_ALL_SEND_CID          2   /* bcr                     R2  */\n#define MMC_SET_RELATIVE_ADDR     3   /* ac   [31:16] RCA        R1  */\n#define MMC_SET_DSR               4   /* bc   [31:16] RCA            */\n#define MMC_SLEEP_AWAKE\t\t  5   /* ac   [31:16] RCA 15:flg R1b */\n#define MMC_SWITCH                6   /* ac   [31:0] See below   R1b */\n#define MMC_SELECT_CARD           7   /* ac   [31:16] RCA        R1  */\n#define MMC_SEND_EXT_CSD          8   /* adtc                    R1  */\n#define MMC_SEND_CSD              9   /* ac   [31:16] RCA        R2  */\n#define MMC_SEND_CID             10   /* ac   [31:16] RCA        R2  */\n#define MMC_READ_DAT_UNTIL_STOP  11   /* adtc [31:0] dadr        R1  */\n#define MMC_STOP_TRANSMISSION    12   /* ac                      R1b */\n#define MMC_SEND_STATUS          13   /* ac   [31:16] RCA        R1  */\n#define MMC_BUS_TEST_R           14   /* adtc                    R1  */\n#define MMC_GO_INACTIVE_STATE    15   /* ac   [31:16] RCA            */\n#define MMC_BUS_TEST_W           19   /* adtc                    R1  */\n#define MMC_SPI_READ_OCR         58   /* spi                  spi_R3 */\n#define MMC_SPI_CRC_ON_OFF       59   /* spi  [0:0] flag      spi_R1 */\n\n/* class 2 */\n#define MMC_SET_BLOCKLEN         16   /* ac   [31:0] block len   R1  */\n#define MMC_READ_SINGLE_BLOCK    17   /* adtc [31:0] data addr   R1  */\n#define MMC_READ_MULTIPLE_BLOCK  18   /* adtc [31:0] data addr   R1  */\n#define MMC_SEND_TUNING_BLOCK    19   /* adtc                    R1  */\n#define MMC_SEND_TUNING_BLOCK_HS200\t21\t/* adtc R1  */\n\n/* class 3 */\n#define MMC_WRITE_DAT_UNTIL_STOP 20   /* adtc [31:0] data addr   R1  */\n\n/* class 4 */\n#define MMC_SET_BLOCK_COUNT      23   /* adtc [31:0] data addr   R1  */\n#define MMC_WRITE_BLOCK          24   /* adtc [31:0] data addr   R1  */\n#define MMC_WRITE_MULTIPLE_BLOCK 25   /* adtc                    R1  */\n#define MMC_PROGRAM_CID          26   /* adtc                    R1  */\n#define MMC_PROGRAM_CSD          27   /* adtc                    R1  */\n\n/* class 6 */\n#define MMC_SET_WRITE_PROT       28   /* ac   [31:0] data addr   R1b */\n#define MMC_CLR_WRITE_PROT       29   /* ac   [31:0] data addr   R1b */\n#define MMC_SEND_WRITE_PROT      30   /* adtc [31:0] wpdata addr R1  */\n\n/* class 5 */\n#define MMC_ERASE_GROUP_START    35   /* ac   [31:0] data addr   R1  */\n#define MMC_ERASE_GROUP_END      36   /* ac   [31:0] data addr   R1  */\n#define MMC_ERASE                38   /* ac                      R1b */\n\n/* class 9 */\n#define MMC_FAST_IO              39   /* ac   <Complex>          R4  */\n#define MMC_GO_IRQ_STATE         40   /* bcr                     R5  */\n\n/* class 7 */\n#define MMC_LOCK_UNLOCK          42   /* adtc                    R1b */\n\n/* class 8 */\n#define MMC_APP_CMD              55   /* ac   [31:16] RCA        R1  */\n#define MMC_GEN_CMD              56   /* adtc [0] RD/WR          R1  */\n\n/* class 11 */\n#define MMC_QUE_TASK_PARAMS      44   /* ac   [20:16] task id    R1  */\n#define MMC_QUE_TASK_ADDR        45   /* ac   [31:0] data addr   R1  */\n#define MMC_EXECUTE_READ_TASK    46   /* adtc [20:16] task id    R1  */\n#define MMC_EXECUTE_WRITE_TASK   47   /* adtc [20:16] task id    R1  */\n#define MMC_CMDQ_TASK_MGMT       48   /* ac   [20:16] task id    R1b */\n\n/*\n* MMC_SWITCH argument format:\n*\n*\t[31:26] Always 0\n*\t[25:24] Access Mode\n*\t[23:16] Location of target Byte in EXT_CSD\n*\t[15:08] Value Byte\n*\t[07:03] Always 0\n*\t[02:00] Command Set\n*/\n\n/*\nMMC status in R1, for native mode (SPI bits are different)\nType\ne : error bit\ns : status bit\nr : detected and set for the actual command response\nx : detected and set during command execution. the host must poll\nthe card by sending status command in order to read these bits.\nClear condition\na : according to the card state\nb : always related to the previous command. Reception of\na valid command will clear it (with a delay of one command)\nc : clear by read\n*/\n\n#define R1_OUT_OF_RANGE\t\t(1 << 31)\t/* er, c */\n#define R1_ADDRESS_ERROR\t(1 << 30)\t/* erx, c */\n#define R1_BLOCK_LEN_ERROR\t(1 << 29)\t/* er, c */\n#define R1_ERASE_SEQ_ERROR      (1 << 28)\t/* er, c */\n#define R1_ERASE_PARAM\t\t(1 << 27)\t/* ex, c */\n#define R1_WP_VIOLATION\t\t(1 << 26)\t/* erx, c */\n#define R1_CARD_IS_LOCKED\t(1 << 25)\t/* sx, a */\n#define R1_LOCK_UNLOCK_FAILED\t(1 << 24)\t/* erx, c */\n#define R1_COM_CRC_ERROR\t(1 << 23)\t/* er, b */\n#define R1_ILLEGAL_COMMAND\t(1 << 22)\t/* er, b */\n#define R1_CARD_ECC_FAILED\t(1 << 21)\t/* ex, c */\n#define R1_CC_ERROR\t\t(1 << 20)\t/* erx, c */\n#define R1_ERROR\t\t(1 << 19)\t/* erx, c */\n#define R1_UNDERRUN\t\t(1 << 18)\t/* ex, c */\n#define R1_OVERRUN\t\t(1 << 17)\t/* ex, c */\n#define R1_CID_CSD_OVERWRITE\t(1 << 16)\t/* erx, c, CID/CSD overwrite */\n#define R1_WP_ERASE_SKIP\t(1 << 15)\t/* sx, c */\n#define R1_CARD_ECC_DISABLED\t(1 << 14)\t/* sx, a */\n#define R1_ERASE_RESET\t\t(1 << 13)\t/* sr, c */\n#define R1_STATUS(x)            (x & 0xFFFFE000)\n#define R1_CURRENT_STATE(x)\t((x & 0x00001E00) >> 9)\t/* sx, b (4 bits) */\n#define R1_READY_FOR_DATA\t(1 << 8)\t/* sx, a */\n#define R1_SWITCH_ERROR\t\t(1 << 7)\t/* sx, c */\n#define R1_EXCEPTION_EVENT\t(1 << 6)\t/* sr, a */\n#define R1_APP_CMD\t\t(1 << 5)\t/* sr, c */\n\n#define R1_STATE_IDLE\t0\n#define R1_STATE_READY\t1\n#define R1_STATE_IDENT\t2\n#define R1_STATE_STBY\t3\n#define R1_STATE_TRAN\t4\n#define R1_STATE_DATA\t5\n#define R1_STATE_RCV\t6\n#define R1_STATE_PRG\t7\n#define R1_STATE_DIS\t8\n\n/*\n* MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS\n* R1 is the low order byte; R2 is the next highest byte, when present.\n*/\n#define R1_SPI_IDLE\t\t(1 << 0)\n#define R1_SPI_ERASE_RESET\t(1 << 1)\n#define R1_SPI_ILLEGAL_COMMAND\t(1 << 2)\n#define R1_SPI_COM_CRC\t\t(1 << 3)\n#define R1_SPI_ERASE_SEQ\t(1 << 4)\n#define R1_SPI_ADDRESS\t\t(1 << 5)\n#define R1_SPI_PARAMETER\t(1 << 6)\n/* R1 bit 7 is always zero */\n#define R2_SPI_CARD_LOCKED\t(1 << 8)\n#define R2_SPI_WP_ERASE_SKIP\t(1 << 9)\t/* or lock/unlock fail */\n#define R2_SPI_LOCK_UNLOCK_FAIL\tR2_SPI_WP_ERASE_SKIP\n#define R2_SPI_ERROR\t\t(1 << 10)\n#define R2_SPI_CC_ERROR\t\t(1 << 11)\n#define R2_SPI_CARD_ECC_ERROR\t(1 << 12)\n#define R2_SPI_WP_VIOLATION\t(1 << 13)\n#define R2_SPI_ERASE_PARAM\t(1 << 14)\n#define R2_SPI_OUT_OF_RANGE\t(1 << 15)\t/* or CSD overwrite */\n#define R2_SPI_CSD_OVERWRITE\tR2_SPI_OUT_OF_RANGE\n\n/*\n* OCR bits are mostly in host.h\n*/\n#define MMC_CARD_BUSY\t0x80000000\t/* Card Power up status bit */\n\n/*\n* Card Command Classes (CCC)\n*/\n#define CCC_BASIC\t\t(1<<0)\t/* (0) Basic protocol functions */\n/* (CMD0,1,2,3,4,7,9,10,12,13,15) */\n/* (and for SPI, CMD58,59) */\n#define CCC_STREAM_READ\t\t(1<<1)\t/* (1) Stream read commands */\n/* (CMD11) */\n#define CCC_BLOCK_READ\t\t(1<<2)\t/* (2) Block read commands */\n/* (CMD16,17,18) */\n#define CCC_STREAM_WRITE\t(1<<3)\t/* (3) Stream write commands */\n/* (CMD20) */\n#define CCC_BLOCK_WRITE\t\t(1<<4)\t/* (4) Block write commands */\n/* (CMD16,24,25,26,27) */\n#define CCC_ERASE\t\t(1<<5)\t/* (5) Ability to erase blocks */\n/* (CMD32,33,34,35,36,37,38,39) */\n#define CCC_WRITE_PROT\t\t(1<<6)\t/* (6) Able to write protect blocks */\n/* (CMD28,29,30) */\n#define CCC_LOCK_CARD\t\t(1<<7)\t/* (7) Able to lock down card */\n/* (CMD16,CMD42) */\n#define CCC_APP_SPEC\t\t(1<<8)\t/* (8) Application specific */\n/* (CMD55,56,57,ACMD*) */\n#define CCC_IO_MODE\t\t(1<<9)\t/* (9) I/O mode */\n/* (CMD5,39,40,52,53) */\n#define CCC_SWITCH\t\t(1<<10)\t/* (10) High speed switch */\n/* (CMD6,34,35,36,37,50) */\n/* (11) Reserved */\n/* (CMD?) */\n\n/*\n* CSD field definitions\n*/\n\n#define CSD_STRUCT_VER_1_0  0           /* Valid for system specification 1.0 - 1.2 */\n#define CSD_STRUCT_VER_1_1  1           /* Valid for system specification 1.4 - 2.2 */\n#define CSD_STRUCT_VER_1_2  2           /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */\n#define CSD_STRUCT_EXT_CSD  3           /* Version is coded in CSD_STRUCTURE in EXT_CSD */\n\n#define CSD_SPEC_VER_0      0           /* Implements system specification 1.0 - 1.2 */\n#define CSD_SPEC_VER_1      1           /* Implements system specification 1.4 */\n#define CSD_SPEC_VER_2      2           /* Implements system specification 2.0 - 2.2 */\n#define CSD_SPEC_VER_3      3           /* Implements system specification 3.1 - 3.2 - 3.31 */\n#define CSD_SPEC_VER_4      4           /* Implements system specification 4.0 - 4.1 */\n\n/*\n* EXT_CSD fields\n*/\n\n#define EXT_CSD_CMDQ_MODE_EN\t\t15\t/* R/W */\n#define EXT_CSD_FLUSH_CACHE\t\t32      /* W */\n#define EXT_CSD_CACHE_CTRL\t\t33      /* R/W */\n#define EXT_CSD_POWER_OFF_NOTIFICATION\t34\t/* R/W */\n#define EXT_CSD_PACKED_FAILURE_INDEX\t35\t/* RO */\n#define EXT_CSD_PACKED_CMD_STATUS\t36\t/* RO */\n#define EXT_CSD_EXP_EVENTS_STATUS\t54\t/* RO, 2 bytes */\n#define EXT_CSD_EXP_EVENTS_CTRL\t\t56\t/* R/W, 2 bytes */\n#define EXT_CSD_DATA_SECTOR_SIZE\t61\t/* R */\n#define EXT_CSD_GP_SIZE_MULT\t\t143\t/* R/W */\n#define EXT_CSD_PARTITION_SETTING_COMPLETED 155\t/* R/W */\n#define EXT_CSD_PARTITION_ATTRIBUTE\t156\t/* R/W */\n#define EXT_CSD_PARTITION_SUPPORT\t160\t/* RO */\n#define EXT_CSD_HPI_MGMT\t\t161\t/* R/W */\n#define EXT_CSD_RST_N_FUNCTION\t\t162\t/* R/W */\n#define EXT_CSD_BKOPS_EN\t\t163\t/* R/W */\n#define EXT_CSD_BKOPS_START\t\t164\t/* W */\n#define EXT_CSD_SANITIZE_START\t\t165     /* W */\n#define EXT_CSD_WR_REL_PARAM\t\t166\t/* RO */\n#define EXT_CSD_RPMB_MULT\t\t168\t/* RO */\n#define EXT_CSD_FW_CONFIG\t\t169\t/* R/W */\n#define EXT_CSD_BOOT_WP\t\t\t173\t/* R/W */\n#define EXT_CSD_ERASE_GROUP_DEF\t\t175\t/* R/W */\n#define EXT_CSD_PART_CONFIG\t\t179\t/* R/W */\n#define EXT_CSD_ERASED_MEM_CONT\t\t181\t/* RO */\n#define EXT_CSD_BUS_WIDTH\t\t183\t/* R/W */\n#define EXT_CSD_STROBE_SUPPORT\t\t184\t/* RO */\n#define EXT_CSD_HS_TIMING\t\t185\t/* R/W */\n#define EXT_CSD_POWER_CLASS\t\t187\t/* R/W */\n#define EXT_CSD_REV\t\t\t192\t/* RO */\n#define EXT_CSD_STRUCTURE\t\t194\t/* RO */\n#define EXT_CSD_CARD_TYPE\t\t196\t/* RO */\n#define EXT_CSD_DRIVER_STRENGTH\t\t197\t/* RO */\n#define EXT_CSD_OUT_OF_INTERRUPT_TIME\t198\t/* RO */\n#define EXT_CSD_PART_SWITCH_TIME        199     /* RO */\n#define EXT_CSD_PWR_CL_52_195\t\t200\t/* RO */\n#define EXT_CSD_PWR_CL_26_195\t\t201\t/* RO */\n#define EXT_CSD_PWR_CL_52_360\t\t202\t/* RO */\n#define EXT_CSD_PWR_CL_26_360\t\t203\t/* RO */\n#define EXT_CSD_SEC_CNT\t\t\t212\t/* RO, 4 bytes */\n#define EXT_CSD_S_A_TIMEOUT\t\t217\t/* RO */\n#define EXT_CSD_REL_WR_SEC_C\t\t222\t/* RO */\n#define EXT_CSD_HC_WP_GRP_SIZE\t\t221\t/* RO */\n#define EXT_CSD_ERASE_TIMEOUT_MULT\t223\t/* RO */\n#define EXT_CSD_HC_ERASE_GRP_SIZE\t224\t/* RO */\n#define EXT_CSD_BOOT_MULT\t\t226\t/* RO */\n#define EXT_CSD_SEC_TRIM_MULT\t\t229\t/* RO */\n#define EXT_CSD_SEC_ERASE_MULT\t\t230\t/* RO */\n#define EXT_CSD_SEC_FEATURE_SUPPORT\t231\t/* RO */\n#define EXT_CSD_TRIM_MULT\t\t232\t/* RO */\n#define EXT_CSD_PWR_CL_200_195\t\t236\t/* RO */\n#define EXT_CSD_PWR_CL_200_360\t\t237\t/* RO */\n#define EXT_CSD_PWR_CL_DDR_52_195\t238\t/* RO */\n#define EXT_CSD_PWR_CL_DDR_52_360\t239\t/* RO */\n#define EXT_CSD_BKOPS_STATUS\t\t246\t/* RO */\n#define EXT_CSD_POWER_OFF_LONG_TIME\t247\t/* RO */\n#define EXT_CSD_GENERIC_CMD6_TIME\t248\t/* RO */\n#define EXT_CSD_CACHE_SIZE\t\t249\t/* RO, 4 bytes */\n#define EXT_CSD_PWR_CL_DDR_200_360\t253\t/* RO */\n#define EXT_CSD_FIRMWARE_VERSION\t254\t/* RO, 8 bytes */\n#define EXT_CSD_DEVICE_VERSION\t\t262\t/* RO, 2 bytes */\n#define EXT_CSD_PRE_EOL_INFO\t\t267\t/* RO */\n#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A\t268\t/* RO */\n#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B\t269\t/* RO */\n#define EXT_CSD_CMDQ_DEPTH\t\t307\t/* RO */\n#define EXT_CSD_CMDQ_SUPPORT\t\t308\t/* RO */\n#define EXT_CSD_SUPPORTED_MODE\t\t493\t/* RO */\n#define EXT_CSD_TAG_UNIT_SIZE\t\t498\t/* RO */\n#define EXT_CSD_DATA_TAG_SUPPORT\t499\t/* RO */\n#define EXT_CSD_MAX_PACKED_WRITES\t500\t/* RO */\n#define EXT_CSD_MAX_PACKED_READS\t501\t/* RO */\n#define EXT_CSD_BKOPS_SUPPORT\t\t502\t/* RO */\n#define EXT_CSD_HPI_FEATURES\t\t503\t/* RO */\n\n/*\n* EXT_CSD field definitions\n*/\n\n#define EXT_CSD_WR_REL_PARAM_EN\t\t(1<<2)\n\n#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS\t(0x40)\n#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS\t(0x10)\n#define EXT_CSD_BOOT_WP_B_PERM_WP_EN\t(0x04)\n#define EXT_CSD_BOOT_WP_B_PWR_WP_EN\t(0x01)\n\n#define EXT_CSD_PART_CONFIG_ACC_MASK\t(0x7)\n#define EXT_CSD_PART_CONFIG_ACC_BOOT0\t(0x1)\n#define EXT_CSD_PART_CONFIG_ACC_RPMB\t(0x3)\n#define EXT_CSD_PART_CONFIG_ACC_GP0\t(0x4)\n\n#define EXT_CSD_PART_SETTING_COMPLETED\t(0x1)\n#define EXT_CSD_PART_SUPPORT_PART_EN\t(0x1)\n\n#define EXT_CSD_CMD_SET_NORMAL\t\t(1<<0)\n#define EXT_CSD_CMD_SET_SECURE\t\t(1<<1)\n#define EXT_CSD_CMD_SET_CPSECURE\t(1<<2)\n\n#define EXT_CSD_CARD_TYPE_HS_26\t(1<<0)\t/* Card can run at 26MHz */\n#define EXT_CSD_CARD_TYPE_HS_52\t(1<<1)\t/* Card can run at 52MHz */\n#define EXT_CSD_CARD_TYPE_HS\t(EXT_CSD_CARD_TYPE_HS_26 | \\\n\t\t\t\t EXT_CSD_CARD_TYPE_HS_52)\n#define EXT_CSD_CARD_TYPE_DDR_1_8V  (1<<2)   /* Card can run at 52MHz */\n/* DDR mode @1.8V or 3V I/O */\n#define EXT_CSD_CARD_TYPE_DDR_1_2V  (1<<3)   /* Card can run at 52MHz */\n/* DDR mode @1.2V I/O */\n#define EXT_CSD_CARD_TYPE_DDR_52       (EXT_CSD_CARD_TYPE_DDR_1_8V  \\\n\t\t\t\t\t| EXT_CSD_CARD_TYPE_DDR_1_2V)\n#define EXT_CSD_CARD_TYPE_HS200_1_8V\t(1<<4)\t/* Card can run at 200MHz */\n#define EXT_CSD_CARD_TYPE_HS200_1_2V\t(1<<5)\t/* Card can run at 200MHz */\n/* SDR mode @1.2V I/O */\n#define EXT_CSD_CARD_TYPE_HS200\t\t(EXT_CSD_CARD_TYPE_HS200_1_8V | \\\n\t\t\t\t\t EXT_CSD_CARD_TYPE_HS200_1_2V)\n#define EXT_CSD_CARD_TYPE_HS400_1_8V\t(1<<6)\t/* Card can run at 200MHz DDR, 1.8V */\n#define EXT_CSD_CARD_TYPE_HS400_1_2V\t(1<<7)\t/* Card can run at 200MHz DDR, 1.2V */\n#define EXT_CSD_CARD_TYPE_HS400\t\t(EXT_CSD_CARD_TYPE_HS400_1_8V | \\\n\t\t\t\t\t EXT_CSD_CARD_TYPE_HS400_1_2V)\n#define EXT_CSD_CARD_TYPE_HS400ES\t(1<<8)\t/* Card can run at HS400ES */\n\n#define EXT_CSD_BUS_WIDTH_1\t0\t/* Card is in 1 bit mode */\n#define EXT_CSD_BUS_WIDTH_4\t1\t/* Card is in 4 bit mode */\n#define EXT_CSD_BUS_WIDTH_8\t2\t/* Card is in 8 bit mode */\n#define EXT_CSD_DDR_BUS_WIDTH_4\t5\t/* Card is in 4 bit DDR mode */\n#define EXT_CSD_DDR_BUS_WIDTH_8\t6\t/* Card is in 8 bit DDR mode */\n#define EXT_CSD_BUS_WIDTH_STROBE (1<<7)\t/* Enhanced strobe mode */\n\n#define EXT_CSD_TIMING_BC\t0\t/* Backwards compatility */\n#define EXT_CSD_TIMING_HS\t1\t/* High speed */\n#define EXT_CSD_TIMING_HS200\t2\t/* HS200 */\n#define EXT_CSD_TIMING_HS400\t3\t/* HS400 */\n#define EXT_CSD_DRV_STR_SHIFT\t4\t/* Driver Strength shift */\n\n#define EXT_CSD_SEC_ER_EN\t(1<<0)\n#define EXT_CSD_SEC_BD_BLK_EN\t(1<<2)\n#define EXT_CSD_SEC_GB_CL_EN\t(1<<4)\n#define EXT_CSD_SEC_SANITIZE\t(1<<6)  /* v4.5 only */\n\n#define EXT_CSD_RST_N_EN_MASK\t0x3\n#define EXT_CSD_RST_N_ENABLED\t1\t/* RST_n is enabled on card */\n\n#define EXT_CSD_NO_POWER_NOTIFICATION\t0\n#define EXT_CSD_POWER_ON\t\t1\n#define EXT_CSD_POWER_OFF_SHORT\t\t2\n#define EXT_CSD_POWER_OFF_LONG\t\t3\n\n#define EXT_CSD_PWR_CL_8BIT_MASK\t0xF0\t/* 8 bit PWR CLS */\n#define EXT_CSD_PWR_CL_4BIT_MASK\t0x0F\t/* 8 bit PWR CLS */\n#define EXT_CSD_PWR_CL_8BIT_SHIFT\t4\n#define EXT_CSD_PWR_CL_4BIT_SHIFT\t0\n\n#define EXT_CSD_PACKED_EVENT_EN\t(1<<3)\n\n/*\n* EXCEPTION_EVENT_STATUS field\n*/\n#define EXT_CSD_URGENT_BKOPS\t\t(1<<0)\n#define EXT_CSD_DYNCAP_NEEDED\t\t(1<<1)\n#define EXT_CSD_SYSPOOL_EXHAUSTED\t(1<<2)\n#define EXT_CSD_PACKED_FAILURE\t\t(1<<3)\n\n#define EXT_CSD_PACKED_GENERIC_ERROR\t(1<<0)\n#define EXT_CSD_PACKED_INDEXED_ERROR\t(1<<1)\n\n/*\n* BKOPS status level\n*/\n#define EXT_CSD_BKOPS_LEVEL_2\t\t0x2\n\n/*\n* BKOPS modes\n*/\n#define EXT_CSD_MANUAL_BKOPS_MASK\t0x01\n#define EXT_CSD_AUTO_BKOPS_MASK\t\t0x02\n\n/*\n* Command Queue\n*/\n#define EXT_CSD_CMDQ_MODE_ENABLED\t(1<<0)\n#define EXT_CSD_CMDQ_DEPTH_MASK\t\t0x1F\n#define EXT_CSD_CMDQ_SUPPORTED\t\t(1<<0)\n\n/*\n* MMC_SWITCH access modes\n*/\n#define MMC_SWITCH_MODE_CMD_SET\t\t0x00\t/* Change the command set */\n#define MMC_SWITCH_MODE_SET_BITS\t0x01\t/* Set bits which are 1 in value */\n#define MMC_SWITCH_MODE_CLEAR_BITS\t0x02\t/* Clear bits which are 1 in value */\n#define MMC_SWITCH_MODE_WRITE_BYTE\t0x03\t/* Set target to value */\n\n/*\n* Erase/trim/discard\n*/\n#define MMC_ERASE_ARG\t\t\t0x00000000\n#define MMC_SECURE_ERASE_ARG\t\t0x80000000\n#define MMC_TRIM_ARG\t\t\t0x00000001\n#define MMC_DISCARD_ARG\t\t\t0x00000003\n#define MMC_SECURE_TRIM1_ARG\t\t0x80000001\n#define MMC_SECURE_TRIM2_ARG\t\t0x80008000\n#define MMC_SECURE_ARGS\t\t\t0x80000000\n#define MMC_TRIM_ARGS\t\t\t0x00008001\n\n#endif /* LINUX_MMC_MMC_H */\n"
  },
  {
    "path": "argon-first-stage/include/storage/sd.h",
    "content": "/*\n *  include/linux/mmc/sd.h\n *\n *  Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved.\n *  Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or (at\n * your option) any later version.\n */\n\n#ifndef LINUX_MMC_SD_H\n#define LINUX_MMC_SD_H\n\n/* SD commands                           type  argument     response */\n/* class 0 */\n/* This is basically the same command as for MMC with some quirks. */\n#define SD_SEND_RELATIVE_ADDR     3   /* bcr                     R6  */\n#define SD_SEND_IF_COND           8   /* bcr  [11:0] See below   R7  */\n#define SD_SWITCH_VOLTAGE         11  /* ac                      R1  */\n\n/* class 10 */\n#define SD_SWITCH                 6   /* adtc [31:0] See below   R1  */\n\n/* class 5 */\n#define SD_ERASE_WR_BLK_START    32   /* ac   [31:0] data addr   R1  */\n#define SD_ERASE_WR_BLK_END      33   /* ac   [31:0] data addr   R1  */\n\n/* Application commands */\n#define SD_APP_SET_BUS_WIDTH      6   /* ac   [1:0] bus width    R1  */\n#define SD_APP_SD_STATUS         13   /* adtc                    R1  */\n#define SD_APP_SEND_NUM_WR_BLKS  22   /* adtc                    R1  */\n#define SD_APP_OP_COND           41   /* bcr  [31:0] OCR         R3  */\n#define SD_APP_SET_CLR_CARD_DETECT 42\n#define SD_APP_SEND_SCR          51   /* adtc                    R1  */\n\n/* OCR bit definitions */\n#define SD_OCR_S18R         (1 << 24)    /* 1.8V switching request */\n#define SD_ROCR_S18A        SD_OCR_S18R  /* 1.8V switching accepted by card */\n#define SD_OCR_XPC          (1 << 28)    /* SDXC power control */\n#define SD_OCR_CCS          (1 << 30)    /* Card Capacity Status */\n#define SD_OCR_VDD_32_33    (1 << 20)\t /* VDD voltage 3.2 ~ 3.3 */\n\n/*\n* SD_SWITCH argument format:\n*\n*      [31] Check (0) or switch (1)\n*      [30:24] Reserved (0)\n*      [23:20] Function group 6\n*      [19:16] Function group 5\n*      [15:12] Function group 4\n*      [11:8] Function group 3\n*      [7:4] Function group 2\n*      [3:0] Function group 1\n*/\n\n/*\n* SD_SEND_IF_COND argument format:\n*\n*\t[31:12] Reserved (0)\n*\t[11:8] Host Voltage Supply Flags\n*\t[7:0] Check Pattern (0xAA)\n*/\n\n/*\n* SCR field definitions\n*/\n#define SCR_SPEC_VER_0\t\t0\t/* Implements system specification 1.0 - 1.01 */\n#define SCR_SPEC_VER_1\t\t1\t/* Implements system specification 1.10 */\n#define SCR_SPEC_VER_2\t\t2\t/* Implements system specification 2.00-3.0X */\n#define SD_SCR_BUS_WIDTH_1\t(1<<0)\n#define SD_SCR_BUS_WIDTH_4\t(1<<2)\n\n/*\n* SD bus widths\n*/\n#define SD_BUS_WIDTH_1\t\t0\n#define SD_BUS_WIDTH_4\t\t2\n\n/*\n* SD bus speeds\n*/\n#define UHS_SDR12_BUS_SPEED\t\t0\n#define HIGH_SPEED_BUS_SPEED\t1\n#define UHS_SDR25_BUS_SPEED\t\t1\n#define UHS_SDR50_BUS_SPEED\t\t2\n#define UHS_SDR104_BUS_SPEED\t3\n#define UHS_DDR50_BUS_SPEED\t\t4\n#define HS400_BUS_SPEED \t\t5\n\n#define SD_MODE_HIGH_SPEED\t(1 << HIGH_SPEED_BUS_SPEED)\n#define SD_MODE_UHS_SDR12\t(1 << UHS_SDR12_BUS_SPEED)\n#define SD_MODE_UHS_SDR25\t(1 << UHS_SDR25_BUS_SPEED)\n#define SD_MODE_UHS_SDR50\t(1 << UHS_SDR50_BUS_SPEED)\n#define SD_MODE_UHS_SDR104\t(1 << UHS_SDR104_BUS_SPEED)\n#define SD_MODE_UHS_DDR50\t(1 << UHS_DDR50_BUS_SPEED)\n\n#define SD_DRIVER_TYPE_B\t0x01\n#define SD_DRIVER_TYPE_A\t0x02\n\n#define SD_SET_CURRENT_LIMIT_200\t0\n#define SD_SET_CURRENT_LIMIT_400\t1\n#define SD_SET_CURRENT_LIMIT_600\t2\n#define SD_SET_CURRENT_LIMIT_800\t3\n\n/*\n* SD_SWITCH mode\n*/\n#define SD_SWITCH_CHECK\t\t0\n#define SD_SWITCH_SET\t\t1\n\n/*\n* SD_SWITCH function groups\n*/\n#define SD_SWITCH_GRP_ACCESS\t0\n\n/*\n* SD_SWITCH access modes\n*/\n#define SD_SWITCH_ACCESS_DEF\t0\n#define SD_SWITCH_ACCESS_HS\t\t1\n\n#endif /* LINUX_MMC_SD_H */"
  },
  {
    "path": "argon-first-stage/include/storage/sdmmc.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _SDMMC_H_\n#define _SDMMC_H_\n\n#include \"utils/types.h\"\n#include \"sdmmc_driver.h\"\n\ntypedef struct _mmc_cid\n{\n\tu32 manfid;\n\tu8  prod_name[8];\n\tu8  card_bga;\n\tu8  prv;\n\tu32 serial;\n\tu16 oemid;\n\tu16\tyear;\n\tu8  hwrev;\n\tu8  fwrev;\n\tu8  month;\n} mmc_cid_t;\n\ntypedef struct _mmc_csd\n{\n\tu8  structure;\n\tu8  mmca_vsn;\n\tu16 cmdclass;\n\tu32 c_size;\n\tu32 r2w_factor;\n\tu32 max_dtr;\n\tu32 erase_size;\t\t/* In sectors */\n\tu32 read_blkbits;\n\tu32 write_blkbits;\n\tu32 capacity;\n\tu8  write_protect;\n\tu16 busspeed;\n} mmc_csd_t;\n\ntypedef struct _mmc_ext_csd\n{\n\tu8  rev;\n\tu32 sectors;\n\tint bkops;        /* background support bit */\n\tint bkops_en;     /* manual bkops enable bit */\n\tu8  ext_struct;   /* 194 */\n\tu8  card_type;    /* 196 */\n\tu8  bkops_status; /* 246 */\n\tu16 dev_version;\n\tu8  boot_mult;\n\tu8  rpmb_mult;\n} mmc_ext_csd_t;\n\ntypedef struct _sd_scr\n{\n\tu8 sda_vsn;\n\tu8 sda_spec3;\n\tu8 bus_widths;\n\tu8 cmds;\n} sd_scr_t;\n\ntypedef struct _sd_ssr\n{\n\tu8 bus_width;\n\tu8 speed_class;\n\tu8 uhs_grade;\n\tu8 video_class;\n\tu8 app_class;\n} sd_ssr_t;\n\n/*! SDMMC storage context. */\ntypedef struct _sdmmc_storage_t\n{\n\tsdmmc_t *sdmmc;\n\tu32 rca;\n\tint has_sector_access;\n\tu32 sec_cnt;\n\tint is_low_voltage;\n\tu32 partition;\n\tu8  raw_cid[0x10];\n\tu8  raw_csd[0x10];\n\tu8  raw_scr[8];\n\tu8  raw_ssr[0x40];\n\tmmc_cid_t     cid;\n\tmmc_csd_t     csd;\n\tmmc_ext_csd_t ext_csd;\n\tsd_scr_t      scr;\n\tsd_ssr_t      ssr;\n} sdmmc_storage_t;\n\nint sdmmc_storage_end(sdmmc_storage_t *storage);\nint sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);\nint sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);\nint sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type);\nint sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition);\nint sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type);\nint sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc);\n\n#endif"
  },
  {
    "path": "argon-first-stage/include/storage/sdmmc_driver.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _SDMMC_DRIVER_H_\n#define _SDMMC_DRIVER_H_\n\n#include \"../utils/types.h\"\n#include \"sdmmc_t210.h\"\n\n/*! SDMMC controller IDs. */\n#define SDMMC_1 0\n#define SDMMC_2 1\n#define SDMMC_3 2\n#define SDMMC_4 3\n\n/*! SDMMC power types. */\n#define SDMMC_POWER_OFF 0\n#define SDMMC_POWER_1_8 1\n#define SDMMC_POWER_3_3 2\n\n/*! SDMMC bus widths. */\n#define SDMMC_BUS_WIDTH_1 0\n#define SDMMC_BUS_WIDTH_4 1\n#define SDMMC_BUS_WIDTH_8 2\n\n/*! SDMMC response types. */\n#define SDMMC_RSP_TYPE_0 0\n#define SDMMC_RSP_TYPE_1 1\n#define SDMMC_RSP_TYPE_2 2\n#define SDMMC_RSP_TYPE_3 3\n#define SDMMC_RSP_TYPE_4 4\n#define SDMMC_RSP_TYPE_5 5\n\n/*! SDMMC mask interrupt status. */\n#define SDMMC_MASKINT_MASKED   0\n#define SDMMC_MASKINT_NOERROR -1\n#define SDMMC_MASKINT_ERROR   -2\n\n/*! SDMMC host control 2 */\n#define SDHCI_CTRL_UHS_MASK\t\t\t0xFFF8\n#define SDHCI_CTRL_VDD_330\t\t\t0xFFF7\n#define SDHCI_CTRL_VDD_180\t\t\t8\n#define SDHCI_CTRL_EXEC_TUNING\t\t0x40\n#define SDHCI_CTRL_TUNED_CLK\t\t0x80\n#define SDHCI_HOST_VERSION_4_EN\t\t0x1000\n#define SDHCI_ADDRESSING_64BIT_EN\t0x2000\n#define SDHCI_CTRL_PRESET_VAL_EN\t0x8000\n\n/*! SD bus speeds. */\n#define UHS_SDR12_BUS_SPEED\t\t0\n#define HIGH_SPEED_BUS_SPEED\t1\n#define UHS_SDR25_BUS_SPEED\t\t1\n#define UHS_SDR50_BUS_SPEED\t\t2\n#define UHS_SDR104_BUS_SPEED\t3\n#define UHS_DDR50_BUS_SPEED\t\t4\n#define HS400_BUS_SPEED \t\t5\n\n/*! Helper for SWITCH command argument. */\n#define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8))\n\n/*! SDMMC controller context. */\ntypedef struct _sdmmc_t\n{\n\tt210_sdmmc_t *regs;\n\tu32 id;\n\tu32 divisor;\n\tu32 clock_stopped;\n\tint no_sd;\n\tint sd_clock_enabled;\n\tint venclkctl_set;\n\tu32 venclkctl_tap;\n\tu32 expected_rsp_type;\n\tu32 dma_addr_next;\n\tu32 rsp[4];\n\tu32 rsp3;\n} sdmmc_t;\n\n/*! SDMMC command. */\ntypedef struct _sdmmc_cmd_t\n{\n\tu16 cmd;\n\tu32 arg;\n\tu32 rsp_type;\n\tu32 check_busy;\n} sdmmc_cmd_t;\n\n/*! SDMMC request. */\ntypedef struct _sdmmc_req_t\n{\n\tvoid *buf;\n\tu32 blksize;\n\tu32 num_sectors;\n\tint is_write;\n\tint is_multi_block;\n\tint is_auto_cmd12;\n} sdmmc_req_t;\n\nint sdmmc_get_voltage(sdmmc_t *sdmmc);\nu32 sdmmc_get_bus_width(sdmmc_t *sdmmc);\nvoid sdmmc_set_bus_width(sdmmc_t *sdmmc, u32 bus_width);\nvoid sdmmc_get_venclkctl(sdmmc_t *sdmmc);\nint sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type);\nvoid sdmmc_sd_clock_ctrl(sdmmc_t *sdmmc, int no_sd);\nint sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type);\nint sdmmc_config_tuning(sdmmc_t *sdmmc, u32 type, u32 cmd);\nint sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp);\nint sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int no_sd);\nvoid sdmmc_end(sdmmc_t *sdmmc);\nvoid sdmmc_init_cmd(sdmmc_cmd_t *cmdbuf, u16 cmd, u32 arg, u32 rsp_type, u32 check_busy);\nint sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out);\nint sdmmc_enable_low_voltage(sdmmc_t *sdmmc);\n\n#endif"
  },
  {
    "path": "argon-first-stage/include/storage/sdmmc_t210.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _SDMMC_T210_H_\n#define _SDMMC_T210_H_\n\n#include \"../utils/types.h\"\n\n#define TEGRA_MMC_PWRCTL_SD_BUS_POWER 0x1\n#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8 0xA\n#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_0 0xC\n#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3 0xE\n#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_MASK 0xF1\n\n#define TEGRA_MMC_HOSTCTL_1BIT 0x00\n#define TEGRA_MMC_HOSTCTL_4BIT 0x02\n#define TEGRA_MMC_HOSTCTL_8BIT 0x20\n\n#define TEGRA_MMC_CLKCON_INTERNAL_CLOCK_ENABLE 0x1\n#define TEGRA_MMC_CLKCON_INTERNAL_CLOCK_STABLE 0x2\n#define TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE 0x4\n#define TEGRA_MMC_CLKCON_CLKGEN_SELECT 0x20\n\n#define TEGRA_MMC_SWRST_SW_RESET_FOR_ALL 0x1\n#define TEGRA_MMC_SWRST_SW_RESET_FOR_CMD_LINE 0x2\n#define TEGRA_MMC_SWRST_SW_RESET_FOR_DAT_LINE 0x4\n\n#define TEGRA_MMC_TRNMOD_DMA_ENABLE 0x1\n#define TEGRA_MMC_TRNMOD_BLOCK_COUNT_ENABLE 0x2\n#define TEGRA_MMC_TRNMOD_AUTO_CMD12 0x4\n#define TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_WRITE 0x0\n#define TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ 0x10\n#define TEGRA_MMC_TRNMOD_MULTI_BLOCK_SELECT 0x20\n\n#define TEGRA_MMC_TRNMOD_CMD_CRC_CHECK 0x8\n#define TEGRA_MMC_TRNMOD_CMD_INDEX_CHECK 0x10\n#define TEGRA_MMC_TRNMOD_DATA_PRESENT_SELECT_DATA_TRANSFER 0x20\n\n#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_MASK 0x3\n#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_NO_RESPONSE 0x0\n#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_136 0x1\n#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48 0x2\n#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48_BUSY 0x3\n\n#define TEGRA_MMC_NORINTSTS_CMD_COMPLETE 0x1\n#define TEGRA_MMC_NORINTSTS_XFER_COMPLETE 0x2\n#define TEGRA_MMC_NORINTSTS_DMA_INTERRUPT 0x8\n#define TEGRA_MMC_NORINTSTS_ERR_INTERRUPT 0x8000\n#define TEGRA_MMC_NORINTSTS_CMD_TIMEOUT 0x10000\n\n#define TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY 0x20\n\ntypedef struct _t210_sdmmc_t\n{\n\tvu32 sysad;\n\tvu16 blksize;\n\tvu16 blkcnt;\n\tvu32 argument;\n\tvu16 trnmod;\n\tvu16 cmdreg;\n\tvu32 rspreg0;\n\tvu32 rspreg1;\n\tvu32 rspreg2;\n\tvu32 rspreg3;\n\tvu32 bdata;\n\tvu32 prnsts;\n\tvu8 hostctl;\n\tvu8 pwrcon;\n\tvu8 blkgap;\n\tvu8 wakcon;\n\tvu16 clkcon;\n\tvu8 timeoutcon;\n\tvu8 swrst;\n\tvu16 norintsts;\n\tvu16 errintsts;\n\tvu16 norintstsen;\n\tvu16 errintstsen;\n\tvu16 norintsigen;\n\tvu16 errintsigen;\n\tvu16 acmd12errsts;\n\tvu16 hostctl2;\n\tvu32 capareg;\n\tvu32 capareg_1;\n\tvu32 maxcurr;\n\tvu8 res3[4];\n\tvu16 setacmd12err;\n\tvu16 setinterr;\n\tvu8 admaerr;\n\tvu8 res4[3];\n\tvu32 admaaddr;\n\tvu32 admaaddr_hi;\n\tvu8 res5[156];\n\tvu16 slotintstatus;\n\tvu16 hcver;\n\tvu32 venclkctl;\n\tvu32 venspictl;\n\tvu32 venspiintsts;\n\tvu32 venceatactl;\n\tvu32 venbootctl;\n\tvu32 venbootacktout;\n\tvu32 venbootdattout;\n\tvu32 vendebouncecnt;\n\tvu32 venmiscctl;\n\tvu32 res6[34];\n\tvu32 veniotrimctl;\n\tvu32 vendllcal;\n\tvu8 res7[8];\n\tvu32 dllcfgstatus;\n\tvu32 ventunctl0;\n\tvu32 field_1C4;\n\tvu8 field_1C8[24];\n\tvu32 sdmemcmppadctl;\n\tvu32 autocalcfg;\n\tvu32 autocalintval;\n\tvu32 autocalsts;\n\tvu32 iospare;\n} t210_sdmmc_t;\n\n#endif"
  },
  {
    "path": "argon-first-stage/include/utils/aarch64_util.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _ARM64_H_\n#define _ARM64_H_\n\n#include \"utils/types.h\"\n\n#define LSL0 0\n#define LSL16 16\n#define LSL32 32\n\n#define _PAGEOFF(x) ((x) & 0xFFFFF000)\n\n#define _ADRP(r, o) 0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F)\n#define _BL(a, o) 0x94000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)\n#define _B(a, o) 0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)\n#define _MOVKX(r, i, s) 0xF2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)\n#define _MOVZX(r, i, s) 0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)\n#define _NOP() 0xD503201F\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/utils/btn.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _BTN_H_\n#define _BTN_H_\n\n#include \"utils/types.h\"\n\n#define BTN_POWER 0x1\n#define BTN_VOL_DOWN 0x2\n#define BTN_VOL_UP 0x4\n\nu32 btn_read();\nu32 btn_wait();\nu32 btn_wait_timeout(u32 time_ms, u32 mask);\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/utils/dirlist.h",
    "content": "/*\n * Copyright (c) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"utils/types.h\"\n\nchar *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles);\n"
  },
  {
    "path": "argon-first-stage/include/utils/fs_utils.h",
    "content": "#ifndef _FS_UTILS_H_\n#define _FS_UTILS_H_\n\n#include \"utils/types.h\"\n#include \"libs/fatfs/ff.h\"\n#include \"storage/sdmmc.h\"\n#include \"storage/sdmmc_driver.h\"\n\nsdmmc_t g_sd_sdmmc;\nsdmmc_storage_t g_sd_storage;\nFATFS g_sd_fs;\nbool g_sd_mounted;\n\nbool sd_mount();\nvoid sd_unmount();\nvoid *sd_file_read(char *path);\nint sd_save_to_file(void *buf, u32 size, const char *filename);\nbool sd_file_exists(const char* filename);\nvoid s_printf(char *out_buf, const char *fmt, ...);\n\n#endif"
  },
  {
    "path": "argon-first-stage/include/utils/types.h",
    "content": "/*\n* Copyright (c) 2018 naehrwert\n*\n* This program is free software; you can redistribute it and/or modify it\n* under the terms and conditions of the GNU General Public License,\n* version 2, as published by the Free Software Foundation.\n*\n* This program is distributed in the hope it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _TYPES_H_\n#define _TYPES_H_\n\n#define NULL ((void *)0)\n\n#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))\n#define MAX(a, b) ((a) > (b) ? (a) : (b))\n#define MIN(a, b) ((a) < (b) ? (a) : (b))\n\n#define OFFSET_OF(t, m) ((u32)&((t *)NULL)->m)\n#define CONTAINER_OF(mp, t, mn) ((t *)((u32)mp - OFFSET_OF(t, mn)))\n\ntypedef signed char s8;\ntypedef short s16;\ntypedef short SHORT;\ntypedef int s32;\ntypedef int INT;\ntypedef long LONG;\ntypedef long long int s64;\ntypedef unsigned char u8;\ntypedef unsigned char BYTE;\ntypedef unsigned short u16;\ntypedef unsigned short WORD;\ntypedef unsigned short WCHAR;\ntypedef unsigned int u32;\ntypedef unsigned int UINT;\ntypedef unsigned long DWORD;\ntypedef unsigned long long QWORD;\ntypedef unsigned long long int u64;\ntypedef volatile unsigned char vu8;\ntypedef volatile unsigned short vu16;\ntypedef volatile unsigned int vu32;\n\ntypedef int bool;\n#define true  1\n#define false 0\n\n#define BOOT_CFG_AUTOBOOT_EN (1 << 0)\n#define BOOT_CFG_FROM_LAUNCH (1 << 1)\n#define BOOT_CFG_SEPT_RUN    (1 << 7)\n\n#define EXTRA_CFG_KEYS    (1 << 0)\n#define EXTRA_CFG_PAYLOAD (1 << 1)\n#define EXTRA_CFG_MODULE  (1 << 2)\n\ntypedef struct __attribute__((__packed__)) _boot_cfg_t\n{\n\tu8  boot_cfg;\n\tu8  autoboot;\n\tu8  autoboot_list;\n\tu8  extra_cfg;\n\tu8  rsvd[128];\n} boot_cfg_t;\n\ntypedef struct __attribute__((__packed__)) _ipl_ver_meta_t\n{\n\tu32 magic;\n\tu32 version;\n\tu16 rsvd0;\n\tu16 rsvd1;\n} ipl_ver_meta_t;\n\ntypedef struct __attribute__((__packed__)) _reloc_meta_t\n{\n\tu32 start;\n\tu32 stack;\n\tu32 end;\n\tu32 ep;\n} reloc_meta_t;\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/include/utils/util.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018 CTCaer\n * Copyright (C) 2018 Guillem96\n * \n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _UTIL_H_\n#define _UTIL_H_\n\n#include \"utils/types.h\"\n\n#define MAKE_REG32(a) (*(vu32 *)(a))\n\n#define byte_swap_32(num) ((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \\\n\t\t\t\t\t\t((num >> 8 )& 0xff00) | ((num << 24) & 0xff000000)\n\ntypedef struct _cfg_op_t\n{\n\tu32 off;\n\tu32 val;\n} cfg_op_t;\n\nu32 get_tmr_us();\nu32 get_tmr_ms();\nu32 get_tmr_s();\nvoid usleep(u32 ticks);\nvoid msleep(u32 milliseconds);\nvoid exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);\nu32 crc32c(const void *buf, u32 len);\n\nvoid reboot_normal(void);\nvoid reboot_rcm(void);\nvoid power_off(void);\n\n/* This is a faster implementation of memcmp that checks two u32 values */\n/* every 128 Bytes block. Intented only for Backup and Restore          */\nu32 memcmp32sparse(const u32 *buf1, const u32 *buf2, u32 len);\n\n__attribute__((noreturn)) void wait_for_button_and_reboot(void);\n\n/**\n * Replace a pattern of string for another string\n */\nchar *str_replace(char *orig, char *rep, char *with);\n\nvoid panic(u32 val);\n\n#endif\n"
  },
  {
    "path": "argon-first-stage/src/LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\n 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Lesser General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n                            NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc.,\n    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.\n"
  },
  {
    "path": "argon-first-stage/src/core/launcher.c",
    "content": "/*\n * Copyright (c) 2018 Guillem96\n * Copyright (c) 2018 CTCaer\n * \n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n#include \"core/launcher.h\"\n\n#include <string.h>\n\n#include \"libs/fatfs/ff.h\"\n\n#include \"utils/types.h\"\n#include \"utils/util.h\"\n#include \"utils/fs_utils.h\"\n\n#include \"soc/hw_init.h\"\n#include \"soc/bpmp.h\"\n\n#include \"gfx/gfx.h\"\n\n#include \"gfx/di.h\"\n\n#include \"mem/heap.h\"\n\n// This is a safe and unused DRAM region for our payloads.\n#define IPL_LOAD_ADDR      0x40003000\n#define EXT_PAYLOAD_ADDR   0xC03C0000\n#define PATCHED_RELOC_SZ   0x94\n#define RCM_PAYLOAD_ADDR   (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))\n#define PAYLOAD_ENTRY      0x40010000\n#define CBFS_SDRAM_EN_ADDR 0x4003e000\n#define COREBOOT_ADDR      (0xD0000000 - 0x100000)\n\nvoid (*ext_payload_ptr)() = (void *)EXT_PAYLOAD_ADDR;\n\nvoid reloc_patcher(u32 payload_size)\n{\n\tstatic const u32 START_OFF = 0x7C;\n\tstatic const u32 PAYLOAD_END_OFF = 0x84;\n\tstatic const u32 IPL_START_OFF = 0x88;\n\n\tmemcpy((u8 *)EXT_PAYLOAD_ADDR, (u8 *)IPL_LOAD_ADDR, PATCHED_RELOC_SZ);\n\n\t*(vu32 *)(EXT_PAYLOAD_ADDR + START_OFF) = PAYLOAD_ENTRY - ALIGN(PATCHED_RELOC_SZ, 0x10);\n\t*(vu32 *)(EXT_PAYLOAD_ADDR + PAYLOAD_END_OFF) = PAYLOAD_ENTRY + payload_size;\n\t*(vu32 *)(EXT_PAYLOAD_ADDR + IPL_START_OFF) = PAYLOAD_ENTRY;\n\n\tif (payload_size == 0x7000)\n\t{\n\t\tmemcpy((u8 *)(EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10)), (u8 *)COREBOOT_ADDR, 0x7000); //Bootblock\n\t\t*(vu32 *)CBFS_SDRAM_EN_ADDR = 0x4452414D;\n\t}\n}\n\nint launch_payload(char *path)\n{\n    u8 *gui = sd_file_read(path);\n    if (!gui)\n    {\n        gfx_printf(\"Cannot find %s\\n\", path);\n        return 1;\n    }\n\n    free(path);\n    path = NULL;\n\n    sd_unmount();\n    \n    void (*gui_ptr)() = (void *)gui;\n\n    bpmp_mmu_disable();\n\tbpmp_clk_rate_set(BPMP_CLK_NORMAL);\n    \n    msleep(100);\n\n    // Launch our payload.\n    (*gui_ptr)();\n\n\treturn 1;\n}\n"
  },
  {
    "path": "argon-first-stage/src/gfx/di.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"gfx/di.h\"\n#include \"gfx/gfx.h\"\n#include \"power/max77620.h\"\n#include \"power/max7762x.h\"\n#include \"soc/clock.h\"\n#include \"soc/gpio.h\"\n#include \"soc/i2c.h\"\n#include \"soc/pinmux.h\"\n#include \"soc/pmc.h\"\n#include \"soc/t210.h\"\n#include \"utils/util.h\"\n\n#include \"gfx/di.inl\"\n\nstatic u32 _display_ver = 0;\n\nstatic void _display_dsi_wait(u32 timeout, u32 off, u32 mask)\n{\n\tu32 end = get_tmr_us() + timeout;\n\twhile (get_tmr_us() < end && DSI(off) & mask)\n\t\t;\n\tusleep(5);\n}\n\nvoid display_init()\n{\n\t// Power on.\n\tmax77620_regulator_set_volt_and_flags(REGULATOR_LDO0, 1200000, MAX77620_POWER_MODE_NORMAL); // Configure to 1.2V.\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO7, MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH | MAX77620_CNFG_GPIO_DRV_PUSHPULL);\n\n\t// Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks.\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x1010000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x1010000;\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = 0x18000000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = 0x18000000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x20000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIP_CAL) = 0xA;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = 0x80000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 0xA;\n\n\t// DPD idle.\n\tPMC(APBDEV_PMC_IO_DPD_REQ) = 0x40000000;\n\tPMC(APBDEV_PMC_IO_DPD2_REQ) = 0x40000000;\n\n\t// Config pins.\n\tPINMUX_AUX(PINMUX_AUX_NFC_EN) &= ~PINMUX_TRISTATE;\n\tPINMUX_AUX(PINMUX_AUX_NFC_INT) &= ~PINMUX_TRISTATE;\n\tPINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) &= ~PINMUX_TRISTATE;\n\tPINMUX_AUX(PINMUX_AUX_LCD_BL_EN) &= ~PINMUX_TRISTATE;\n\tPINMUX_AUX(PINMUX_AUX_LCD_RST) &= ~PINMUX_TRISTATE;\n\n\tgpio_config(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_MODE_GPIO); // Backlight +-5V.\n\tgpio_output_enable(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_OUTPUT_ENABLE); // Backlight +-5V.\n\tgpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_HIGH); // Backlight +5V enable.\n\n\tusleep(10000);\n\n\tgpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_HIGH); // Backlight -5V enable.\n\n\tusleep(10000);\n\n\tgpio_config(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_MODE_GPIO); // Backlight PWM, Enable, Reset.\n\tgpio_output_enable(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_OUTPUT_ENABLE);\n\tgpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH); // Backlight Enable enable.\n\n\t// Config display interface and display.\n\tMIPI_CAL(MIPI_CAL_MIPI_BIAS_PAD_CFG2) = 0;\n\n\texec_cfg((u32 *)CLOCK_BASE, _display_config_1, 4);\n\texec_cfg((u32 *)DISPLAY_A_BASE, _display_config_2, 94);\n\texec_cfg((u32 *)DSI_BASE, _display_config_3, 61);\n\n\tusleep(10000);\n\n\tgpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_HIGH); // Backlight Reset enable.\n\n\tusleep(60000);\n\n\tDSI(_DSIREG(DSI_BTA_TIMING)) = 0x50204;\n\tDSI(_DSIREG(DSI_WR_DATA)) = 0x337; // MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE\n\tDSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;\n\t_display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);\n\n\tDSI(_DSIREG(DSI_WR_DATA)) = 0x406; // MIPI_DCS_GET_DISPLAY_ID\n\tDSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;\n\t_display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);\n\n\tDSI(_DSIREG(DSI_HOST_CONTROL)) = DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC;\n\t_display_dsi_wait(150000, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA);\n\n\tusleep(5000);\n\n\t_display_ver = DSI(_DSIREG(DSI_RD_DATA));\n\tif (_display_ver == 0x10)\n\t\texec_cfg((u32 *)DSI_BASE, _display_config_4, 43);\n\n\tDSI(_DSIREG(DSI_WR_DATA)) = 0x1105; // MIPI_DCS_EXIT_SLEEP_MODE\n\tDSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;\n\n\tusleep(180000);\n\n\tDSI(_DSIREG(DSI_WR_DATA)) = 0x2905; // MIPI_DCS_SET_DISPLAY_ON\n\tDSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;\n\n\tusleep(20000);\n\n\texec_cfg((u32 *)CLOCK_BASE, _display_config_6, 3);\n\texec_cfg((u32 *)DSI_BASE, _display_config_5, 21);\n\tDISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = 4;\n\texec_cfg((u32 *)DSI_BASE, _display_config_7, 10);\n\n\tusleep(10000);\n\n\texec_cfg((u32 *)MIPI_CAL_BASE, _display_config_8, 6);\n\texec_cfg((u32 *)DSI_BASE, _display_config_9, 4);\n\texec_cfg((u32 *)MIPI_CAL_BASE, _display_config_10, 16);\n\n\tusleep(10000);\n\n\texec_cfg((u32 *)DISPLAY_A_BASE, _display_config_11, 113);\n}\n\nvoid display_backlight_pwm_init()\n{\n\tclock_enable_pwm();\n\n\tPWM(PWM_CONTROLLER_PWM_CSR_0) = (1 << 31); // Enable PWM\n\n\tPINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) >> 2) << 2 | 1; // PWM clock source.\n\tgpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight power mode.\n\t\n}\n\nvoid display_backlight(bool enable)\n{\n\tgpio_write(GPIO_PORT_V, GPIO_PIN_0, enable ? GPIO_HIGH : GPIO_LOW); // Backlight PWM GPIO.\n}\n\nvoid display_backlight_brightness(u32 brightness, u32 step_delay)\n{\n\tu32 old_value = (PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF;\n\tif (brightness == old_value)\n\t\treturn;\n\n\tif (brightness > 255)\n\t\tbrightness = 255;\n\n\tif (old_value < brightness)\n\t{\n\t\tfor (u32 i = old_value; i < brightness + 1; i++)\n\t\t{\n\t\t\tPWM(PWM_CONTROLLER_PWM_CSR_0) = (1 << 31) | (i << 16); // Enable PWM\n\t\t\tusleep(step_delay);\n\t\t}\n\t}\n\telse\n\t{\n\t\tfor (u32 i = old_value; i > brightness; i--)\n\t\t{\n\t\t\tPWM(PWM_CONTROLLER_PWM_CSR_0) = (1 << 31) | (i << 16); // Enable PWM\n\t\t\tusleep(step_delay);\n\t\t}\n\t}\n\tif (!brightness)\n\t\tPWM(PWM_CONTROLLER_PWM_CSR_0) = 0;\n}\n\nvoid display_end()\n{\n\tdisplay_backlight_brightness(0, 1000);\n\n\tDSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 1;\n\tDSI(_DSIREG(DSI_WR_DATA)) = 0x2805; // MIPI_DCS_SET_DISPLAY_OFF\n\n\tDISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX | WRITE_MUX;\n\tDSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;\n\n\texec_cfg((u32 *)DISPLAY_A_BASE, _display_config_12, 17);\n\texec_cfg((u32 *)DSI_BASE, _display_config_13, 16);\n\n\tusleep(10000);\n\n\tif (_display_ver == 0x10)\n\t\texec_cfg((u32 *)DSI_BASE, _display_config_14, 22);\n\n\tDSI(_DSIREG(DSI_WR_DATA)) = 0x1005; // MIPI_DCS_ENTER_SLEEP_MODE\n\tDSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;\n\n\tusleep(50000);\n\n\tgpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); //Backlight Reset disable.\n\n\tusleep(10000);\n\n\tgpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); //Backlight -5V disable.\n\n\tusleep(10000);\n\n\tgpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); //Backlight +5V disable.\n\n\tusleep(10000);\n\n\t// Disable clocks.\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = 0x1010000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = 0x1010000;\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = 0x18000000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = 0x18000000;\n\n\tDSI(_DSIREG(DSI_PAD_CONTROL_0)) = DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF);\n\tDSI(_DSIREG(DSI_POWER_CONTROL)) = 0;\n\n\tgpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight PWM.\n\n\tPINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_TRISTATE) | PINMUX_TRISTATE;\n\tPINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) >> 2) << 2 | 1;\n}\n\nvoid display_color_screen(u32 color)\n{\n\texec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_one_color, 8);\n\n\t// Configure display to show single color.\n\tDISPLAY_A(_DIREG(DC_WIN_AD_WIN_OPTIONS)) = 0;\n\tDISPLAY_A(_DIREG(DC_WIN_BD_WIN_OPTIONS)) = 0;\n\tDISPLAY_A(_DIREG(DC_WIN_CD_WIN_OPTIONS)) = 0;\n\tDISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color;\n\tDISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = (DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE) | GENERAL_ACT_REQ;\n\n\tusleep(35000);\n\n\tdisplay_backlight(true);\n}\n\nu32 *display_init_framebuffer()\n{\n\t// Sanitize framebuffer area.\n\t// memset((u32 *)FB_ADDRESS, 0, 0x3C0000);\n\t// This configures the framebuffer @ 0xC0000000 with a resolution of 1280x720 (line stride 720).\n\texec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer, 32);\n\n\tusleep(35000);\n\n\treturn (u32 *)FB_ADDRESS;\n}\n"
  },
  {
    "path": "argon-first-stage/src/gfx/gfx.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018-2019 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdarg.h>\n#include <string.h>\n#include \"gfx/gfx.h\"\n#include \"mem/heap.h\"\n\nstatic const u8 _gfx_font[] = {\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 032 ( )\n\t0x00, 0x30, 0x30, 0x18, 0x18, 0x00, 0x0C, 0x00, // Char 033 (!)\n\t0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, // Char 034 (\")\n\t0x00, 0x66, 0x66, 0xFF, 0x66, 0xFF, 0x66, 0x66, // Char 035 (#)\n\t0x00, 0x18, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x18, // Char 036 ($)\n\t0x00, 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62, // Char 037 (%)\n\t0x00, 0x3C, 0x66, 0x3C, 0x1C, 0xE6, 0x66, 0xFC, // Char 038 (&)\n\t0x00, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, // Char 039 (')\n\t0x00, 0x30, 0x18, 0x0C, 0x0C, 0x18, 0x30, 0x00, // Char 040 (()\n\t0x00, 0x0C, 0x18, 0x30, 0x30, 0x18, 0x0C, 0x00, // Char 041 ())\n\t0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, // Char 042 (*)\n\t0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, // Char 043 (+)\n\t0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0C, 0x00, // Char 044 (,)\n\t0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, // Char 045 (-)\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, // Char 046 (.)\n\t0x00, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, // Char 047 (/)\n\t0x00, 0x3C, 0x66, 0x76, 0x6E, 0x66, 0x3C, 0x00, // Char 048 (0)\n\t0x00, 0x18, 0x1C, 0x18, 0x18, 0x18, 0x7E, 0x00, // Char 049 (1)\n\t0x00, 0x3C, 0x62, 0x30, 0x0C, 0x06, 0x7E, 0x00, // Char 050 (2)\n\t0x00, 0x3C, 0x62, 0x38, 0x60, 0x66, 0x3C, 0x00, // Char 051 (3)\n\t0x00, 0x6C, 0x6C, 0x66, 0xFE, 0x60, 0x60, 0x00, // Char 052 (4)\n\t0x00, 0x7E, 0x06, 0x7E, 0x60, 0x66, 0x3C, 0x00, // Char 053 (5)\n\t0x00, 0x3C, 0x06, 0x3E, 0x66, 0x66, 0x3C, 0x00, // Char 054 (6)\n\t0x00, 0x7E, 0x30, 0x30, 0x18, 0x18, 0x18, 0x00, // Char 055 (7)\n\t0x00, 0x3C, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, // Char 056 (8)\n\t0x00, 0x3C, 0x66, 0x7C, 0x60, 0x66, 0x3C, 0x00, // Char 057 (9)\n\t0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, // Char 058 (:)\n\t0x00, 0x00, 0x18, 0x00, 0x18, 0x18, 0x0C, 0x00, // Char 059 (;)\n\t0x00, 0x70, 0x1C, 0x06, 0x06, 0x1C, 0x70, 0x00, // Char 060 (<)\n\t0x00, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x00, 0x00, // Char 061 (=)\n\t0x00, 0x0E, 0x38, 0x60, 0x60, 0x38, 0x0E, 0x00, // Char 062 (>)\n\t0x00, 0x3C, 0x66, 0x30, 0x18, 0x00, 0x18, 0x00, // Char 063 (?)\n\t0x00, 0x3C, 0x66, 0x76, 0x76, 0x06, 0x46, 0x3C, // Char 064 (@)\n\t0x00, 0x3C, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, // Char 065 (A)\n\t0x00, 0x3E, 0x66, 0x3E, 0x66, 0x66, 0x3E, 0x00, // Char 066 (B)\n\t0x00, 0x3C, 0x66, 0x06, 0x06, 0x66, 0x3C, 0x00, // Char 067 (C)\n\t0x00, 0x1E, 0x36, 0x66, 0x66, 0x36, 0x1E, 0x00, // Char 068 (D)\n\t0x00, 0x7E, 0x06, 0x1E, 0x06, 0x06, 0x7E, 0x00, // Char 069 (E)\n\t0x00, 0x3E, 0x06, 0x1E, 0x06, 0x06, 0x06, 0x00, // Char 070 (F)\n\t0x00, 0x3C, 0x66, 0x06, 0x76, 0x66, 0x3C, 0x00, // Char 071 (G)\n\t0x00, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, // Char 072 (H)\n\t0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, // Char 073 (I)\n\t0x00, 0x78, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, // Char 074 (J)\n\t0x00, 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x00, // Char 075 (K)\n\t0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7E, 0x00, // Char 076 (L)\n\t0x00, 0x46, 0x6E, 0x7E, 0x56, 0x46, 0x46, 0x00, // Char 077 (M)\n\t0x00, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x66, 0x00, // Char 078 (N)\n\t0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, // Char 079 (O)\n\t0x00, 0x3E, 0x66, 0x3E, 0x06, 0x06, 0x06, 0x00, // Char 080 (P)\n\t0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x70, 0x00, // Char 081 (Q)\n\t0x00, 0x3E, 0x66, 0x3E, 0x1E, 0x36, 0x66, 0x00, // Char 082 (R)\n\t0x00, 0x3C, 0x66, 0x0C, 0x30, 0x66, 0x3C, 0x00, // Char 083 (S)\n\t0x00, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, // Char 084 (T)\n\t0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, // Char 085 (U)\n\t0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, // Char 086 (V)\n\t0x00, 0x46, 0x46, 0x56, 0x7E, 0x6E, 0x46, 0x00, // Char 087 (W)\n\t0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00, // Char 088 (X)\n\t0x00, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00, // Char 089 (Y)\n\t0x00, 0x7E, 0x30, 0x18, 0x0C, 0x06, 0x7E, 0x00, // Char 090 (Z)\n\t0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, // Char 091 ([)\n\t0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00, // Char 092 (\\)\n\t0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, // Char 093 (])\n\t0x00, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, // Char 094 (^)\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, // Char 095 (_)\n\t0x00, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, // Char 096 (`)\n\t0x00, 0x00, 0x3C, 0x60, 0x7C, 0x66, 0x7C, 0x00, // Char 097 (a)\n\t0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x00, // Char 098 (b)\n\t0x00, 0x00, 0x3C, 0x06, 0x06, 0x06, 0x3C, 0x00, // Char 099 (c)\n\t0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00, // Char 100 (d)\n\t0x00, 0x00, 0x3C, 0x66, 0x7E, 0x06, 0x3C, 0x00, // Char 101 (e)\n\t0x00, 0x38, 0x0C, 0x3E, 0x0C, 0x0C, 0x0C, 0x00, // Char 102 (f)\n\t0x00, 0x00, 0x7C, 0x66, 0x7C, 0x40, 0x3C, 0x00, // Char 103 (g)\n\t0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x00, // Char 104 (h)\n\t0x00, 0x18, 0x00, 0x1C, 0x18, 0x18, 0x3C, 0x00, // Char 105 (i)\n\t0x00, 0x30, 0x00, 0x30, 0x30, 0x30, 0x1E, 0x00, // Char 106 (j)\n\t0x00, 0x06, 0x06, 0x36, 0x1E, 0x36, 0x66, 0x00, // Char 107 (k)\n\t0x00, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, // Char 108 (l)\n\t0x00, 0x00, 0x66, 0xFE, 0xFE, 0xD6, 0xC6, 0x00, // Char 109 (m)\n\t0x00, 0x00, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x00, // Char 110 (n)\n\t0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00, // Char 111 (o)\n\t0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x00, // Char 112 (p)\n\t0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x00, // Char 113 (q)\n\t0x00, 0x00, 0x3E, 0x66, 0x06, 0x06, 0x06, 0x00, // Char 114 (r)\n\t0x00, 0x00, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x00, // Char 115 (s)\n\t0x00, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x70, 0x00, // Char 116 (t)\n\t0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x00, // Char 117 (u)\n\t0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, // Char 118 (v)\n\t0x00, 0x00, 0xC6, 0xD6, 0xFE, 0x7C, 0x6C, 0x00, // Char 119 (w)\n\t0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, // Char 120 (x)\n\t0x00, 0x00, 0x66, 0x66, 0x7C, 0x60, 0x3C, 0x00, // Char 121 (y)\n\t0x00, 0x00, 0x7E, 0x30, 0x18, 0x0C, 0x7E, 0x00, // Char 122 (z)\n\t0x00, 0x18, 0x08, 0x08, 0x04, 0x08, 0x08, 0x18, // Char 123 ({)\n\t0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, // Char 124 (|)\n\t0x00, 0x0C, 0x08, 0x08, 0x10, 0x08, 0x08, 0x0C, // Char 125 (})\n\t0x00, 0x00, 0x00, 0x4C, 0x32, 0x00, 0x00, 0x00  // Char 126 (~)\n};\n\nvoid gfx_init_ctxt(u32 *fb, u32 width, u32 height, u32 stride)\n{\n\tg_gfx_ctxt.fb = fb;\n\tg_gfx_ctxt.width = width;\n\tg_gfx_ctxt.height = height;\n\tg_gfx_ctxt.stride = stride;\n}\n\nvoid gfx_clear_grey(u8 color)\n{\n\tmemset(g_gfx_ctxt.fb, color, 0x3C0000);\n}\n\nvoid gfx_clear_color(u32 color)\n{\n\tfor (u32 i = 0; i < g_gfx_ctxt.height * g_gfx_ctxt.stride; i++)\n\t\tg_gfx_ctxt.fb[i] = color;\n}\n\nvoid gfx_clear_partial_grey(u8 color, u32 pos_x, u32 height)\n{\n\tmemset(g_gfx_ctxt.fb + pos_x * g_gfx_ctxt.stride, color, height * 4 * g_gfx_ctxt.stride);\n}\n\nvoid gfx_con_init()\n{\n\tg_gfx_con.gfx_ctxt = &g_gfx_ctxt;\n\tg_gfx_con.fntsz = 16;\n\tg_gfx_con.x = 0;\n\tg_gfx_con.y = 0;\n\tg_gfx_con.savedx = 0;\n\tg_gfx_con.savedy = 0;\n\tg_gfx_con.fgcol = 0xFFCCCCCC;\n\tg_gfx_con.fillbg = 1;\n\tg_gfx_con.bgcol = 0xFF1B1B1B;\n\tg_gfx_con.mute = 0;\n}\n\nvoid gfx_con_setcol(u32 fgcol, int fillbg, u32 bgcol)\n{\n\tg_gfx_con.fgcol = fgcol;\n\tg_gfx_con.fillbg = fillbg;\n\tg_gfx_con.bgcol = bgcol;\n}\n\nvoid gfx_con_getpos(u32 *x, u32 *y)\n{\n\t*x = g_gfx_con.x;\n\t*y = g_gfx_con.y;\n}\n\nvoid gfx_con_setpos(u32 x, u32 y)\n{\n\tg_gfx_con.x = x;\n\tg_gfx_con.y = y;\n}\n\nvoid gfx_putc(char c)\n{\n\t// Duplicate code for performance reasons.\n\tswitch (g_gfx_con.fntsz)\n\t{\n\tcase 16:\n\t\tif (c >= 32 && c <= 126)\n\t\t{\n\t\t\tu8 *cbuf = (u8 *)&_gfx_font[8 * (c - 32)];\n\t\t\tu32 *fb = g_gfx_ctxt.fb + g_gfx_con.x + g_gfx_con.y * g_gfx_ctxt.stride;\n\n\t\t\tfor (u32 i = 0; i < 16; i+=2)\n\t\t\t{\n\t\t\t\tu8 v = *cbuf++;\n\t\t\t\tfor (u32 k = 0; k < 2; k++)\n\t\t\t\t{\n\t\t\t\t\tfor (u32 j = 0; j < 8; j++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (v & 1)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t*fb = g_gfx_con.fgcol;\n\t\t\t\t\t\t\tfb++;\n\t\t\t\t\t\t\t*fb = g_gfx_con.fgcol;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (g_gfx_con.fillbg)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t*fb = g_gfx_con.bgcol;\n\t\t\t\t\t\t\tfb++;\n\t\t\t\t\t\t\t*fb = g_gfx_con.bgcol;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tfb++;\n\t\t\t\t\t\tv >>= 1;\n\t\t\t\t\t\tfb++;\n\t\t\t\t\t}\n\t\t\t\t\tfb += g_gfx_ctxt.stride - 16;\n\t\t\t\t\tv = *cbuf;\n\t\t\t\t}\n\t\t\t}\n\t\t\tg_gfx_con.x += 16;\n\t\t}\n\t\telse if (c == '\\n')\n\t\t{\n\t\t\tg_gfx_con.x = 0;\n\t\t\tg_gfx_con.y +=16;\n\t\t\tif (g_gfx_con.y > g_gfx_ctxt.height - 16)\n\t\t\t\tg_gfx_con.y = 0;\n\t\t}\n\t\tbreak;\n\tcase 8:\n\tdefault:\n\t\tif (c >= 32 && c <= 126)\n\t\t{\n\t\t\tu8 *cbuf = (u8 *)&_gfx_font[8 * (c - 32)];\n\t\t\tu32 *fb = g_gfx_ctxt.fb + g_gfx_con.x + g_gfx_con.y * g_gfx_ctxt.stride;\n\t\t\tfor (u32 i = 0; i < 8; i++)\n\t\t\t{\n\t\t\t\tu8 v = *cbuf++;\n\t\t\t\tfor (u32 j = 0; j < 8; j++)\n\t\t\t\t{\n\t\t\t\t\tif (v & 1)\n\t\t\t\t\t\t*fb = g_gfx_con.fgcol;\n\t\t\t\t\telse if (g_gfx_con.fillbg)\n\t\t\t\t\t\t*fb = g_gfx_con.bgcol;\n\t\t\t\t\tv >>= 1;\n\t\t\t\t\tfb++;\n\t\t\t\t}\n\t\t\t\tfb += g_gfx_ctxt.stride - 8;\n\t\t\t}\n\t\t\tg_gfx_con.x += 8;\n\t\t}\n\t\telse if (c == '\\n')\n\t\t{\n\t\t\tg_gfx_con.x = 0;\n\t\t\tg_gfx_con.y += 8;\n\t\t\tif (g_gfx_con.y > g_gfx_ctxt.height - 8)\n\t\t\t\tg_gfx_con.y = 0;\n\t\t}\n\t\tbreak;\n\t}\n\t\n}\n\nvoid gfx_puts(const char *s)\n{\n\tif (!s || g_gfx_con.mute)\n\t\treturn;\n\n\tfor (; *s; s++)\n\t\tgfx_putc(*s);\n}\n\nstatic void _gfx_putn(u32 v, int base, char fill, int fcnt)\n{\n\tchar buf[65];\n\tstatic const char digits[] = \"0123456789ABCDEFghijklmnopqrstuvwxyz\";\n\tchar *p;\n\tint c = fcnt;\n\n\tif (base > 36)\n\t\treturn;\n\n\tp = buf + 64;\n\t*p = 0;\n\tdo\n\t{\n\t\tc--;\n\t\t*--p = digits[v % base];\n\t\tv /= base;\n\t} while (v);\n\n\tif (fill != 0)\n\t{\n\t\twhile (c > 0)\n\t\t{\n\t\t\t*--p = fill;\n\t\t\tc--;\n\t\t}\n\t}\n\n\tgfx_puts(p);\n}\n\nvoid gfx_put_small_sep()\n{\n\tu8 prevFontSize = g_gfx_con.fntsz;\n\tg_gfx_con.fntsz = 8;\n\tgfx_putc('\\n');\n\tg_gfx_con.fntsz = prevFontSize;\n}\n\nvoid gfx_put_big_sep()\n{\n\tu8 prevFontSize = g_gfx_con.fntsz;\n\tg_gfx_con.fntsz = 16;\n\tgfx_putc('\\n');\n\tg_gfx_con.fntsz = prevFontSize;\n}\n\nvoid gfx_printf(const char *fmt, ...)\n{\n\tif (g_gfx_con.mute)\n\t\treturn;\n\n\tva_list ap;\n\tint fill, fcnt;\n\n\tva_start(ap, fmt);\n\twhile(*fmt)\n\t{\n\t\tif(*fmt == '%')\n\t\t{\n\t\t\tfmt++;\n\t\t\tfill = 0;\n\t\t\tfcnt = 0;\n\t\t\tif ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ')\n\t\t\t{\n\t\t\t\tfcnt = *fmt;\n\t\t\t\tfmt++;\n\t\t\t\tif (*fmt >= '0' && *fmt <= '9')\n\t\t\t\t{\n\t\t\t\t\tfill = fcnt;\n\t\t\t\t\tfcnt = *fmt - '0';\n\t\t\t\t\tfmt++;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfill = ' ';\n\t\t\t\t\tfcnt -= '0';\n\t\t\t\t}\n\t\t\t}\n\t\t\tswitch(*fmt)\n\t\t\t{\n\t\t\tcase 'c':\n\t\t\t\tgfx_putc(va_arg(ap, u32));\n\t\t\t\tbreak;\n\t\t\tcase 's':\n\t\t\t\tgfx_puts(va_arg(ap, char *));\n\t\t\t\tbreak;\n\t\t\tcase 'd':\n\t\t\t\t_gfx_putn(va_arg(ap, u32), 10, fill, fcnt);\n\t\t\t\tbreak;\n\t\t\tcase 'p':\n\t\t\tcase 'P':\n\t\t\tcase 'x':\n\t\t\tcase 'X':\n\t\t\t\t_gfx_putn(va_arg(ap, u32), 16, fill, fcnt);\n\t\t\t\tbreak;\n\t\t\tcase 'k':\n\t\t\t\tg_gfx_con.fgcol = va_arg(ap, u32);\n\t\t\t\tbreak;\n\t\t\tcase 'K':\n\t\t\t\tg_gfx_con.bgcol = va_arg(ap, u32);\n\t\t\t\tg_gfx_con.fillbg = 1;\n\t\t\t\tbreak;\n\t\t\tcase '%':\n\t\t\t\tgfx_putc('%');\n\t\t\t\tbreak;\n\t\t\tcase '\\0':\n\t\t\t\tgoto out;\n\t\t\tdefault:\n\t\t\t\tgfx_putc('%');\n\t\t\t\tgfx_putc(*fmt);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tgfx_putc(*fmt);\n\t\tfmt++;\n\t}\n\n\tout:\n\tva_end(ap);\n}\n\nvoid gfx_hexdump(u32 base, const u8 *buf, u32 len)\n{\n\tif (g_gfx_con.mute)\n\t\treturn;\n\n\tu8 prevFontSize = g_gfx_con.fntsz;\n\tg_gfx_con.fntsz = 8;\n\tfor(u32 i = 0; i < len; i++)\n\t{\n\t\tif(i % 0x10 == 0)\n\t\t{\n\t\t\tif(i != 0)\n\t\t\t{\n\t\t\t\tgfx_puts(\"| \");\n\t\t\t\tfor(u32 j = 0; j < 0x10; j++)\n\t\t\t\t{\n\t\t\t\t\tu8 c = buf[i - 0x10 + j];\n\t\t\t\t\tif(c >= 32 && c <= 126)\n\t\t\t\t\t\tgfx_putc(c);\n\t\t\t\t\telse\n\t\t\t\t\t\tgfx_putc('.');\n\t\t\t\t}\n\t\t\t\tgfx_putc('\\n');\n\t\t\t}\n\t\t\tgfx_printf(\"%08x: \", base + i);\n\t\t}\n\t\tgfx_printf(\"%02x \", buf[i]);\n\t\tif (i == len - 1)\n\t\t{\n\t\t\tint ln = len % 0x10 != 0;\n\t\t\tu32 k = 0x10 - 1;\n\t\t\tif (ln)\n\t\t\t{\n\t\t\t\tk = (len & 0xF) - 1;\n\t\t\t\tfor (u32 j = 0; j < 0x10 - k; j++)\n\t\t\t\t\tgfx_puts(\"   \");\n\t\t\t}\n\t\t\tgfx_puts(\"| \");\n\t\t\tfor(u32 j = 0; j < (ln ? k : k + 1); j++)\n\t\t\t{\n\t\t\t\tu8 c = buf[i - k + j];\n\t\t\t\tif(c >= 32 && c <= 126)\n\t\t\t\t\tgfx_putc(c);\n\t\t\t\telse\n\t\t\t\t\tgfx_putc('.');\n\t\t\t}\n\t\t\tgfx_putc('\\n');\n\t\t}\n\t}\n\tgfx_putc('\\n');\n\tg_gfx_con.fntsz = prevFontSize;\n}\n\nstatic int abs(int x)\n{\n\tif (x < 0)\n\t\treturn -x;\n\treturn x;\n}\n\nvoid gfx_set_pixel(u32 x, u32 y, u32 color)\n{\n\tg_gfx_ctxt.fb[x + y * g_gfx_ctxt.stride] = color;\n}\n\nvoid gfx_line(int x0, int y0, int x1, int y1, u32 color)\n{\n\tint dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;\n\tint dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1;\n\tint err = (dx > dy ? dx : -dy) / 2, e2;\n\n\twhile (1)\n\t{\n\t\tgfx_set_pixel(x0, y0, color);\n\t\tif (x0 == x1 && y0 == y1)\n\t\t\tbreak;\n\t\te2 = err;\n\t\tif (e2 >-dx)\n\t\t{\n\t\t\terr -= dy;\n\t\t\tx0 += sx;\n\t\t}\n\t\tif (e2 < dy)\n\t\t{\n\t\t\terr += dx;\n\t\t\ty0 += sy;\n\t\t}\n\t}\n}\n\nvoid gfx_set_rect_grey(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)\n{\n\tu32 pos = 0;\n\tfor (u32 y = pos_y; y < (pos_y + size_y); y++)\n\t{\n\t\tfor (u32 x = pos_x; x < (pos_x + size_x); x++)\n\t\t{\n\t\t\tmemset(&g_gfx_ctxt.fb[x + y*g_gfx_ctxt.stride], buf[pos], 4);\n\t\t\tpos++;\n\t\t}\n\t}\n}\n\n\nvoid gfx_set_rect_rgb(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)\n{\n\tu32 pos = 0;\n\tfor (u32 y = pos_y; y < (pos_y + size_y); y++)\n\t{\n\t\tfor (u32 x = pos_x; x < (pos_x + size_x); x++)\n\t\t{\n\t\t\tg_gfx_ctxt.fb[x + y * g_gfx_ctxt.stride] = buf[pos + 2] | (buf[pos + 1] << 8) | (buf[pos] << 16);\n\t\t\tpos+=3;\n\t\t}\n\t}\n}\n\nvoid gfx_set_rect_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)\n{\n\tu32 *ptr = (u32 *)buf;\n\tfor (u32 y = pos_y; y < (pos_y + size_y); y++)\n\t\tfor (u32 x = pos_x; x < (pos_x + size_x); x++)\n\t\t\tg_gfx_ctxt.fb[x + y * g_gfx_ctxt.stride] = *ptr++;\n}\n\nvoid gfx_render_bmp_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)\n{\n\tfor (u32 y = pos_y; y < (pos_y + size_y); y++)\n\t{\n\t\tfor (u32 x = pos_x; x < (pos_x + size_x); x++)\n\t\t\tg_gfx_ctxt.fb[x + y * g_gfx_ctxt.stride] = buf[(size_y + pos_y - 1 - y ) * size_x + x - pos_x];\n\t}\n}\n\nvoid gfx_render_splash(u8 *bitmap)\n{\n    bmp_data_t bmp_data;\n    u8 *image = NULL;\n    bool image_found = false;\n\n    if (bitmap != NULL)\n    {\n        // Get values manually to avoid unaligned access.\n        bmp_data.size = bitmap[2] | bitmap[3] << 8 |\n                        bitmap[4] << 16 | bitmap[5] << 24;\n        bmp_data.offset = bitmap[10] | bitmap[11] << 8 |\n                          bitmap[12] << 16 | bitmap[13] << 24;\n        bmp_data.size_x = bitmap[18] | bitmap[19] << 8 |\n                          bitmap[20] << 16 | bitmap[21] << 24;\n        bmp_data.size_y = bitmap[22] | bitmap[23] << 8 |\n                          bitmap[24] << 16 | bitmap[25] << 24;\n        // Sanity check.\n        if (bitmap[0] == 'B' &&\n            bitmap[1] == 'M' &&\n            bitmap[28] == 32 && //\n            bmp_data.size_x <= g_gfx_ctxt.width &&\n            bmp_data.size_y <= g_gfx_ctxt.height)\n        {\n            if ((bmp_data.size - bmp_data.offset) <= 0x400000)\n            {\n                // Avoid unaligned access from BM 2-byte MAGIC and remove header.\n                image = (u8 *)malloc(0x400000);\n                memcpy(image, bitmap + bmp_data.offset, bmp_data.size - bmp_data.offset);\n                bmp_data.pos_x = (g_gfx_ctxt.height - bmp_data.size_x) >> 1;\n                bmp_data.pos_y = (g_gfx_ctxt.width - bmp_data.size_y) >> 1;\n\n                // Get background color from 1st pixel.\n\t\t\t\tif (bmp_data.size_x < g_gfx_ctxt.height || bmp_data.size_y < g_gfx_ctxt.width)\n                    gfx_clear_color(*(u32 *)image);\n                    \n                image_found = true;\n            }\n        }\n\t\telse\n\t\t{\n\t\t\tgfx_printf(\"Sanity check failed...\\n\");\n\t\t}\n    }\n    if (image_found)\n    {\n\t\tu32* buf = (u32*)image;\n\t\tgfx_render_bmp_argb(buf, bmp_data.size_x, bmp_data.size_y, 0, 0);\n    } \n\telse\n\t{\n\t\tgfx_printf(\"Error rendering BMP file\\n\");\n\t}\n\t\n    free(image);\n}"
  },
  {
    "path": "argon-first-stage/src/ianos/ianos.c",
    "content": "/*\n * Copyright (c) 2018 M4xw\n * Copyright (c) 2018-2019 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"ianos/ianos.h\"\n#include \"utils/types.h\"\n#include \"libs/elfload/elfload.h\"\n#include \"mem/heap.h\"\n#include \"gfx/gfx.h\"\n\n#define IRAM_LIB_ADDR 0x4002B000\n#define DRAM_LIB_ADDR 0xE0000000\n\n// Module Callback\ntypedef void (*cbMainModule_t)(const char *s);\ntypedef void (*memcpy_t)(void *, void *, size_t);\ntypedef void (*memset_t)(void *, int, size_t);\n\ntypedef struct _bdkParams_t\n{\n\tgfx_con_t *gfxCon;\n\tgfx_ctxt_t *gfxCtx;\n\theap_t *sharedHeap;\n\tmemcpy_t memcpy;\n\tmemset_t memset;\n} *bdkParams_t;\n\n// Module Entrypoint\ntypedef void (*moduleEntrypoint_t)(void *, bdkParams_t);\n\nextern heap_t _heap;\n\nextern void *sd_file_read(const char *path, u32 *fsize);\nextern bool sd_mount();\nextern void sd_unmount(bool deinit);\n\nvoid *elfBuf = NULL;\nvoid *fileBuf = NULL;\n\nstatic void _ianos_call_ep(moduleEntrypoint_t entrypoint, void *moduleConfig)\n{\n\tbdkParams_t bdkParameters = (bdkParams_t)malloc(sizeof(struct _bdkParams_t));\n\tbdkParameters->gfxCon = &g_gfx_con;\n\tbdkParameters->gfxCtx = &g_gfx_ctxt;\n\tbdkParameters->memcpy = (memcpy_t)&memcpy;\n\tbdkParameters->memset = (memset_t)&memset;\n\tbdkParameters->sharedHeap = &_heap;\n\n\tentrypoint(moduleConfig, bdkParameters);\n}\n\nstatic void *_ianos_alloc_cb(el_ctx *ctx, Elf_Addr phys, Elf_Addr virt, Elf_Addr size)\n{\n\t(void)ctx;\n\t(void)phys;\n\t(void)size;\n\treturn (void *)virt;\n}\n\nstatic bool _ianos_read_cb(el_ctx *ctx, void *dest, size_t numberBytes, size_t offset)\n{\n\t(void)ctx;\n\n\tmemcpy(dest, fileBuf + offset, numberBytes);\n\n\treturn true;\n}\n\n//TODO: Support shared libraries.\nuintptr_t ianos_loader(bool sdmount, char *path, elfType_t type, void *moduleConfig)\n{\n\tuintptr_t epaddr = 0;\n\n\tif (sdmount)\n\t{\n\t\tif (!sd_mount())\n\t\t\tgoto elfLoadFinalOut;\n\t}\n\n\tfileBuf = sd_file_read(path, NULL);\n\n\tif (sdmount)\n\t\tsd_unmount(true);\n\n\tif (!fileBuf)\n\t\tgoto elfLoadFinalOut;\n\n\n\tel_ctx ctx;\n\tctx.pread = _ianos_read_cb;\n\n\tif (el_init(&ctx))\n\t\tgoto elfLoadFinalOut;\n\n\t// Set our relocated library's buffer.\n\tswitch (type & 0xFFFF)\n\t{\n\tcase EXEC_ELF:\n\tcase AR64_ELF:\n\t\telfBuf = (void *)DRAM_LIB_ADDR;\n\t\tsd_unmount(true);\n\t\tbreak;\n\tdefault:\n\t\telfBuf = memalign(ctx.align, ctx.memsz);\n\t}\n\n\tif (!elfBuf)\n\t\tgoto elfLoadFinalOut;\n\n\t// Load and relocate library.\n\tctx.base_load_vaddr = ctx.base_load_paddr = (uintptr_t)elfBuf;\n\tif (el_load(&ctx, _ianos_alloc_cb))\n\t\tgoto elfFreeOut;\n\n\tif (el_relocate(&ctx))\n\t\tgoto elfFreeOut;\n\n\t// Launch.\n\tepaddr = ctx.ehdr.e_entry + (uintptr_t)elfBuf;\n\tmoduleEntrypoint_t ep = (moduleEntrypoint_t)epaddr;\n\n\t_ianos_call_ep(ep, moduleConfig);\n\nelfFreeOut:\n\tfree(fileBuf);\n\telfBuf = NULL;\n\tfileBuf = NULL;\n\nelfLoadFinalOut:\n\n\treturn epaddr;\n}"
  },
  {
    "path": "argon-first-stage/src/libs/compr/blz.c",
    "content": "/*\n * Copyright (c) 2018 rajkosto\n * Copyright (c) 2018 SciresM\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdlib.h>\n#include <string.h>\n\n#include \"libs/compr/blz.h\"\n\nconst blz_footer *blz_get_footer(const unsigned char *compData, unsigned int compDataLen, blz_footer *outFooter)\n{\n\tif (compDataLen < sizeof(blz_footer))\n\t\treturn NULL;\n\n\tconst blz_footer *srcFooter = (const blz_footer*)&compData[compDataLen - sizeof(blz_footer)];\n\tif (outFooter != NULL)\n\t\tmemcpy(outFooter, srcFooter, sizeof(blz_footer)); // Must be a memcpy because no umaligned accesses on ARMv4.\n\n\treturn srcFooter;\n}\n\n// From https://github.com/SciresM/hactool/blob/master/kip.c which is exactly how kernel does it, thanks SciresM!\nint blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const blz_footer *footer) \n{\n\tu32 addl_size = footer->addl_size;\n\tu32 header_size = footer->header_size;\n\tu32 cmp_and_hdr_size = footer->cmp_and_hdr_size;\n\t\n\tunsigned char* cmp_start = &dataBuf[compSize] - cmp_and_hdr_size;\n\tu32 cmp_ofs = cmp_and_hdr_size - header_size;\n\tu32 out_ofs = cmp_and_hdr_size + addl_size;\n\t\n\twhile (out_ofs) \n\t{\n\t\tunsigned char control = cmp_start[--cmp_ofs];\n\t\tfor (unsigned int i=0; i<8; i++) \n\t\t{\n\t\t\tif (control & 0x80) \n\t\t\t{\n\t\t\t\tif (cmp_ofs < 2) \n\t\t\t\t\treturn 0; // Out of bounds.\n\n\t\t\t\tcmp_ofs -= 2;\n\t\t\t\tu16 seg_val = ((unsigned int)(cmp_start[cmp_ofs + 1]) << 8) | cmp_start[cmp_ofs];\n\t\t\t\tu32 seg_size = ((seg_val >> 12) & 0xF) + 3;\n\t\t\t\tu32 seg_ofs = (seg_val & 0x0FFF) + 3;\n\t\t\t\tif (out_ofs < seg_size) // Kernel restricts segment copy to stay in bounds.\n\t\t\t\t\tseg_size = out_ofs;\n\n\t\t\t\tout_ofs -= seg_size;\n\n\t\t\t\tfor (unsigned int j = 0; j < seg_size; j++)\n\t\t\t\t\tcmp_start[out_ofs + j] = cmp_start[out_ofs + j + seg_ofs];\n\t\t\t}\n\t\t\telse \n\t\t\t{\n\t\t\t\t// Copy directly.\n\t\t\t\tif (cmp_ofs < 1) \n\t\t\t\t\treturn 0; //out of bounds\n\n\t\t\t\tcmp_start[--out_ofs] = cmp_start[--cmp_ofs];\n\t\t\t}\n\t\t\tcontrol <<= 1;\n\t\t\tif (out_ofs == 0) // Blz works backwards, so if it reaches byte 0, it's done.\n\t\t\t\treturn 1; \n\t\t\t}\n\t\t}\n\n\treturn 1;\n}\n\nint blz_uncompress_srcdest(const unsigned char *compData, unsigned int compDataLen, unsigned char *dstData, unsigned int dstSize)\n{\n\tblz_footer footer;\n\tconst blz_footer *compFooterPtr = blz_get_footer(compData, compDataLen, &footer);\n\tif (compFooterPtr == NULL)\n\t\treturn 0;\n\n\t// Decompression must be done in-place, so need to copy the relevant compressed data first.\n\tunsigned int numCompBytes = (const unsigned char*)(compFooterPtr)-compData;\n\tmemcpy(dstData, compData, numCompBytes);\n\tmemset(&dstData[numCompBytes], 0, dstSize - numCompBytes);\n\n\treturn blz_uncompress_inplace(dstData, compDataLen, &footer);\n}\n"
  },
  {
    "path": "argon-first-stage/src/libs/compr/lz.c",
    "content": "/*************************************************************************\n* Name:        lz.c\n* Author:      Marcus Geelnard\n* Description: LZ77 coder/decoder implementation.\n* Reentrant:   Yes\n*\n* The LZ77 compression scheme is a substitutional compression scheme\n* proposed by Abraham Lempel and Jakob Ziv in 1977. It is very simple in\n* its design, and uses no fancy bit level compression.\n*\n* This is my first attempt at an implementation of a LZ77 code/decoder.\n*\n* The principle of the LZ77 compression algorithm is to store repeated\n* occurrences of strings as references to previous occurrences of the same\n* string. The point is that the reference consumes less space than the\n* string itself, provided that the string is long enough (in this\n* implementation, the string has to be at least 4 bytes long, since the\n* minimum coded reference is 3 bytes long). Also note that the term\n* \"string\" refers to any kind of byte sequence (it does not have to be\n* an ASCII string, for instance).\n*\n* The coder uses a brute force approach to finding string matches in the\n* history buffer (or \"sliding window\", if you wish), which is very, very\n* slow. I recon the complexity is somewhere between O(n^2) and O(n^3),\n* depending on the input data.\n*\n* There is also a faster implementation that uses a large working buffer\n* in which a \"jump table\" is stored, which is used to quickly find\n* possible string matches (see the source code for LZ_CompressFast() for\n* more information). The faster method is an order of magnitude faster,\n* but still quite slow compared to other compression methods.\n*\n* The upside is that decompression is very fast, and the compression ratio\n* is often very good.\n*\n* The reference to a string is coded as a (length,offset) pair, where the\n* length indicates the length of the string, and the offset gives the\n* offset from the current data position. To distinguish between string\n* references and literal strings (uncompressed bytes), a string reference\n* is preceded by a marker byte, which is chosen as the least common byte\n* symbol in the input data stream (this marker byte is stored in the\n* output stream as the first byte).\n*\n* Occurrences of the marker byte in the stream are encoded as the marker\n* byte followed by a zero byte, which means that occurrences of the marker\n* byte have to be coded with two bytes.\n*\n* The lengths and offsets are coded in a variable length fashion, allowing\n* values of any magnitude (up to 4294967295 in this implementation).\n*\n* With this compression scheme, the worst case compression result is\n* (257/256)*insize + 1.\n*\n*-------------------------------------------------------------------------\n* Copyright (c) 2003-2006 Marcus Geelnard\n*\n* This software is provided 'as-is', without any express or implied\n* warranty. In no event will the authors be held liable for any damages\n* arising from the use of this software.\n*\n* Permission is granted to anyone to use this software for any purpose,\n* including commercial applications, and to alter it and redistribute it\n* freely, subject to the following restrictions:\n*\n* 1. The origin of this software must not be misrepresented; you must not\n*    claim that you wrote the original software. If you use this software\n*    in a product, an acknowledgment in the product documentation would\n*    be appreciated but is not required.\n*\n* 2. Altered source versions must be plainly marked as such, and must not\n*    be misrepresented as being the original software.\n*\n* 3. This notice may not be removed or altered from any source\n*    distribution.\n*\n* Marcus Geelnard\n* marcus.geelnard at home.se\n*************************************************************************/\n\n\n/*************************************************************************\n*                           INTERNAL FUNCTIONS                           *\n*************************************************************************/\n\n\n/*************************************************************************\n* _LZ_ReadVarSize() - Read unsigned integer with variable number of\n* bytes depending on value.\n*************************************************************************/\n\nstatic int _LZ_ReadVarSize( unsigned int * x, const unsigned char * buf )\n{\n    unsigned int y, b, num_bytes;\n\n    /* Read complete value (stop when byte contains zero in 8:th bit) */\n    y = 0;\n    num_bytes = 0;\n    do\n    {\n        b = (unsigned int) (*buf ++);\n        y = (y << 7) | (b & 0x0000007f);\n        ++ num_bytes;\n    }\n    while( b & 0x00000080 );\n\n    /* Store value in x */\n    *x = y;\n\n    /* Return number of bytes read */\n    return num_bytes;\n}\n\n\n\n/*************************************************************************\n*                            PUBLIC FUNCTIONS                            *\n*************************************************************************/\n\n\n/*************************************************************************\n* LZ_Uncompress() - Uncompress a block of data using an LZ77 decoder.\n*  in      - Input (compressed) buffer.\n*  out     - Output (uncompressed) buffer. This buffer must be large\n*            enough to hold the uncompressed data.\n*  insize  - Number of input bytes.\n*************************************************************************/\n\nvoid LZ_Uncompress( const unsigned char *in, unsigned char *out,\n    unsigned int insize )\n{\n    unsigned char marker, symbol;\n    unsigned int  i, inpos, outpos, length, offset;\n\n    /* Do we have anything to uncompress? */\n    if( insize < 1 )\n    {\n        return;\n    }\n\n    /* Get marker symbol from input stream */\n    marker = in[ 0 ];\n    inpos = 1;\n\n    /* Main decompression loop */\n    outpos = 0;\n    do\n    {\n        symbol = in[ inpos ++ ];\n        if( symbol == marker )\n        {\n            /* We had a marker byte */\n            if( in[ inpos ] == 0 )\n            {\n                /* It was a single occurrence of the marker byte */\n                out[ outpos ++ ] = marker;\n                ++ inpos;\n            }\n            else\n            {\n                /* Extract true length and offset */\n                inpos += _LZ_ReadVarSize( &length, &in[ inpos ] );\n                inpos += _LZ_ReadVarSize( &offset, &in[ inpos ] );\n\n                /* Copy corresponding data from history window */\n                for( i = 0; i < length; ++ i )\n                {\n                    out[ outpos ] = out[ outpos - offset ];\n                    ++ outpos;\n                }\n            }\n        }\n        else\n        {\n            /* No marker, plain copy */\n            out[ outpos ++ ] = symbol;\n        }\n    }\n    while( inpos < insize );\n}\n"
  },
  {
    "path": "argon-first-stage/src/libs/elfload/elfload.c",
    "content": "/*\n * Copyright © 2018, M4xw\n * Copyright © 2014, Owen Shepherd\n *\n * Permission to use, copy, modify, and/or distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\n * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\n * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n * PERFORMANCE OF THIS SOFTWARE.\n */\n \n#include <string.h>\n\n#include \"libs/elfload/elfload.h\"\n\nel_status el_pread(el_ctx *ctx, void *def, size_t nb, size_t offset)\n{\n\treturn ctx->pread(ctx, def, nb, offset) ? EL_OK : EL_EIO;\n}\n\n#define EL_PHOFF(ctx, num) (((ctx)->ehdr.e_phoff + (num) *(ctx)->ehdr.e_phentsize))\nel_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, uint32_t type, unsigned *i)\n{\n\tel_status rv = EL_OK;\n\tfor (; *i < ctx->ehdr.e_phnum; (*i)++)\n\t{\n\t\tif ((rv = el_pread(ctx, phdr, sizeof *phdr, EL_PHOFF(ctx, *i))))\n\t\t\treturn rv;\n\n\t\tif (phdr->p_type == type)\n\t\t{\n\t\t\treturn rv;\n\t\t}\n\t}\n\n\t*i = -1;\n\treturn rv;\n}\n\n#define EL_SHOFF(ctx, num) (((ctx)->ehdr.e_shoff + (num) *(ctx)->ehdr.e_shentsize))\nel_status el_findshdr(el_ctx *ctx, Elf_Shdr *shdr, uint32_t type, unsigned *i)\n{\n\tel_status rv = EL_OK;\n\n\tfor (; *i < ctx->ehdr.e_shnum; (*i)++)\n\t{\n\t\tif ((rv = el_pread(ctx, shdr, sizeof *shdr, EL_SHOFF(ctx, *i))))\n\n\t\t\treturn rv;\n\n\t\tif (shdr->sh_type == type)\n\t\t{\n\t\t\treturn rv;\n\t\t}\n\t}\n\n\t*i = -1;\n\n\treturn rv;\n}\n\nel_status el_init(el_ctx *ctx)\n{\n\tel_status rv = EL_OK;\n\tif ((rv = el_pread(ctx, &ctx->ehdr, sizeof ctx->ehdr, 0)))\n\t\treturn rv;\n\n\t/* validate header */\n\n\tif (!IS_ELF(ctx->ehdr))\n\t\treturn EL_NOTELF;\n\n\tif (ctx->ehdr.e_ident[EI_CLASS] != ELFCLASS)\n\t\treturn EL_WRONGBITS;\n\n\tif (ctx->ehdr.e_ident[EI_DATA] != ELFDATATHIS)\n\t\treturn EL_WRONGENDIAN;\n\n\tif (ctx->ehdr.e_ident[EI_VERSION] != EV_CURRENT)\n\t\treturn EL_NOTELF;\n\n\tif (ctx->ehdr.e_type != ET_EXEC && ctx->ehdr.e_type != ET_DYN)\n\t\treturn EL_NOTEXEC;\n\n\tif (ctx->ehdr.e_machine != EM_THIS)\n\t\treturn EL_WRONGARCH;\n\n\tif (ctx->ehdr.e_version != EV_CURRENT)\n\t\treturn EL_NOTELF;\n\n\t/* load phdrs */\n\tElf_Phdr ph;\n\n\t/* iterate through, calculate extents */\n\tctx->base_load_paddr = ctx->base_load_vaddr = 0;\n\tctx->align = 1;\n\tctx->memsz = 0;\n\n\tunsigned i = 0;\n\tfor (;;)\n\t{\n\t\tif ((rv = el_findphdr(ctx, &ph, PT_LOAD, &i)))\n\t\t\treturn rv;\n\n\t\tif (i == (unsigned)-1)\n\t\t\tbreak;\n\n\t\tElf_Addr phend = ph.p_vaddr + ph.p_memsz;\n\t\tif (phend > ctx->memsz)\n\t\t\tctx->memsz = phend;\n\n\t\tif (ph.p_align > ctx->align)\n\t\t\tctx->align = ph.p_align;\n\n\t\ti++;\n\t}\n\n\t// Program Header\n\tif (ctx->ehdr.e_type == ET_DYN)\n\t{\n\t\ti = 0;\n\n\t\tif ((rv = el_findphdr(ctx, &ph, PT_DYNAMIC, &i)))\n\t\t\treturn rv;\n\n\t\tif (i == (unsigned)-1)\n\t\t\treturn EL_NODYN;\n\n\t\tctx->dynoff = ph.p_offset;\n\t\tctx->dynsize = ph.p_filesz;\n\t}\n\telse\n\t{\n\t\tctx->dynoff = 0;\n\t\tctx->dynsize = 0;\n\t}\n\n\t// Section String Table\n\tif (ctx->ehdr.e_type == ET_DYN)\n\t{\n\t\ti = ctx->ehdr.e_shstrndx - 1;\n\n\t\tif ((rv = el_findshdr(ctx, &ctx->shstr, SHT_STRTAB, &i)))\n\t\t\treturn rv;\n\n\t\t// Reset\n\t\ti = 0;\n\n\t\tif ((rv = el_findshdr(ctx, &ctx->symtab, SHT_SYMTAB, &i)))\n\t\t\treturn rv;\n\n\t\tif (i == (unsigned)-1)\n\t\t\treturn EL_NODYN;\n\t}\n\n\treturn rv;\n}\n\n/*\ntypedef void* (*el_alloc_cb)(\n\tel_ctx *ctx,\n\tElf_Addr phys,\n\tElf_Addr virt,\n\tElf_Addr size);\n*/\n\nel_status el_load(el_ctx *ctx, el_alloc_cb alloc)\n{\n\tel_status rv = EL_OK;\n\n\t/* address deltas */\n\tElf_Addr pdelta = ctx->base_load_paddr;\n\tElf_Addr vdelta = ctx->base_load_vaddr;\n\n\t/* iterate paddrs */\n\tElf_Phdr ph;\n\tunsigned i = 0;\n\tfor (;;)\n\t{\n\t\tif ((rv = el_findphdr(ctx, &ph, PT_LOAD, &i)))\n\t\t\treturn rv;\n\n\t\tif (i == (unsigned)-1)\n\t\t\tbreak;\n\n\t\tElf_Addr pload = ph.p_paddr + pdelta;\n\t\tElf_Addr vload = ph.p_vaddr + vdelta;\n\n\t\t/* allocate mem */\n\t\tchar *dest = alloc(ctx, pload, vload, ph.p_memsz);\n\t\tif (!dest)\n\t\t\treturn EL_ENOMEM;\n\n\t\tEL_DEBUG(\"Loading seg fileoff %x, vaddr %x to %p\\n\",\n\t\t\t\tph.p_offset, ph.p_vaddr, dest);\n\n\t\t/* read loaded portion */\n\t\tif ((rv = el_pread(ctx, dest, ph.p_filesz, ph.p_offset)))\n\t\t\treturn rv;\n\n\t\t/* zero mem-only portion */\n\t\tmemset(dest + ph.p_filesz, 0, ph.p_memsz - ph.p_filesz);\n\n\t\ti++;\n\t}\n\n\treturn rv;\n}\n\nel_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, uint32_t tag)\n{\n\tel_status rv = EL_OK;\n\tsize_t ndyn = ctx->dynsize / sizeof(Elf_Dyn);\n\n\tfor (unsigned i = 0; i < ndyn; i++)\n\t{\n\t\tif ((rv = el_pread(ctx, dyn, sizeof *dyn, ctx->dynoff + i * sizeof *dyn)))\n\t\t\treturn rv;\n\n\t\tif (dyn->d_tag == tag)\n\t\t\treturn EL_OK;\n\t}\n\n\tdyn->d_tag = DT_NULL;\n\treturn EL_OK;\n}\n\nel_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, uint32_t type)\n{\n\tel_status rv = EL_OK;\n\n\tElf_Dyn rel, relsz, relent;\n\n\tif ((rv = el_finddyn(ctx, &rel, type)))\n\t\treturn rv;\n\n\tif ((rv = el_finddyn(ctx, &relsz, type + 1)))\n\t\treturn rv;\n\n\tif ((rv = el_finddyn(ctx, &relent, type + 2)))\n\t\treturn rv;\n\n\tif (rel.d_tag == DT_NULL || relsz.d_tag == DT_NULL || relent.d_tag == DT_NULL)\n\t{\n\t\tri->entrysize = 0;\n\t\tri->tablesize = 0;\n\t\tri->tableoff = 0;\n\t}\n\telse\n\t{\n\t\tri->tableoff = rel.d_un.d_ptr;\n\t\tri->tablesize = relsz.d_un.d_val;\n\t\tri->entrysize = relent.d_un.d_val;\n\t}\n\n\treturn rv;\n}\n\nextern el_status el_applyrel(el_ctx *ctx, Elf_Rel *rel);\nextern el_status el_applyrela(el_ctx *ctx, Elf_RelA *rela);\n\nel_status el_relocate(el_ctx *ctx)\n{\n\tel_status rv = EL_OK;\n\n\t// not dynamic\n\tif (ctx->ehdr.e_type != ET_DYN)\n\t\treturn EL_OK;\n\n\tchar *base = (char *)ctx->base_load_paddr;\n\n\tel_relocinfo ri;\n#ifdef EL_ARCH_USES_REL\n\tif ((rv = el_findrelocs(ctx, &ri, DT_REL)))\n\t\treturn rv;\n\n\tif (ri.entrysize != sizeof(Elf_Rel) && ri.tablesize)\n\t{\n\t\tEL_DEBUG(\"Relocation size %u doesn't match expected %u\\n\",\n\t\t\t\tri.entrysize, sizeof(Elf_Rel));\n\t\treturn EL_BADREL;\n\t}\n\n\tsize_t relcnt = ri.tablesize / sizeof(Elf_Rel);\n\tElf_Rel *reltab = (Elf_Rel *)(base + ri.tableoff);\n\tfor (size_t i = 0; i < relcnt; i++)\n\t{\n\t\tif ((rv = el_applyrel(ctx, &reltab[i])))\n\t\t\treturn rv;\n\t}\n#endif\n\n#ifdef EL_ARCH_USES_RELA\n\tif ((rv = el_findrelocs(ctx, &ri, DT_RELA)))\n\t\treturn rv;\n\n\tif (ri.entrysize != sizeof(Elf_RelA) && ri.tablesize)\n\t{\n\t\tEL_DEBUG(\"Relocation size %u doesn't match expected %u\\n\",\n\t\t\t\tri.entrysize, sizeof(Elf_RelA));\n\t\treturn EL_BADREL;\n\t}\n\n\tsize_t relacnt = ri.tablesize / sizeof(Elf_RelA);\n\tElf_RelA *relatab = (Elf_RelA *)(base + ri.tableoff);\n\tfor (size_t i = 0; i < relacnt; i++)\n\t{\n\t\tif ((rv = el_applyrela(ctx, &relatab[i])))\n\t\t\treturn rv;\n\t}\n#endif\n\n#if !defined(EL_ARCH_USES_REL) && !defined(EL_ARCH_USES_RELA)\n#error No relocation type defined!\n#endif\n\n\treturn rv;\n}\n"
  },
  {
    "path": "argon-first-stage/src/libs/elfload/elfreloc_aarch64.c",
    "content": "\n/*\n * Copyright © 2014, Owen Shepherd\n *\n * Permission to use, copy, modify, and/or distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\n * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\n * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n * PERFORMANCE OF THIS SOFTWARE.\n */\n\n#include \"libs/elfload/elfload.h\"\n\n#if defined(__aarch64__)\n\n#define R_AARCH64_NONE 0\n#define R_AARCH64_RELATIVE 1027\n\nel_status el_applyrela(el_ctx *ctx, Elf_RelA *rel)\n{\n\tuintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr);\n\tuint32_t type = ELF_R_TYPE(rel->r_info);\n\tuint32_t sym = ELF_R_SYM(rel->r_info);\n\n\tswitch (type)\n\t{\n\tcase R_AARCH64_NONE:\n\t\tEL_DEBUG(\"R_AARCH64_NONE\\n\");\n\t\tbreak;\n\tcase R_AARCH64_RELATIVE:\n\t\tif (sym)\n\t\t{\n\t\t\tEL_DEBUG(\"R_AARCH64_RELATIVE with symbol ref!\\n\");\n\t\t\treturn EL_BADREL;\n\t\t}\n\n\t\tEL_DEBUG(\"Applying R_AARCH64_RELATIVE reloc @%p\\n\", p);\n\t\t*p = rel->r_addend + ctx->base_load_vaddr;\n\t\tbreak;\n\n\tdefault:\n\t\tEL_DEBUG(\"Bad relocation %u\\n\", type);\n\t\treturn EL_BADREL;\n\t}\n\n\treturn EL_OK;\n}\n\nel_status el_applyrel(el_ctx *ctx, Elf_Rel *rel)\n{\n\tuintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr);\n\tuint32_t type = ELF_R_TYPE(rel->r_info);\n\tuint32_t sym = ELF_R_SYM(rel->r_info);\n\n\tswitch (type)\n\t{\n\tcase R_AARCH64_NONE:\n\t\tEL_DEBUG(\"R_AARCH64_NONE\\n\");\n\t\tbreak;\n\tcase R_AARCH64_RELATIVE:\n\t\tif (sym)\n\t\t{\n\t\t\tEL_DEBUG(\"R_AARCH64_RELATIVE with symbol ref!\\n\");\n\t\t\treturn EL_BADREL;\n\t\t}\n\n\t\tEL_DEBUG(\"Applying R_AARCH64_RELATIVE reloc @%p\\n\", p);\n\t\t*p += ctx->base_load_vaddr;\n\t\tbreak;\n\n\tdefault:\n\t\tEL_DEBUG(\"Bad relocation %u\\n\", type);\n\t\treturn EL_BADREL;\n\t}\n\n\treturn EL_OK;\n}\n\n#endif"
  },
  {
    "path": "argon-first-stage/src/libs/elfload/elfreloc_arm.c",
    "content": "\n/*\n * ----------------------------------------------------------------------------\n * \"THE BEER-WARE LICENSE\" (Revision 42):\n * <m4x@m4xw.net> wrote this file. As long as you retain this notice you can do\n * whatever you want with this stuff. If we meet some day, and you think this\n * stuff is worth it, you can buy me a beer in return.                     M4xw\n * ----------------------------------------------------------------------------\n */\n\n#include \"libs/elfload/elfload.h\"\n\n#if defined(__arm__)\n\n// Taken from http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044f/IHI0044F_aaelf.pdf\n#define R_ARM_NONE 0\n#define R_ARM_ABS32 2\n#define R_ARM_JUMP_SLOT 22\n#define R_ARM_GLOB_DAT 21\n#define R_ARM_RELATIVE 23\n\nel_status el_applyrel(el_ctx *ctx, Elf_Rel *rel)\n{\n\tuint32_t sym = ELF_R_SYM(rel->r_info);                              // Symbol offset\n\tuint32_t type = ELF_R_TYPE(rel->r_info);                            // Relocation Type\n\tuintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr); // Target Addr\n\n#if 0 // For later symbol usage\n\tElf32_Sym *elfSym;\n\tconst char *symbolName;\n\n\t// We resolve relocs from the originating elf-image\n\telfSym = (Elf32_Sym *)(ctx->symtab.sh_offset + (char *)buffteg) + sym;\n\tint strtab_offset = ctx->shstr.sh_offset;\n\tchar *strtab = (char *)buffteg + strtab_offset;\n\tsymbolName = strtab + elfSym->st_name;\n\t//EL_DEBUG(\"Str: %s sz: %x val: %x\\n\", symbolName, elfSym->st_size, elfSym->st_value);\n#endif\n\n\tswitch (type)\n\t{\n\tcase R_ARM_NONE:\n\t\tEL_DEBUG(\"R_ARM_NONE\\n\");\n\t\tbreak;\n\tcase R_ARM_JUMP_SLOT:\n\tcase R_ARM_ABS32:\n\tcase R_ARM_GLOB_DAT:\n\t\t// Stubbed for later purpose\n\t\t//*p += elfSym->st_value; // + vaddr from sec\n\t\t//*p |= 0; // 1 if Thumb && STT_FUNC, ignored for now\n\t\tbreak;\n\tcase R_ARM_RELATIVE: // Needed for PIE\n\t\tif (sym)\n\t\t{\n\t\t\treturn EL_BADREL;\n\t\t}\n\t\t*p += ctx->base_load_vaddr;\n\t\tbreak;\n\n\tdefault:\n\t\treturn EL_BADREL;\n\t}\n\n\treturn EL_OK;\n}\n\n#endif"
  },
  {
    "path": "argon-first-stage/src/libs/fatfs/diskio.c",
    "content": "/*-----------------------------------------------------------------------*/\n/* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2016        */\n/*-----------------------------------------------------------------------*/\n/* If a working storage control module is available, it should be        */\n/* attached to the FatFs via a glue function rather than modifying it.   */\n/* This is an example of glue functions to attach various exsisting      */\n/* storage control modules to the FatFs module with a defined API.       */\n/*-----------------------------------------------------------------------*/\n\n#include <string.h>\n#include \"libs/fatfs/diskio.h\"\t\t/* FatFs lower layer API */\n#include \"storage/sdmmc.h\"\n\n#define SDMMC_UPPER_BUFFER 0xB8000000\n#define DRAM_START         0x80000000\n\nextern sdmmc_storage_t g_sd_storage;\n\n/*-----------------------------------------------------------------------*/\n/* Get Drive Status                                                      */\n/*-----------------------------------------------------------------------*/\nDSTATUS disk_status (\n\tBYTE pdrv\t\t/* Physical drive nmuber to identify the drive */\n)\n{\n\treturn 0;\n}\n\n/*-----------------------------------------------------------------------*/\n/* Inidialize a Drive                                                    */\n/*-----------------------------------------------------------------------*/\nDSTATUS disk_initialize (\n\tBYTE pdrv\t\t\t\t/* Physical drive nmuber to identify the drive */\n)\n{\n\treturn 0;\n}\n\n/*-----------------------------------------------------------------------*/\n/* Read Sector(s)                                                        */\n/*-----------------------------------------------------------------------*/\nDRESULT disk_read (\n\tBYTE pdrv,\t\t/* Physical drive nmuber to identify the drive */\n\tBYTE *buff,\t\t/* Data buffer to store read data */\n\tDWORD sector,\t/* Start sector in LBA */\n\tUINT count\t\t/* Number of sectors to read */\n)\n{\n\tif ((u32)buff >= DRAM_START)\n\t\treturn sdmmc_storage_read(&g_sd_storage, sector, count, buff) ? RES_OK : RES_ERROR;\n\tu8 *buf = (u8 *)SDMMC_UPPER_BUFFER;\n\tif (sdmmc_storage_read(&g_sd_storage, sector, count, buf))\n\t{\n\t\tmemcpy(buff, buf, 512 * count);\n\t\treturn RES_OK;\n\t}\n\treturn RES_ERROR;\n}\n\n/*-----------------------------------------------------------------------*/\n/* Write Sector(s)                                                       */\n/*-----------------------------------------------------------------------*/\nDRESULT disk_write (\n\tBYTE pdrv,\t\t\t/* Physical drive nmuber to identify the drive */\n\tconst BYTE *buff,\t/* Data to be written */\n\tDWORD sector,\t\t/* Start sector in LBA */\n\tUINT count\t\t\t/* Number of sectors to write */\n)\n{\n\tif ((u32)buff >= DRAM_START)\n\t\treturn sdmmc_storage_write(&g_sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;\n\tu8 *buf = (u8 *)SDMMC_UPPER_BUFFER; //TODO: define this somewhere.\n\tmemcpy(buf, buff, 512 * count);\n\tif (sdmmc_storage_write(&g_sd_storage, sector, count, buf))\n\t\treturn RES_OK;\n\treturn RES_ERROR;\n}\n\n/*-----------------------------------------------------------------------*/\n/* Miscellaneous Functions                                               */\n/*-----------------------------------------------------------------------*/\nDRESULT disk_ioctl (\n\tBYTE pdrv,\t\t/* Physical drive nmuber (0..) */\n\tBYTE cmd,\t\t/* Control code */\n\tvoid *buff\t\t/* Buffer to send/receive control data */\n)\n{\n\treturn RES_OK;\n}\n"
  },
  {
    "path": "argon-first-stage/src/libs/fatfs/ff.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018-2019 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n/*----------------------------------------------------------------------------/\n/  FatFs - Generic FAT Filesystem Module  R0.13c (p3)                         /\n/-----------------------------------------------------------------------------/\n/\n/ Copyright (C) 2018, ChaN, all right reserved.\n/\n/ FatFs module is an open source software. Redistribution and use of FatFs in\n/ source and binary forms, with or without modification, are permitted provided\n/ that the following condition is met:\n/\n/ 1. Redistributions of source code must retain the above copyright notice,\n/    this condition and the following disclaimer.\n/\n/ This software is provided by the copyright holder and contributors \"AS IS\"\n/ and any warranties related to this software are DISCLAIMED.\n/ The copyright owner or contributors be NOT LIABLE for any damages caused\n/ by use of this software.\n/\n/----------------------------------------------------------------------------*/\n\n\n#include \"libs/fatfs/ff.h\"\t\t\t/* Declarations of FatFs API */\n#include \"libs/fatfs/diskio.h\"\t\t/* Declarations of device I/O functions */\n#include \"gfx/gfx.h\"\n\n#pragma GCC push_options\n#pragma GCC target (\"thumb\")\n\n#define EFSPRINTF(text, ...) print_error(); gfx_printf(\"%k\"text\"%k\\n\", 0xFFFFFF00, 0xFFFFFFFF);\n//#define EFSPRINTF(...)\n\n/*--------------------------------------------------------------------------\n\n   Module Private Definitions\n\n---------------------------------------------------------------------------*/\n\n#if FF_DEFINED != 86604\t/* Revision ID */\n#error Wrong include file (ff.h).\n#endif\n\n\n/* Limits and boundaries */\n#define MAX_DIR\t\t0x200000\t\t/* Max size of FAT directory */\n#define MAX_DIR_EX\t0x10000000\t\t/* Max size of exFAT directory */\n#define MAX_FAT12\t0xFF5\t\t\t/* Max FAT12 clusters (differs from specs, but right for real DOS/Windows behavior) */\n#define MAX_FAT16\t0xFFF5\t\t\t/* Max FAT16 clusters (differs from specs, but right for real DOS/Windows behavior) */\n#define MAX_FAT32\t0x0FFFFFF5\t\t/* Max FAT32 clusters (not specified, practical limit) */\n#define MAX_EXFAT\t0x7FFFFFFD\t\t/* Max exFAT clusters (differs from specs, implementation limit) */\n\n\n/* Character code support macros */\n#define IsUpper(c)\t\t((c) >= 'A' && (c) <= 'Z')\n#define IsLower(c)\t\t((c) >= 'a' && (c) <= 'z')\n#define IsDigit(c)\t\t((c) >= '0' && (c) <= '9')\n#define IsSurrogate(c)\t((c) >= 0xD800 && (c) <= 0xDFFF)\n#define IsSurrogateH(c)\t((c) >= 0xD800 && (c) <= 0xDBFF)\n#define IsSurrogateL(c)\t((c) >= 0xDC00 && (c) <= 0xDFFF)\n\n\n/* Additional file access control and file status flags for internal use */\n#define FA_SEEKEND\t0x20\t/* Seek to end of the file on file open */\n#define FA_MODIFIED\t0x40\t/* File has been modified */\n#define FA_DIRTY\t0x80\t/* FIL.buf[] needs to be written-back */\n\n\n/* Additional file attribute bits for internal use */\n#define AM_VOL\t\t0x08\t/* Volume label */\n#define AM_LFN\t\t0x0F\t/* LFN entry */\n#define AM_MASK\t\t0x3F\t/* Mask of defined bits */\n\n\n/* Name status flags in fn[11] */\n#define NSFLAG\t\t11\t\t/* Index of the name status byte */\n#define NS_LOSS\t\t0x01\t/* Out of 8.3 format */\n#define NS_LFN\t\t0x02\t/* Force to create LFN entry */\n#define NS_LAST\t\t0x04\t/* Last segment */\n#define NS_BODY\t\t0x08\t/* Lower case flag (body) */\n#define NS_EXT\t\t0x10\t/* Lower case flag (ext) */\n#define NS_DOT\t\t0x20\t/* Dot entry */\n#define NS_NOLFN\t0x40\t/* Do not find LFN */\n#define NS_NONAME\t0x80\t/* Not followed */\n\n\n/* exFAT directory entry types */\n#define\tET_BITMAP\t0x81\t/* Allocation bitmap */\n#define\tET_UPCASE\t0x82\t/* Up-case table */\n#define\tET_VLABEL\t0x83\t/* Volume label */\n#define\tET_FILEDIR\t0x85\t/* File and directory */\n#define\tET_STREAM\t0xC0\t/* Stream extension */\n#define\tET_FILENAME\t0xC1\t/* Name extension */\n\n\n/* FatFs refers the FAT structure as simple byte array instead of structure member\n/ because the C structure is not binary compatible between different platforms */\n\n#define BS_JmpBoot\t\t\t0\t\t/* x86 jump instruction (3-byte) */\n#define BS_OEMName\t\t\t3\t\t/* OEM name (8-byte) */\n#define BPB_BytsPerSec\t\t11\t\t/* Sector size [byte] (WORD) */\n#define BPB_SecPerClus\t\t13\t\t/* Cluster size [sector] (BYTE) */\n#define BPB_RsvdSecCnt\t\t14\t\t/* Size of reserved area [sector] (WORD) */\n#define BPB_NumFATs\t\t\t16\t\t/* Number of FATs (BYTE) */\n#define BPB_RootEntCnt\t\t17\t\t/* Size of root directory area for FAT [entry] (WORD) */\n#define BPB_TotSec16\t\t19\t\t/* Volume size (16-bit) [sector] (WORD) */\n#define BPB_Media\t\t\t21\t\t/* Media descriptor byte (BYTE) */\n#define BPB_FATSz16\t\t\t22\t\t/* FAT size (16-bit) [sector] (WORD) */\n#define BPB_SecPerTrk\t\t24\t\t/* Number of sectors per track for int13h [sector] (WORD) */\n#define BPB_NumHeads\t\t26\t\t/* Number of heads for int13h (WORD) */\n#define BPB_HiddSec\t\t\t28\t\t/* Volume offset from top of the drive (DWORD) */\n#define BPB_TotSec32\t\t32\t\t/* Volume size (32-bit) [sector] (DWORD) */\n#define BS_DrvNum\t\t\t36\t\t/* Physical drive number for int13h (BYTE) */\n#define BS_NTres\t\t\t37\t\t/* WindowsNT error flag (BYTE) */\n#define BS_BootSig\t\t\t38\t\t/* Extended boot signature (BYTE) */\n#define BS_VolID\t\t\t39\t\t/* Volume serial number (DWORD) */\n#define BS_VolLab\t\t\t43\t\t/* Volume label string (8-byte) */\n#define BS_FilSysType\t\t54\t\t/* Filesystem type string (8-byte) */\n#define BS_BootCode\t\t\t62\t\t/* Boot code (448-byte) */\n#define BS_55AA\t\t\t\t510\t\t/* Signature word (WORD) */\n\n#define BPB_FATSz32\t\t\t36\t\t/* FAT32: FAT size [sector] (DWORD) */\n#define BPB_ExtFlags32\t\t40\t\t/* FAT32: Extended flags (WORD) */\n#define BPB_FSVer32\t\t\t42\t\t/* FAT32: Filesystem version (WORD) */\n#define BPB_RootClus32\t\t44\t\t/* FAT32: Root directory cluster (DWORD) */\n#define BPB_FSInfo32\t\t48\t\t/* FAT32: Offset of FSINFO sector (WORD) */\n#define BPB_BkBootSec32\t\t50\t\t/* FAT32: Offset of backup boot sector (WORD) */\n#define BS_DrvNum32\t\t\t64\t\t/* FAT32: Physical drive number for int13h (BYTE) */\n#define BS_NTres32\t\t\t65\t\t/* FAT32: Error flag (BYTE) */\n#define BS_BootSig32\t\t66\t\t/* FAT32: Extended boot signature (BYTE) */\n#define BS_VolID32\t\t\t67\t\t/* FAT32: Volume serial number (DWORD) */\n#define BS_VolLab32\t\t\t71\t\t/* FAT32: Volume label string (8-byte) */\n#define BS_FilSysType32\t\t82\t\t/* FAT32: Filesystem type string (8-byte) */\n#define BS_BootCode32\t\t90\t\t/* FAT32: Boot code (420-byte) */\n\n#define BPB_ZeroedEx\t\t11\t\t/* exFAT: MBZ field (53-byte) */\n#define BPB_VolOfsEx\t\t64\t\t/* exFAT: Volume offset from top of the drive [sector] (QWORD) */\n#define BPB_TotSecEx\t\t72\t\t/* exFAT: Volume size [sector] (QWORD) */\n#define BPB_FatOfsEx\t\t80\t\t/* exFAT: FAT offset from top of the volume [sector] (DWORD) */\n#define BPB_FatSzEx\t\t\t84\t\t/* exFAT: FAT size [sector] (DWORD) */\n#define BPB_DataOfsEx\t\t88\t\t/* exFAT: Data offset from top of the volume [sector] (DWORD) */\n#define BPB_NumClusEx\t\t92\t\t/* exFAT: Number of clusters (DWORD) */\n#define BPB_RootClusEx\t\t96\t\t/* exFAT: Root directory start cluster (DWORD) */\n#define BPB_VolIDEx\t\t\t100\t\t/* exFAT: Volume serial number (DWORD) */\n#define BPB_FSVerEx\t\t\t104\t\t/* exFAT: Filesystem version (WORD) */\n#define BPB_VolFlagEx\t\t106\t\t/* exFAT: Volume flags (WORD) */\n#define BPB_BytsPerSecEx\t108\t\t/* exFAT: Log2 of sector size in unit of byte (BYTE) */\n#define BPB_SecPerClusEx\t109\t\t/* exFAT: Log2 of cluster size in unit of sector (BYTE) */\n#define BPB_NumFATsEx\t\t110\t\t/* exFAT: Number of FATs (BYTE) */\n#define BPB_DrvNumEx\t\t111\t\t/* exFAT: Physical drive number for int13h (BYTE) */\n#define BPB_PercInUseEx\t\t112\t\t/* exFAT: Percent in use (BYTE) */\n#define BPB_RsvdEx\t\t\t113\t\t/* exFAT: Reserved (7-byte) */\n#define BS_BootCodeEx\t\t120\t\t/* exFAT: Boot code (390-byte) */\n\n#define DIR_Name\t\t\t0\t\t/* Short file name (11-byte) */\n#define DIR_Attr\t\t\t11\t\t/* Attribute (BYTE) */\n#define DIR_NTres\t\t\t12\t\t/* Lower case flag (BYTE) */\n#define DIR_CrtTime10\t\t13\t\t/* Created time sub-second (BYTE) */\n#define DIR_CrtTime\t\t\t14\t\t/* Created time (DWORD) */\n#define DIR_LstAccDate\t\t18\t\t/* Last accessed date (WORD) */\n#define DIR_FstClusHI\t\t20\t\t/* Higher 16-bit of first cluster (WORD) */\n#define DIR_ModTime\t\t\t22\t\t/* Modified time (DWORD) */\n#define DIR_FstClusLO\t\t26\t\t/* Lower 16-bit of first cluster (WORD) */\n#define DIR_FileSize\t\t28\t\t/* File size (DWORD) */\n#define LDIR_Ord\t\t\t0\t\t/* LFN: LFN order and LLE flag (BYTE) */\n#define LDIR_Attr\t\t\t11\t\t/* LFN: LFN attribute (BYTE) */\n#define LDIR_Type\t\t\t12\t\t/* LFN: Entry type (BYTE) */\n#define LDIR_Chksum\t\t\t13\t\t/* LFN: Checksum of the SFN (BYTE) */\n#define LDIR_FstClusLO\t\t26\t\t/* LFN: MBZ field (WORD) */\n#define XDIR_Type\t\t\t0\t\t/* exFAT: Type of exFAT directory entry (BYTE) */\n#define XDIR_NumLabel\t\t1\t\t/* exFAT: Number of volume label characters (BYTE) */\n#define XDIR_Label\t\t\t2\t\t/* exFAT: Volume label (11-WORD) */\n#define XDIR_CaseSum\t\t4\t\t/* exFAT: Sum of case conversion table (DWORD) */\n#define XDIR_NumSec\t\t\t1\t\t/* exFAT: Number of secondary entries (BYTE) */\n#define XDIR_SetSum\t\t\t2\t\t/* exFAT: Sum of the set of directory entries (WORD) */\n#define XDIR_Attr\t\t\t4\t\t/* exFAT: File attribute (WORD) */\n#define XDIR_CrtTime\t\t8\t\t/* exFAT: Created time (DWORD) */\n#define XDIR_ModTime\t\t12\t\t/* exFAT: Modified time (DWORD) */\n#define XDIR_AccTime\t\t16\t\t/* exFAT: Last accessed time (DWORD) */\n#define XDIR_CrtTime10\t\t20\t\t/* exFAT: Created time subsecond (BYTE) */\n#define XDIR_ModTime10\t\t21\t\t/* exFAT: Modified time subsecond (BYTE) */\n#define XDIR_CrtTZ\t\t\t22\t\t/* exFAT: Created timezone (BYTE) */\n#define XDIR_ModTZ\t\t\t23\t\t/* exFAT: Modified timezone (BYTE) */\n#define XDIR_AccTZ\t\t\t24\t\t/* exFAT: Last accessed timezone (BYTE) */\n#define XDIR_GenFlags\t\t33\t\t/* exFAT: General secondary flags (BYTE) */\n#define XDIR_NumName\t\t35\t\t/* exFAT: Number of file name characters (BYTE) */\n#define XDIR_NameHash\t\t36\t\t/* exFAT: Hash of file name (WORD) */\n#define XDIR_ValidFileSize\t40\t\t/* exFAT: Valid file size (QWORD) */\n#define XDIR_FstClus\t\t52\t\t/* exFAT: First cluster of the file data (DWORD) */\n#define XDIR_FileSize\t\t56\t\t/* exFAT: File/Directory size (QWORD) */\n\n#define SZDIRE\t\t\t\t32\t\t/* Size of a directory entry */\n#define DDEM\t\t\t\t0xE5\t/* Deleted directory entry mark set to DIR_Name[0] */\n#define RDDEM\t\t\t\t0x05\t/* Replacement of the character collides with DDEM */\n#define LLEF\t\t\t\t0x40\t/* Last long entry flag in LDIR_Ord */\n\n#define FSI_LeadSig\t\t\t0\t\t/* FAT32 FSI: Leading signature (DWORD) */\n#define FSI_StrucSig\t\t484\t\t/* FAT32 FSI: Structure signature (DWORD) */\n#define FSI_Free_Count\t\t488\t\t/* FAT32 FSI: Number of free clusters (DWORD) */\n#define FSI_Nxt_Free\t\t492\t\t/* FAT32 FSI: Last allocated cluster (DWORD) */\n\n#define MBR_Table\t\t\t446\t\t/* MBR: Offset of partition table in the MBR */\n#define SZ_PTE\t\t\t\t16\t\t/* MBR: Size of a partition table entry */\n#define PTE_Boot\t\t\t0\t\t/* MBR PTE: Boot indicator */\n#define PTE_StHead\t\t\t1\t\t/* MBR PTE: Start head */\n#define PTE_StSec\t\t\t2\t\t/* MBR PTE: Start sector */\n#define PTE_StCyl\t\t\t3\t\t/* MBR PTE: Start cylinder */\n#define PTE_System\t\t\t4\t\t/* MBR PTE: System ID */\n#define PTE_EdHead\t\t\t5\t\t/* MBR PTE: End head */\n#define PTE_EdSec\t\t\t6\t\t/* MBR PTE: End sector */\n#define PTE_EdCyl\t\t\t7\t\t/* MBR PTE: End cylinder */\n#define PTE_StLba\t\t\t8\t\t/* MBR PTE: Start in LBA */\n#define PTE_SizLba\t\t\t12\t\t/* MBR PTE: Size in LBA */\n\n\n/* Post process on fatal error in the file operations */\n#define ABORT(fs, res)\t\t{ fp->err = (BYTE)(res); LEAVE_FF(fs, res); }\n\n\n/* Re-entrancy related */\n#if FF_FS_REENTRANT\n#if FF_USE_LFN == 1\n#error Static LFN work area cannot be used at thread-safe configuration\n#endif\n#define LEAVE_FF(fs, res)\t{ unlock_fs(fs, res); return res; }\n#else\n#define LEAVE_FF(fs, res)\treturn res\n#endif\n\n\n/* Definitions of volume - physical location conversion */\n#if FF_MULTI_PARTITION\n#define LD2PD(vol) VolToPart[vol].pd\t/* Get physical drive number */\n#define LD2PT(vol) VolToPart[vol].pt\t/* Get partition index */\n#else\n#define LD2PD(vol) (BYTE)(vol)\t/* Each logical drive is bound to the same physical drive number */\n#define LD2PT(vol) 0\t\t\t/* Find first valid partition or in SFD */\n#endif\n\n\n/* Definitions of sector size */\n#if (FF_MAX_SS < FF_MIN_SS) || (FF_MAX_SS != 512 && FF_MAX_SS != 1024 && FF_MAX_SS != 2048 && FF_MAX_SS != 4096) || (FF_MIN_SS != 512 && FF_MIN_SS != 1024 && FF_MIN_SS != 2048 && FF_MIN_SS != 4096)\n#error Wrong sector size configuration\n#endif\n#if FF_MAX_SS == FF_MIN_SS\n#define SS(fs)\t((UINT)FF_MAX_SS)\t/* Fixed sector size */\n#else\n#define SS(fs)\t((fs)->ssize)\t/* Variable sector size */\n#endif\n\n\n/* Timestamp */\n#if FF_FS_NORTC == 1\n#if FF_NORTC_YEAR < 1980 || FF_NORTC_YEAR > 2107 || FF_NORTC_MON < 1 || FF_NORTC_MON > 12 || FF_NORTC_MDAY < 1 || FF_NORTC_MDAY > 31\n#error Invalid FF_FS_NORTC settings\n#endif\n#define GET_FATTIME()\t((DWORD)(FF_NORTC_YEAR - 1980) << 25 | (DWORD)FF_NORTC_MON << 21 | (DWORD)FF_NORTC_MDAY << 16)\n#else\n#define GET_FATTIME()\tget_fattime()\n#endif\n\n\n/* File lock controls */\n#if FF_FS_LOCK != 0\n#if FF_FS_READONLY\n#error FF_FS_LOCK must be 0 at read-only configuration\n#endif\ntypedef struct {\n\tFATFS *fs;\t\t/* Object ID 1, volume (NULL:blank entry) */\n\tDWORD clu;\t\t/* Object ID 2, containing directory (0:root) */\n\tDWORD ofs;\t\t/* Object ID 3, offset in the directory */\n\tWORD ctr;\t\t/* Object open counter, 0:none, 0x01..0xFF:read mode open count, 0x100:write mode */\n} FILESEM;\n#endif\n\n\n/* SBCS up-case tables (\\x80-\\xFF) */\n#define TBL_CT437  {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT720  {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT737  {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \\\n\t\t\t\t\t0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xEF,0xF5,0xF0,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT771  {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDC,0xDE,0xDE, \\\n\t\t\t\t\t0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFE,0xFF}\n#define TBL_CT775  {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT850  {0x43,0x55,0x45,0x41,0x41,0x41,0x41,0x43,0x45,0x45,0x45,0x49,0x49,0x49,0x41,0x41, \\\n\t\t\t\t\t0x45,0x92,0x92,0x4F,0x4F,0x4F,0x55,0x55,0x59,0x4F,0x55,0x4F,0x9C,0x4F,0x9E,0x9F, \\\n\t\t\t\t\t0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0x41,0x41,0x41,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0x41,0x41,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD1,0xD1,0x45,0x45,0x45,0x49,0x49,0x49,0x49,0xD9,0xDA,0xDB,0xDC,0xDD,0x49,0xDF, \\\n\t\t\t\t\t0x4F,0xE1,0x4F,0x4F,0x4F,0x4F,0xE6,0xE8,0xE8,0x55,0x55,0x55,0x59,0x59,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT852  {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0xAC, \\\n\t\t\t\t\t0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}\n#define TBL_CT855  {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F, \\\n\t\t\t\t\t0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \\\n\t\t\t\t\t0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \\\n\t\t\t\t\t0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT857  {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x49,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \\\n\t\t\t\t\t0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0x49,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT860  {0x80,0x9A,0x90,0x8F,0x8E,0x91,0x86,0x80,0x89,0x89,0x92,0x8B,0x8C,0x98,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x91,0x92,0x8C,0x99,0xA9,0x96,0x9D,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0x86,0x8B,0x9F,0x96,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT861  {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x8B,0x8B,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x92,0x92,0x4F,0x99,0x8D,0x55,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0xA4,0xA5,0xA6,0xA7,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT862  {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT863  {0x43,0x55,0x45,0x41,0x41,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x41,0x8F, \\\n\t\t\t\t\t0x45,0x45,0x45,0x4F,0x45,0x49,0x55,0x55,0x98,0x4F,0x55,0x9B,0x9C,0x55,0x55,0x9F, \\\n\t\t\t\t\t0xA0,0xA1,0x4F,0x55,0xA4,0xA5,0xA6,0xA7,0x49,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT864  {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT865  {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT866  {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT869  {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x86,0x9C,0x8D,0x8F,0x90, \\\n\t\t\t\t\t0x91,0x90,0x92,0x95,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xA4,0xA5,0xA6,0xD9,0xDA,0xDB,0xDC,0xA7,0xA8,0xDF, \\\n\t\t\t\t\t0xA9,0xAA,0xAC,0xAD,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xCF,0xCF,0xD0,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xD1,0xD2,0xD3,0xF5,0xD4,0xF7,0xF8,0xF9,0xD5,0x96,0x95,0x98,0xFE,0xFF}\n\n\n/* DBCS code range |----- 1st byte -----|  |----------- 2nd byte -----------| */\n#define TBL_DC932 {0x81, 0x9F, 0xE0, 0xFC, 0x40, 0x7E, 0x80, 0xFC, 0x00, 0x00}\n#define TBL_DC936 {0x81, 0xFE, 0x00, 0x00, 0x40, 0x7E, 0x80, 0xFE, 0x00, 0x00}\n#define TBL_DC949 {0x81, 0xFE, 0x00, 0x00, 0x41, 0x5A, 0x61, 0x7A, 0x81, 0xFE}\n#define TBL_DC950 {0x81, 0xFE, 0x00, 0x00, 0x40, 0x7E, 0xA1, 0xFE, 0x00, 0x00}\n\n\n/* Macros for table definitions */\n#define MERGE_2STR(a, b) a ## b\n#define MKCVTBL(hd, cp) MERGE_2STR(hd, cp)\n\n\n\n\n/*--------------------------------------------------------------------------\n\n   Module Private Work Area\n\n---------------------------------------------------------------------------*/\n/* Remark: Variables defined here without initial value shall be guaranteed\n/  zero/null at start-up. If not, the linker option or start-up routine is\n/  not compliance with C standard. */\n\n/*--------------------------------*/\n/* File/Volume controls           */\n/*--------------------------------*/\n\n#if FF_VOLUMES < 1 || FF_VOLUMES > 10\n#error Wrong FF_VOLUMES setting\n#endif\nstatic FATFS* FatFs[FF_VOLUMES];\t/* Pointer to the filesystem objects (logical drives) */\nstatic WORD Fsid;\t\t\t\t\t/* Filesystem mount ID */\n\n#if FF_FS_RPATH != 0\nstatic BYTE CurrVol;\t\t\t\t/* Current drive */\n#endif\n\n#if FF_FS_LOCK != 0\nstatic FILESEM Files[FF_FS_LOCK];\t/* Open object lock semaphores */\n#endif\n\n#if FF_STR_VOLUME_ID\n#ifdef FF_VOLUME_STRS\nstatic const char* const VolumeStr[FF_VOLUMES] = {FF_VOLUME_STRS};\t/* Pre-defined volume ID */\n#endif\n#endif\n\n\n/*--------------------------------*/\n/* LFN/Directory working buffer   */\n/*--------------------------------*/\n\n#if FF_USE_LFN == 0\t\t/* Non-LFN configuration */\n#if FF_FS_EXFAT\n#error LFN must be enabled when enable exFAT\n#endif\n#define DEF_NAMBUF\n#define INIT_NAMBUF(fs)\n#define FREE_NAMBUF()\n#define LEAVE_MKFS(res)\treturn res\n\n#else\t\t\t\t\t/* LFN configurations */\n#if FF_MAX_LFN < 12 || FF_MAX_LFN > 255\n#error Wrong setting of FF_MAX_LFN\n#endif\n#if FF_LFN_BUF < FF_SFN_BUF || FF_SFN_BUF < 12\n#error Wrong setting of FF_LFN_BUF or FF_SFN_BUF\n#endif\n#if FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3\n#error Wrong setting of FF_LFN_UNICODE\n#endif\nstatic const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30};\t/* FAT: Offset of LFN characters in the directory entry */\n#define MAXDIRB(nc)\t((nc + 44U) / 15 * SZDIRE)\t/* exFAT: Size of directory entry block scratchpad buffer needed for the name length */\n\n#if FF_USE_LFN == 1\t\t/* LFN enabled with static working buffer */\n#if FF_FS_EXFAT\nstatic BYTE\tDirBuf[MAXDIRB(FF_MAX_LFN)];\t/* Directory entry block scratchpad buffer */\n#endif\nstatic WCHAR LfnBuf[FF_MAX_LFN + 1];\t\t/* LFN working buffer */\n#define DEF_NAMBUF\n#define INIT_NAMBUF(fs)\n#define FREE_NAMBUF()\n#define LEAVE_MKFS(res)\treturn res\n\n#elif FF_USE_LFN == 2 \t/* LFN enabled with dynamic working buffer on the stack */\n#if FF_FS_EXFAT\n#define DEF_NAMBUF\t\tWCHAR lbuf[FF_MAX_LFN+1]; BYTE dbuf[MAXDIRB(FF_MAX_LFN)];\t/* LFN working buffer and directory entry block scratchpad buffer */\n#define INIT_NAMBUF(fs)\t{ (fs)->lfnbuf = lbuf; (fs)->dirbuf = dbuf; }\n#define FREE_NAMBUF()\n#else\n#define DEF_NAMBUF\t\tWCHAR lbuf[FF_MAX_LFN+1];\t/* LFN working buffer */\n#define INIT_NAMBUF(fs)\t{ (fs)->lfnbuf = lbuf; }\n#define FREE_NAMBUF()\n#endif\n#define LEAVE_MKFS(res)\treturn res\n\n#elif FF_USE_LFN == 3 \t/* LFN enabled with dynamic working buffer on the heap */\n#if FF_FS_EXFAT\n#define DEF_NAMBUF\t\tWCHAR *lfn;\t/* Pointer to LFN working buffer and directory entry block scratchpad buffer */\n#define INIT_NAMBUF(fs)\t{ lfn = ff_memalloc((FF_MAX_LFN+1)*2 + MAXDIRB(FF_MAX_LFN)); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; (fs)->dirbuf = (BYTE*)(lfn+FF_MAX_LFN+1); }\n#define FREE_NAMBUF()\tff_memfree(lfn)\n#else\n#define DEF_NAMBUF\t\tWCHAR *lfn;\t/* Pointer to LFN working buffer */\n#define INIT_NAMBUF(fs)\t{ lfn = ff_memalloc((FF_MAX_LFN+1)*2); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; }\n#define FREE_NAMBUF()\tff_memfree(lfn)\n#endif\n#define LEAVE_MKFS(res)\t{ if (!work) ff_memfree(buf); return res; }\n#define MAX_MALLOC\t0x8000\t/* Must be >=FF_MAX_SS */\n\n#else\n#error Wrong setting of FF_USE_LFN\n\n#endif\t/* FF_USE_LFN == 1 */\n#endif\t/* FF_USE_LFN == 0 */\n\n\n\n/*--------------------------------*/\n/* Code conversion tables         */\n/*--------------------------------*/\n\n#if FF_CODE_PAGE == 0\t\t/* Run-time code page configuration */\n#define CODEPAGE CodePage\nstatic WORD CodePage;\t/* Current code page */\nstatic const BYTE *ExCvt, *DbcTbl;\t/* Pointer to current SBCS up-case table and DBCS code range table below */\n\nstatic const BYTE Ct437[] = TBL_CT437;\nstatic const BYTE Ct720[] = TBL_CT720;\nstatic const BYTE Ct737[] = TBL_CT737;\nstatic const BYTE Ct771[] = TBL_CT771;\nstatic const BYTE Ct775[] = TBL_CT775;\nstatic const BYTE Ct850[] = TBL_CT850;\nstatic const BYTE Ct852[] = TBL_CT852;\nstatic const BYTE Ct855[] = TBL_CT855;\nstatic const BYTE Ct857[] = TBL_CT857;\nstatic const BYTE Ct860[] = TBL_CT860;\nstatic const BYTE Ct861[] = TBL_CT861;\nstatic const BYTE Ct862[] = TBL_CT862;\nstatic const BYTE Ct863[] = TBL_CT863;\nstatic const BYTE Ct864[] = TBL_CT864;\nstatic const BYTE Ct865[] = TBL_CT865;\nstatic const BYTE Ct866[] = TBL_CT866;\nstatic const BYTE Ct869[] = TBL_CT869;\nstatic const BYTE Dc932[] = TBL_DC932;\nstatic const BYTE Dc936[] = TBL_DC936;\nstatic const BYTE Dc949[] = TBL_DC949;\nstatic const BYTE Dc950[] = TBL_DC950;\n\n#elif FF_CODE_PAGE < 900\t/* Static code page configuration (SBCS) */\n#define CODEPAGE FF_CODE_PAGE\nstatic const BYTE ExCvt[] = MKCVTBL(TBL_CT, FF_CODE_PAGE);\n\n#else\t\t\t\t\t/* Static code page configuration (DBCS) */\n#define CODEPAGE FF_CODE_PAGE\nstatic const BYTE DbcTbl[] = MKCVTBL(TBL_DC, FF_CODE_PAGE);\n\n#endif\n\n\n\n\n/*--------------------------------------------------------------------------\n\n   Module Private Functions\n\n---------------------------------------------------------------------------*/\n\n/*-----------------------------------------------------------------------*/\n/* Print error header                                                    */\n/*-----------------------------------------------------------------------*/\n\nvoid print_error()\n{\n\tgfx_printf(\"\\n\\n\\n%k[FatFS] Error: %k\", 0xFFFFFF00, 0xFFFFFFFF);\n}\n\n\n/*-----------------------------------------------------------------------*/\n/* Load/Store multi-byte word in the FAT structure                       */\n/*-----------------------------------------------------------------------*/\n\nstatic WORD ld_word (const BYTE* ptr)\t/*\t Load a 2-byte little-endian word */\n{\n\tWORD rv;\n\n\trv = ptr[1];\n\trv = rv << 8 | ptr[0];\n\treturn rv;\n}\n\nstatic DWORD ld_dword (const BYTE* ptr)\t/* Load a 4-byte little-endian word */\n{\n\tDWORD rv;\n\n\trv = ptr[3];\n\trv = rv << 8 | ptr[2];\n\trv = rv << 8 | ptr[1];\n\trv = rv << 8 | ptr[0];\n\treturn rv;\n}\n\n#if FF_FS_EXFAT\nstatic QWORD ld_qword (const BYTE* ptr)\t/* Load an 8-byte little-endian word */\n{\n\tQWORD rv;\n\n\trv = ptr[7];\n\trv = rv << 8 | ptr[6];\n\trv = rv << 8 | ptr[5];\n\trv = rv << 8 | ptr[4];\n\trv = rv << 8 | ptr[3];\n\trv = rv << 8 | ptr[2];\n\trv = rv << 8 | ptr[1];\n\trv = rv << 8 | ptr[0];\n\treturn rv;\n}\n#endif\n\n#if !FF_FS_READONLY\nstatic void st_word (BYTE* ptr, WORD val)\t/* Store a 2-byte word in little-endian */\n{\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val;\n}\n\nstatic void st_dword (BYTE* ptr, DWORD val)\t/* Store a 4-byte word in little-endian */\n{\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val;\n}\n\n#if FF_FS_EXFAT\nstatic void st_qword (BYTE* ptr, QWORD val)\t/* Store an 8-byte word in little-endian */\n{\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val;\n}\n#endif\n#endif\t/* !FF_FS_READONLY */\n\n\n\n/*-----------------------------------------------------------------------*/\n/* String functions                                                      */\n/*-----------------------------------------------------------------------*/\n\n/* Copy memory to memory */\nstatic void mem_cpy (void* dst, const void* src, UINT cnt)\n{\n\tBYTE *d = (BYTE*)dst;\n\tconst BYTE *s = (const BYTE*)src;\n\n\tif (cnt != 0) {\n\t\tdo {\n\t\t\t*d++ = *s++;\n\t\t} while (--cnt);\n\t}\n}\n\n\n/* Fill memory block */\nstatic void mem_set (void* dst, int val, UINT cnt)\n{\n\tBYTE *d = (BYTE*)dst;\n\n\tdo {\n\t\t*d++ = (BYTE)val;\n\t} while (--cnt);\n}\n\n\n/* Compare memory block */\nstatic int mem_cmp (const void* dst, const void* src, UINT cnt)\t/* ZR:same, NZ:different */\n{\n\tconst BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src;\n\tint r = 0;\n\n\tdo {\n\t\tr = *d++ - *s++;\n\t} while (--cnt && r == 0);\n\n\treturn r;\n}\n\n\n/* Check if chr is contained in the string */\nstatic int chk_chr (const char* str, int chr)\t/* NZ:contained, ZR:not contained */\n{\n\twhile (*str && *str != chr) str++;\n\treturn *str;\n}\n\n\n/* Test if the character is DBC 1st byte */\nstatic int dbc_1st (BYTE c)\n{\n#if FF_CODE_PAGE == 0\t\t/* Variable code page */\n\tif (DbcTbl && c >= DbcTbl[0]) {\n\t\tif (c <= DbcTbl[1]) return 1;\t\t\t\t\t/* 1st byte range 1 */\n\t\tif (c >= DbcTbl[2] && c <= DbcTbl[3]) return 1;\t/* 1st byte range 2 */\n\t}\n#elif FF_CODE_PAGE >= 900\t/* DBCS fixed code page */\n\tif (c >= DbcTbl[0]) {\n\t\tif (c <= DbcTbl[1]) return 1;\n\t\tif (c >= DbcTbl[2] && c <= DbcTbl[3]) return 1;\n\t}\n#else\t\t\t\t\t\t/* SBCS fixed code page */\n\tif (c != 0) return 0;\t/* Always false */\n#endif\n\treturn 0;\n}\n\n\n/* Test if the character is DBC 2nd byte */\nstatic int dbc_2nd (BYTE c)\n{\n#if FF_CODE_PAGE == 0\t\t/* Variable code page */\n\tif (DbcTbl && c >= DbcTbl[4]) {\n\t\tif (c <= DbcTbl[5]) return 1;\t\t\t\t\t/* 2nd byte range 1 */\n\t\tif (c >= DbcTbl[6] && c <= DbcTbl[7]) return 1;\t/* 2nd byte range 2 */\n\t\tif (c >= DbcTbl[8] && c <= DbcTbl[9]) return 1;\t/* 2nd byte range 3 */\n\t}\n#elif FF_CODE_PAGE >= 900\t/* DBCS fixed code page */\n\tif (c >= DbcTbl[4]) {\n\t\tif (c <= DbcTbl[5]) return 1;\n\t\tif (c >= DbcTbl[6] && c <= DbcTbl[7]) return 1;\n\t\tif (c >= DbcTbl[8] && c <= DbcTbl[9]) return 1;\n\t}\n#else\t\t\t\t\t\t/* SBCS fixed code page */\n\tif (c != 0) return 0;\t/* Always false */\n#endif\n\treturn 0;\n}\n\n\n#if FF_USE_LFN\n\n/* Get a character from TCHAR string in defined API encodeing */\nstatic DWORD tchar2uni (\t/* Returns character in UTF-16 encoding (>=0x10000 on double encoding unit, 0xFFFFFFFF on decode error) */\n\tconst TCHAR** str\t\t/* Pointer to pointer to TCHAR string in configured encoding */\n)\n{\n\tDWORD uc;\n\tconst TCHAR *p = *str;\n\n#if FF_LFN_UNICODE == 1\t\t/* UTF-16 input */\n\tWCHAR wc;\n\n\tuc = *p++;\t/* Get a unit */\n\tif (IsSurrogate(uc)) {\t/* Surrogate? */\n\t\twc = *p++;\t\t/* Get low surrogate */\n\t\tif (!IsSurrogateH(uc) || !IsSurrogateL(wc)) return 0xFFFFFFFF;\t/* Wrong surrogate? */\n\t\tuc = uc << 16 | wc;\n\t}\n\n#elif FF_LFN_UNICODE == 2\t/* UTF-8 input */\n\tBYTE b;\n\tint nf;\n\n\tuc = (BYTE)*p++;\t/* Get a unit */\n\tif (uc & 0x80) {\t/* Multiple byte code? */\n\t\tif ((uc & 0xE0) == 0xC0) {\t/* 2-byte sequence? */\n\t\t\tuc &= 0x1F; nf = 1;\n\t\t} else {\n\t\t\tif ((uc & 0xF0) == 0xE0) {\t/* 3-byte sequence? */\n\t\t\t\tuc &= 0x0F; nf = 2;\n\t\t\t} else {\n\t\t\t\tif ((uc & 0xF8) == 0xF0) {\t/* 4-byte sequence? */\n\t\t\t\t\tuc &= 0x07; nf = 3;\n\t\t\t\t} else {\t\t\t\t\t/* Wrong sequence */\n\t\t\t\t\treturn 0xFFFFFFFF;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdo {\t/* Get trailing bytes */\n\t\t\tb = (BYTE)*p++;\n\t\t\tif ((b & 0xC0) != 0x80) return 0xFFFFFFFF;\t/* Wrong sequence? */\n\t\t\tuc = uc << 6 | (b & 0x3F);\n\t\t} while (--nf != 0);\n\t\tif (uc < 0x80 || IsSurrogate(uc) || uc >= 0x110000) return 0xFFFFFFFF;\t/* Wrong code? */\n\t\tif (uc >= 0x010000) uc = 0xD800DC00 | ((uc - 0x10000) << 6 & 0x3FF0000) | (uc & 0x3FF);\t/* Make a surrogate pair if needed */\n\t}\n\n#elif FF_LFN_UNICODE == 3\t/* UTF-32 input */\n\tuc = (TCHAR)*p++;\t/* Get a unit */\n\tif (uc >= 0x110000) return 0xFFFFFFFF;\t/* Wrong code? */\n\tif (uc >= 0x010000) uc = 0xD800DC00 | ((uc - 0x10000) << 6 & 0x3FF0000) | (uc & 0x3FF);\t/* Make a surrogate pair if needed */\n\n#else\t\t/* ANSI/OEM input */\n\tBYTE b;\n\tWCHAR wc;\n\n\twc = (BYTE)*p++;\t\t\t/* Get a byte */\n\tif (dbc_1st((BYTE)wc)) {\t/* Is it a DBC 1st byte? */\n\t\tb = (BYTE)*p++;\t\t\t/* Get 2nd byte */\n\t\tif (!dbc_2nd(b)) return 0xFFFFFFFF;\t/* Invalid code? */\n\t\twc = (wc << 8) + b;\t\t/* Make a DBC */\n\t}\n\tif (wc != 0) {\n\t\twc = ff_oem2uni(wc, CODEPAGE);\t/* ANSI/OEM ==> Unicode */\n\t\tif (wc == 0) return 0xFFFFFFFF;\t/* Invalid code? */\n\t}\n\tuc = wc;\n\n#endif\n\t*str = p;\t/* Next read pointer */\n\treturn uc;\n}\n\n\n/* Output a TCHAR string in defined API encoding */\nstatic BYTE put_utf (\t/* Returns number of encoding units written (0:buffer overflow or wrong encoding) */\n\tDWORD chr,\t/* UTF-16 encoded character (Double encoding unit char if >=0x10000) */\n\tTCHAR* buf,\t/* Output buffer */\n\tUINT szb\t/* Size of the buffer */\n)\n{\n#if FF_LFN_UNICODE == 1\t/* UTF-16 output */\n\tWCHAR hs, wc;\n\n\ths = (WCHAR)(chr >> 16);\n\twc = (WCHAR)chr;\n\tif (hs == 0) {\t/* Single encoding unit? */\n\t\tif (szb < 1 || IsSurrogate(wc)) return 0;\t/* Buffer overflow or wrong code? */\n\t\t*buf = wc;\n\t\treturn 1;\n\t}\n\tif (szb < 2 || !IsSurrogateH(hs) || !IsSurrogateL(wc)) return 0;\t/* Buffer overflow or wrong surrogate? */\n\t*buf++ = hs;\n\t*buf++ = wc;\n\treturn 2;\n\n#elif FF_LFN_UNICODE == 2\t/* UTF-8 output */\n\tDWORD hc;\n\n\tif (chr < 0x80) {\t/* Single byte code? */\n\t\tif (szb < 1) return 0;\t/* Buffer overflow? */\n\t\t*buf = (TCHAR)chr;\n\t\treturn 1;\n\t}\n\tif (chr < 0x800) {\t/* 2-byte sequence? */\n\t\tif (szb < 2) return 0;\t/* Buffer overflow? */\n\t\t*buf++ = (TCHAR)(0xC0 | (chr >> 6 & 0x1F));\n\t\t*buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F));\n\t\treturn 2;\n\t}\n\tif (chr < 0x10000) {\t/* 3-byte sequence? */\n\t\tif (szb < 3 || IsSurrogate(chr)) return 0;\t/* Buffer overflow or wrong code? */\n\t\t*buf++ = (TCHAR)(0xE0 | (chr >> 12 & 0x0F));\n\t\t*buf++ = (TCHAR)(0x80 | (chr >> 6 & 0x3F));\n\t\t*buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F));\n\t\treturn 3;\n\t}\n\t/* 4-byte sequence */\n\tif (szb < 4) return 0;\t/* Buffer overflow? */\n\thc = ((chr & 0xFFFF0000) - 0xD8000000) >> 6;\t/* Get high 10 bits */\n\tchr = (chr & 0xFFFF) - 0xDC00;\t\t\t\t\t/* Get low 10 bits */\n\tif (hc >= 0x100000 || chr >= 0x400) return 0;\t/* Wrong surrogate? */\n\tchr = (hc | chr) + 0x10000;\n\t*buf++ = (TCHAR)(0xF0 | (chr >> 18 & 0x07));\n\t*buf++ = (TCHAR)(0x80 | (chr >> 12 & 0x3F));\n\t*buf++ = (TCHAR)(0x80 | (chr >> 6 & 0x3F));\n\t*buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F));\n\treturn 4;\n\n#elif FF_LFN_UNICODE == 3\t/* UTF-32 output */\n\tDWORD hc;\n\n\tif (szb < 1) return 0;\t/* Buffer overflow? */\n\tif (chr >= 0x10000) {\t/* Out of BMP? */\n\t\thc = ((chr & 0xFFFF0000) - 0xD8000000) >> 6;\t/* Get high 10 bits */\n\t\tchr = (chr & 0xFFFF) - 0xDC00;\t\t\t\t\t/* Get low 10 bits */\n\t\tif (hc >= 0x100000 || chr >= 0x400) return 0;\t/* Wrong surrogate? */\n\t\tchr = (hc | chr) + 0x10000;\n\t}\n\t*buf++ = (TCHAR)chr;\n\treturn 1;\n\n#else\t\t\t\t\t\t/* ANSI/OEM output */\n\tWCHAR wc;\n\n\twc = ff_uni2oem(chr, CODEPAGE);\n\tif (wc >= 0x100) {\t/* Is this a DBC? */\n\t\tif (szb < 2) return 0;\n\t\t*buf++ = (char)(wc >> 8);\t/* Store DBC 1st byte */\n\t\t*buf++ = (TCHAR)wc;\t\t\t/* Store DBC 2nd byte */\n\t\treturn 2;\n\t}\n\tif (wc == 0 || szb < 1) return 0;\t/* Invalid char or buffer overflow? */\n\t*buf++ = (TCHAR)wc;\t\t\t\t\t/* Store the character */\n\treturn 1;\n#endif\n}\n#endif\t/* FF_USE_LFN */\n\n\n#if FF_FS_REENTRANT\n/*-----------------------------------------------------------------------*/\n/* Request/Release grant to access the volume                            */\n/*-----------------------------------------------------------------------*/\nstatic int lock_fs (\t\t/* 1:Ok, 0:timeout */\n\tFATFS* fs\t\t/* Filesystem object */\n)\n{\n\treturn ff_req_grant(fs->sobj);\n}\n\n\nstatic void unlock_fs (\n\tFATFS* fs,\t\t/* Filesystem object */\n\tFRESULT res\t\t/* Result code to be returned */\n)\n{\n\tif (fs && res != FR_NOT_ENABLED && res != FR_INVALID_DRIVE && res != FR_TIMEOUT) {\n\t\tff_rel_grant(fs->sobj);\n\t}\n}\n\n#endif\n\n\n\n#if FF_FS_LOCK != 0\n/*-----------------------------------------------------------------------*/\n/* File lock control functions                                           */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT chk_lock (\t/* Check if the file can be accessed */\n\tDIR* dp,\t\t/* Directory object pointing the file to be checked */\n\tint acc\t\t\t/* Desired access type (0:Read mode open, 1:Write mode open, 2:Delete or rename) */\n)\n{\n\tUINT i, be;\n\n\t/* Search open object table for the object */\n\tbe = 0;\n\tfor (i = 0; i < FF_FS_LOCK; i++) {\n\t\tif (Files[i].fs) {\t/* Existing entry */\n\t\t\tif (Files[i].fs == dp->obj.fs &&\t \t/* Check if the object matches with an open object */\n\t\t\t\tFiles[i].clu == dp->obj.sclust &&\n\t\t\t\tFiles[i].ofs == dp->dptr) break;\n\t\t} else {\t\t\t/* Blank entry */\n\t\t\tbe = 1;\n\t\t}\n\t}\n\tif (i == FF_FS_LOCK) {\t/* The object has not been opened */\n\t\treturn (!be && acc != 2) ? FR_TOO_MANY_OPEN_FILES : FR_OK;\t/* Is there a blank entry for new object? */\n\t}\n\n\t/* The object was opened. Reject any open against writing file and all write mode open */\n\treturn (acc != 0 || Files[i].ctr == 0x100) ? FR_LOCKED : FR_OK;\n}\n\n\nstatic int enq_lock (void)\t/* Check if an entry is available for a new object */\n{\n\tUINT i;\n\n\tfor (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ;\n\treturn (i == FF_FS_LOCK) ? 0 : 1;\n}\n\n\nstatic UINT inc_lock (\t/* Increment object open counter and returns its index (0:Internal error) */\n\tDIR* dp,\t/* Directory object pointing the file to register or increment */\n\tint acc\t\t/* Desired access (0:Read, 1:Write, 2:Delete/Rename) */\n)\n{\n\tUINT i;\n\n\n\tfor (i = 0; i < FF_FS_LOCK; i++) {\t/* Find the object */\n\t\tif (Files[i].fs == dp->obj.fs &&\n\t\t\tFiles[i].clu == dp->obj.sclust &&\n\t\t\tFiles[i].ofs == dp->dptr) break;\n\t}\n\n\tif (i == FF_FS_LOCK) {\t\t\t\t/* Not opened. Register it as new. */\n\t\tfor (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ;\n\t\tif (i == FF_FS_LOCK) return 0;\t/* No free entry to register (int err) */\n\t\tFiles[i].fs = dp->obj.fs;\n\t\tFiles[i].clu = dp->obj.sclust;\n\t\tFiles[i].ofs = dp->dptr;\n\t\tFiles[i].ctr = 0;\n\t}\n\n\tif (acc >= 1 && Files[i].ctr) return 0;\t/* Access violation (int err) */\n\n\tFiles[i].ctr = acc ? 0x100 : Files[i].ctr + 1;\t/* Set semaphore value */\n\n\treturn i + 1;\t/* Index number origin from 1 */\n}\n\n\nstatic FRESULT dec_lock (\t/* Decrement object open counter */\n\tUINT i\t\t\t/* Semaphore index (1..) */\n)\n{\n\tWORD n;\n\tFRESULT res;\n\n\n\tif (--i < FF_FS_LOCK) {\t/* Index number origin from 0 */\n\t\tn = Files[i].ctr;\n\t\tif (n == 0x100) n = 0;\t\t/* If write mode open, delete the entry */\n\t\tif (n > 0) n--;\t\t\t\t/* Decrement read mode open count */\n\t\tFiles[i].ctr = n;\n\t\tif (n == 0) Files[i].fs = 0;\t/* Delete the entry if open count gets zero */\n\t\tres = FR_OK;\n\t} else {\n\t\tres = FR_INT_ERR;\t\t\t/* Invalid index nunber */\n\t}\n\treturn res;\n}\n\n\nstatic void clear_lock (\t/* Clear lock entries of the volume */\n\tFATFS *fs\n)\n{\n\tUINT i;\n\n\tfor (i = 0; i < FF_FS_LOCK; i++) {\n\t\tif (Files[i].fs == fs) Files[i].fs = 0;\n\t}\n}\n\n#endif\t/* FF_FS_LOCK != 0 */\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Move/Flush disk access window in the filesystem object                */\n/*-----------------------------------------------------------------------*/\n#if !FF_FS_READONLY\nstatic FRESULT sync_window (\t/* Returns FR_OK or FR_DISK_ERR */\n\tFATFS* fs\t\t\t/* Filesystem object */\n)\n{\n\tFRESULT res = FR_OK;\n\n\n\tif (fs->wflag) {\t/* Is the disk access window dirty */\n\t\tif (disk_write(fs->pdrv, fs->win, fs->winsect, 1) == RES_OK) {\t/* Write back the window */\n\t\t\tfs->wflag = 0;\t/* Clear window dirty flag */\n\t\t\tif (fs->winsect - fs->fatbase < fs->fsize) {\t/* Is it in the 1st FAT? */\n\t\t\t\tif (fs->n_fats == 2) disk_write(fs->pdrv, fs->win, fs->winsect + fs->fsize, 1);\t/* Reflect it to 2nd FAT if needed */\n\t\t\t}\n\t\t} else {\n\t\t\tres = FR_DISK_ERR;\n\t\t}\n\t}\n\treturn res;\n}\n#endif\n\n\nstatic FRESULT move_window (\t/* Returns FR_OK or FR_DISK_ERR */\n\tFATFS* fs,\t\t\t/* Filesystem object */\n\tDWORD sector\t\t/* Sector number to make appearance in the fs->win[] */\n)\n{\n\tFRESULT res = FR_OK;\n\n\n\tif (sector != fs->winsect) {\t/* Window offset changed? */\n#if !FF_FS_READONLY\n\t\tres = sync_window(fs);\t\t/* Write-back changes */\n#endif\n\t\tif (res == FR_OK) {\t\t\t/* Fill sector window with new data */\n\t\t\tif (disk_read(fs->pdrv, fs->win, sector, 1) != RES_OK) {\n\t\t\t\tsector = 0xFFFFFFFF;\t/* Invalidate window if read data is not valid */\n\t\t\t\tres = FR_DISK_ERR;\n\t\t\t}\n\t\t\tfs->winsect = sector;\n\t\t}\n\t}\n\treturn res;\n}\n\n\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Synchronize filesystem and data on the storage                        */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT sync_fs (\t/* Returns FR_OK or FR_DISK_ERR */\n\tFATFS* fs\t\t/* Filesystem object */\n)\n{\n\tFRESULT res;\n\n\n\tres = sync_window(fs);\n\tif (res == FR_OK) {\n\t\tif (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) {\t/* FAT32: Update FSInfo sector if needed */\n\t\t\t/* Create FSInfo structure */\n\t\t\tmem_set(fs->win, 0, sizeof fs->win);\n\t\t\tst_word(fs->win + BS_55AA, 0xAA55);\n\t\t\tst_dword(fs->win + FSI_LeadSig, 0x41615252);\n\t\t\tst_dword(fs->win + FSI_StrucSig, 0x61417272);\n\t\t\tst_dword(fs->win + FSI_Free_Count, fs->free_clst);\n\t\t\tst_dword(fs->win + FSI_Nxt_Free, fs->last_clst);\n\t\t\t/* Write it into the FSInfo sector */\n\t\t\tfs->winsect = fs->volbase + 1;\n\t\t\tdisk_write(fs->pdrv, fs->win, fs->winsect, 1);\n\t\t\tfs->fsi_flag = 0;\n\t\t}\n\t\t/* Make sure that no pending write process in the lower layer */\n\t\tif (disk_ioctl(fs->pdrv, CTRL_SYNC, 0) != RES_OK) res = FR_DISK_ERR;\n\t}\n\n\treturn res;\n}\n\n#endif\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Get physical sector number from cluster number                        */\n/*-----------------------------------------------------------------------*/\n\nstatic DWORD clst2sect (\t/* !=0:Sector number, 0:Failed (invalid cluster#) */\n\tFATFS* fs,\t\t/* Filesystem object */\n\tDWORD clst\t\t/* Cluster# to be converted */\n)\n{\n\tclst -= 2;\t\t/* Cluster number is origin from 2 */\n\tif (clst >= fs->n_fatent - 2) return 0;\t\t/* Is it invalid cluster number? */\n\treturn fs->database + fs->csize * clst;\t\t/* Start sector number of the cluster */\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* FAT access - Read value of a FAT entry                                */\n/*-----------------------------------------------------------------------*/\n\nstatic DWORD get_fat (\t\t/* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x7FFFFFFF:Cluster status */\n\tFFOBJID* obj,\t/* Corresponding object */\n\tDWORD clst\t\t/* Cluster number to get the value */\n)\n{\n\tUINT wc, bc;\n\tDWORD val;\n\tFATFS *fs = obj->fs;\n\n\n\tif (clst < 2 || clst >= fs->n_fatent) {\t/* Check if in valid range */\n\t\tval = 1;\t/* Internal error */\n\n\t} else {\n\t\tval = 0xFFFFFFFF;\t/* Default value falls on disk error */\n\n\t\tswitch (fs->fs_type) {\n\t\tcase FS_FAT12 :\n\t\t\tbc = (UINT)clst; bc += bc / 2;\n\t\t\tif (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break;\n\t\t\twc = fs->win[bc++ % SS(fs)];\t\t/* Get 1st byte of the entry */\n\t\t\tif (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break;\n\t\t\twc |= fs->win[bc % SS(fs)] << 8;\t/* Merge 2nd byte of the entry */\n\t\t\tval = (clst & 1) ? (wc >> 4) : (wc & 0xFFF);\t/* Adjust bit position */\n\t\t\tbreak;\n\n\t\tcase FS_FAT16 :\n\t\t\tif (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))) != FR_OK) break;\n\t\t\tval = ld_word(fs->win + clst * 2 % SS(fs));\t\t/* Simple WORD array */\n\t\t\tbreak;\n\n\t\tcase FS_FAT32 :\n\t\t\tif (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break;\n\t\t\tval = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x0FFFFFFF;\t/* Simple DWORD array but mask out upper 4 bits */\n\t\t\tbreak;\n#if FF_FS_EXFAT\n\t\tcase FS_EXFAT :\n\t\t\tif ((obj->objsize != 0 && obj->sclust != 0) || obj->stat == 0) {\t/* Object except root dir must have valid data length */\n\t\t\t\tDWORD cofs = clst - obj->sclust;\t/* Offset from start cluster */\n\t\t\t\tDWORD clen = (DWORD)((obj->objsize - 1) / SS(fs)) / fs->csize;\t/* Number of clusters - 1 */\n\n\t\t\t\tif (obj->stat == 2 && cofs <= clen) {\t/* Is it a contiguous chain? */\n\t\t\t\t\tval = (cofs == clen) ? 0x7FFFFFFF : clst + 1;\t/* No data on the FAT, generate the value */\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (obj->stat == 3 && cofs < obj->n_cont) {\t/* Is it in the 1st fragment? */\n\t\t\t\t\tval = clst + 1; \t/* Generate the value */\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (obj->stat != 2) {\t/* Get value from FAT if FAT chain is valid */\n\t\t\t\t\tif (obj->n_frag != 0) {\t/* Is it on the growing edge? */\n\t\t\t\t\t\tval = 0x7FFFFFFF;\t/* Generate EOC */\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break;\n\t\t\t\t\t\tval = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x7FFFFFFF;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* go to default */\n#endif\n\t\tdefault:\n\t\t\tval = 1;\t/* Internal error */\n\t\t}\n\t}\n\n\treturn val;\n}\n\n\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* FAT access - Change value of a FAT entry                              */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT put_fat (\t/* FR_OK(0):succeeded, !=0:error */\n\tFATFS* fs,\t\t/* Corresponding filesystem object */\n\tDWORD clst,\t\t/* FAT index number (cluster number) to be changed */\n\tDWORD val\t\t/* New value to be set to the entry */\n)\n{\n\tUINT bc;\n\tBYTE *p;\n\tFRESULT res = FR_INT_ERR;\n\n\n\tif (clst >= 2 && clst < fs->n_fatent) {\t/* Check if in valid range */\n\t\tswitch (fs->fs_type) {\n\t\tcase FS_FAT12 :\n\t\t\tbc = (UINT)clst; bc += bc / 2;\t/* bc: byte offset of the entry */\n\t\t\tres = move_window(fs, fs->fatbase + (bc / SS(fs)));\n\t\t\tif (res != FR_OK) break;\n\t\t\tp = fs->win + bc++ % SS(fs);\n\t\t\t*p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;\t\t/* Put 1st byte */\n\t\t\tfs->wflag = 1;\n\t\t\tres = move_window(fs, fs->fatbase + (bc / SS(fs)));\n\t\t\tif (res != FR_OK) break;\n\t\t\tp = fs->win + bc % SS(fs);\n\t\t\t*p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));\t/* Put 2nd byte */\n\t\t\tfs->wflag = 1;\n\t\t\tbreak;\n\n\t\tcase FS_FAT16 :\n\t\t\tres = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)));\n\t\t\tif (res != FR_OK) break;\n\t\t\tst_word(fs->win + clst * 2 % SS(fs), (WORD)val);\t/* Simple WORD array */\n\t\t\tfs->wflag = 1;\n\t\t\tbreak;\n\n\t\tcase FS_FAT32 :\n#if FF_FS_EXFAT\n\t\tcase FS_EXFAT :\n#endif\n\t\t\tres = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)));\n\t\t\tif (res != FR_OK) break;\n\t\t\tif (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) {\n\t\t\t\tval = (val & 0x0FFFFFFF) | (ld_dword(fs->win + clst * 4 % SS(fs)) & 0xF0000000);\n\t\t\t}\n\t\t\tst_dword(fs->win + clst * 4 % SS(fs), val);\n\t\t\tfs->wflag = 1;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn res;\n}\n\n#endif /* !FF_FS_READONLY */\n\n\n\n\n#if FF_FS_EXFAT && !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* exFAT: Accessing FAT and Allocation Bitmap                            */\n/*-----------------------------------------------------------------------*/\n\n/*--------------------------------------*/\n/* Find a contiguous free cluster block */\n/*--------------------------------------*/\n\nstatic DWORD find_bitmap (\t/* 0:Not found, 2..:Cluster block found, 0xFFFFFFFF:Disk error */\n\tFATFS* fs,\t/* Filesystem object */\n\tDWORD clst,\t/* Cluster number to scan from */\n\tDWORD ncl\t/* Number of contiguous clusters to find (1..) */\n)\n{\n\tBYTE bm, bv;\n\tUINT i;\n\tDWORD val, scl, ctr;\n\n\n\tclst -= 2;\t/* The first bit in the bitmap corresponds to cluster #2 */\n\tif (clst >= fs->n_fatent - 2) clst = 0;\n\tscl = val = clst; ctr = 0;\n\tfor (;;) {\n\t\tif (move_window(fs, fs->bitbase + val / 8 / SS(fs)) != FR_OK) return 0xFFFFFFFF;\n\t\ti = val / 8 % SS(fs); bm = 1 << (val % 8);\n\t\tdo {\n\t\t\tdo {\n\t\t\t\tbv = fs->win[i] & bm; bm <<= 1;\t\t/* Get bit value */\n\t\t\t\tif (++val >= fs->n_fatent - 2) {\t/* Next cluster (with wrap-around) */\n\t\t\t\t\tval = 0; bm = 0; i = SS(fs);\n\t\t\t\t}\n\t\t\t\tif (bv == 0) {\t/* Is it a free cluster? */\n\t\t\t\t\tif (++ctr == ncl) return scl + 2;\t/* Check if run length is sufficient for required */\n\t\t\t\t} else {\n\t\t\t\t\tscl = val; ctr = 0;\t\t/* Encountered a cluster in-use, restart to scan */\n\t\t\t\t}\n\t\t\t\tif (val == clst) return 0;\t/* All cluster scanned? */\n\t\t\t} while (bm != 0);\n\t\t\tbm = 1;\n\t\t} while (++i < SS(fs));\n\t}\n}\n\n\n/*----------------------------------------*/\n/* Set/Clear a block of allocation bitmap */\n/*----------------------------------------*/\n\nstatic FRESULT change_bitmap (\n\tFATFS* fs,\t/* Filesystem object */\n\tDWORD clst,\t/* Cluster number to change from */\n\tDWORD ncl,\t/* Number of clusters to be changed */\n\tint bv\t\t/* bit value to be set (0 or 1) */\n)\n{\n\tBYTE bm;\n\tUINT i;\n\tDWORD sect;\n\n\n\tclst -= 2;\t/* The first bit corresponds to cluster #2 */\n\tsect = fs->bitbase + clst / 8 / SS(fs);\t/* Sector address */\n\ti = clst / 8 % SS(fs);\t\t\t\t\t/* Byte offset in the sector */\n\tbm = 1 << (clst % 8);\t\t\t\t\t/* Bit mask in the byte */\n\tfor (;;) {\n\t\tif (move_window(fs, sect++) != FR_OK) return FR_DISK_ERR;\n\t\tdo {\n\t\t\tdo {\n\t\t\t\tif (bv == (int)((fs->win[i] & bm) != 0)) return FR_INT_ERR;\t/* Is the bit expected value? */\n\t\t\t\tfs->win[i] ^= bm;\t/* Flip the bit */\n\t\t\t\tfs->wflag = 1;\n\t\t\t\tif (--ncl == 0) return FR_OK;\t/* All bits processed? */\n\t\t\t} while (bm <<= 1);\t\t/* Next bit */\n\t\t\tbm = 1;\n\t\t} while (++i < SS(fs));\t\t/* Next byte */\n\t\ti = 0;\n\t}\n}\n\n\n/*---------------------------------------------*/\n/* Fill the first fragment of the FAT chain    */\n/*---------------------------------------------*/\n\nstatic FRESULT fill_first_frag (\n\tFFOBJID* obj\t/* Pointer to the corresponding object */\n)\n{\n\tFRESULT res;\n\tDWORD cl, n;\n\n\n\tif (obj->stat == 3) {\t/* Has the object been changed 'fragmented' in this session? */\n\t\tfor (cl = obj->sclust, n = obj->n_cont; n; cl++, n--) {\t/* Create cluster chain on the FAT */\n\t\t\tres = put_fat(obj->fs, cl, cl + 1);\n\t\t\tif (res != FR_OK) return res;\n\t\t}\n\t\tobj->stat = 0;\t/* Change status 'FAT chain is valid' */\n\t}\n\treturn FR_OK;\n}\n\n\n/*---------------------------------------------*/\n/* Fill the last fragment of the FAT chain     */\n/*---------------------------------------------*/\n\nstatic FRESULT fill_last_frag (\n\tFFOBJID* obj,\t/* Pointer to the corresponding object */\n\tDWORD lcl,\t\t/* Last cluster of the fragment */\n\tDWORD term\t\t/* Value to set the last FAT entry */\n)\n{\n\tFRESULT res;\n\n\n\twhile (obj->n_frag > 0) {\t/* Create the chain of last fragment */\n\t\tres = put_fat(obj->fs, lcl - obj->n_frag + 1, (obj->n_frag > 1) ? lcl - obj->n_frag + 2 : term);\n\t\tif (res != FR_OK) return res;\n\t\tobj->n_frag--;\n\t}\n\treturn FR_OK;\n}\n\n#endif\t/* FF_FS_EXFAT && !FF_FS_READONLY */\n\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* FAT handling - Remove a cluster chain                                 */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT remove_chain (\t/* FR_OK(0):succeeded, !=0:error */\n\tFFOBJID* obj,\t\t/* Corresponding object */\n\tDWORD clst,\t\t\t/* Cluster to remove a chain from */\n\tDWORD pclst\t\t\t/* Previous cluster of clst (0 if entire chain) */\n)\n{\n\tFRESULT res = FR_OK;\n\tDWORD nxt;\n\tFATFS *fs = obj->fs;\n#if FF_FS_EXFAT || FF_USE_TRIM\n\tDWORD scl = clst, ecl = clst;\n#endif\n#if FF_USE_TRIM\n\tDWORD rt[2];\n#endif\n\n\tif (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR;\t/* Check if in valid range */\n\n\t/* Mark the previous cluster 'EOC' on the FAT if it exists */\n\tif (pclst != 0 && (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT || obj->stat != 2)) {\n\t\tres = put_fat(fs, pclst, 0xFFFFFFFF);\n\t\tif (res != FR_OK) return res;\n\t}\n\n\t/* Remove the chain */\n\tdo {\n\t\tnxt = get_fat(obj, clst);\t\t\t/* Get cluster status */\n\t\tif (nxt == 0) break;\t\t\t\t/* Empty cluster? */\n\t\tif (nxt == 1) return FR_INT_ERR;\t/* Internal error? */\n\t\tif (nxt == 0xFFFFFFFF) return FR_DISK_ERR;\t/* Disk error? */\n\t\tif (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) {\n\t\t\tres = put_fat(fs, clst, 0);\t\t/* Mark the cluster 'free' on the FAT */\n\t\t\tif (res != FR_OK) return res;\n\t\t}\n\t\tif (fs->free_clst < fs->n_fatent - 2) {\t/* Update FSINFO */\n\t\t\tfs->free_clst++;\n\t\t\tfs->fsi_flag |= 1;\n\t\t}\n#if FF_FS_EXFAT || FF_USE_TRIM\n\t\tif (ecl + 1 == nxt) {\t/* Is next cluster contiguous? */\n\t\t\tecl = nxt;\n\t\t} else {\t\t\t\t/* End of contiguous cluster block */\n#if FF_FS_EXFAT\n\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\tres = change_bitmap(fs, scl, ecl - scl + 1, 0);\t/* Mark the cluster block 'free' on the bitmap */\n\t\t\t\tif (res != FR_OK) return res;\n\t\t\t}\n#endif\n#if FF_USE_TRIM\n\t\t\trt[0] = clst2sect(fs, scl);\t\t\t\t\t/* Start of data area freed */\n\t\t\trt[1] = clst2sect(fs, ecl) + fs->csize - 1;\t/* End of data area freed */\n\t\t\tdisk_ioctl(fs->pdrv, CTRL_TRIM, rt);\t\t/* Inform device the data in the block is no longer needed */\n#endif\n\t\t\tscl = ecl = nxt;\n\t\t}\n#endif\n\t\tclst = nxt;\t\t\t\t\t/* Next cluster */\n\t} while (clst < fs->n_fatent);\t/* Repeat while not the last link */\n\n#if FF_FS_EXFAT\n\t/* Some post processes for chain status */\n\tif (fs->fs_type == FS_EXFAT) {\n\t\tif (pclst == 0) {\t/* Has the entire chain been removed? */\n\t\t\tobj->stat = 0;\t\t/* Change the chain status 'initial' */\n\t\t} else {\n\t\t\tif (obj->stat == 0) {\t/* Is it a fragmented chain from the beginning of this session? */\n\t\t\t\tclst = obj->sclust;\t\t/* Follow the chain to check if it gets contiguous */\n\t\t\t\twhile (clst != pclst) {\n\t\t\t\t\tnxt = get_fat(obj, clst);\n\t\t\t\t\tif (nxt < 2) return FR_INT_ERR;\n\t\t\t\t\tif (nxt == 0xFFFFFFFF) return FR_DISK_ERR;\n\t\t\t\t\tif (nxt != clst + 1) break;\t/* Not contiguous? */\n\t\t\t\t\tclst++;\n\t\t\t\t}\n\t\t\t\tif (clst == pclst) {\t/* Has the chain got contiguous again? */\n\t\t\t\t\tobj->stat = 2;\t\t/* Change the chain status 'contiguous' */\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (obj->stat == 3 && pclst >= obj->sclust && pclst <= obj->sclust + obj->n_cont) {\t/* Was the chain fragmented in this session and got contiguous again? */\n\t\t\t\t\tobj->stat = 2;\t/* Change the chain status 'contiguous' */\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n#endif\n\treturn FR_OK;\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* FAT handling - Stretch a chain or Create a new chain                  */\n/*-----------------------------------------------------------------------*/\n\nstatic DWORD create_chain (\t/* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */\n\tFFOBJID* obj,\t\t/* Corresponding object */\n\tDWORD clst\t\t\t/* Cluster# to stretch, 0:Create a new chain */\n)\n{\n\tDWORD cs, ncl, scl;\n\tFRESULT res;\n\tFATFS *fs = obj->fs;\n\n\n\tif (clst == 0) {\t/* Create a new chain */\n\t\tscl = fs->last_clst;\t\t\t\t/* Suggested cluster to start to find */\n\t\tif (scl == 0 || scl >= fs->n_fatent) scl = 1;\n\t}\n\telse {\t\t\t\t/* Stretch a chain */\n\t\tcs = get_fat(obj, clst);\t\t\t/* Check the cluster status */\n\t\tif (cs < 2) return 1;\t\t\t\t/* Test for insanity */\n\t\tif (cs == 0xFFFFFFFF) return cs;\t/* Test for disk error */\n\t\tif (cs < fs->n_fatent) return cs;\t/* It is already followed by next cluster */\n\t\tscl = clst;\t\t\t\t\t\t\t/* Cluster to start to find */\n\t}\n\tif (fs->free_clst == 0) return 0;\t\t/* No free cluster */\n\n#if FF_FS_EXFAT\n\tif (fs->fs_type == FS_EXFAT) {\t/* On the exFAT volume */\n\t\tncl = find_bitmap(fs, scl, 1);\t\t\t\t/* Find a free cluster */\n\t\tif (ncl == 0 || ncl == 0xFFFFFFFF) return ncl;\t/* No free cluster or hard error? */\n\t\tres = change_bitmap(fs, ncl, 1, 1);\t\t\t/* Mark the cluster 'in use' */\n\t\tif (res == FR_INT_ERR) return 1;\n\t\tif (res == FR_DISK_ERR) return 0xFFFFFFFF;\n\t\tif (clst == 0) {\t\t\t\t\t\t\t/* Is it a new chain? */\n\t\t\tobj->stat = 2;\t\t\t\t\t\t\t/* Set status 'contiguous' */\n\t\t} else {\t\t\t\t\t\t\t\t\t/* It is a stretched chain */\n\t\t\tif (obj->stat == 2 && ncl != scl + 1) {\t/* Is the chain got fragmented? */\n\t\t\t\tobj->n_cont = scl - obj->sclust;\t/* Set size of the contiguous part */\n\t\t\t\tobj->stat = 3;\t\t\t\t\t\t/* Change status 'just fragmented' */\n\t\t\t}\n\t\t}\n\t\tif (obj->stat != 2) {\t/* Is the file non-contiguous? */\n\t\t\tif (ncl == clst + 1) {\t/* Is the cluster next to previous one? */\n\t\t\t\tobj->n_frag = obj->n_frag ? obj->n_frag + 1 : 2;\t/* Increment size of last framgent */\n\t\t\t} else {\t\t\t\t/* New fragment */\n\t\t\t\tif (obj->n_frag == 0) obj->n_frag = 1;\n\t\t\t\tres = fill_last_frag(obj, clst, ncl);\t/* Fill last fragment on the FAT and link it to new one */\n\t\t\t\tif (res == FR_OK) obj->n_frag = 1;\n\t\t\t}\n\t\t}\n\t} else\n#endif\n\t{\t/* On the FAT/FAT32 volume */\n\t\tncl = 0;\n\t\tif (scl == clst) {\t\t\t\t\t\t/* Stretching an existing chain? */\n\t\t\tncl = scl + 1;\t\t\t\t\t\t/* Test if next cluster is free */\n\t\t\tif (ncl >= fs->n_fatent) ncl = 2;\n\t\t\tcs = get_fat(obj, ncl);\t\t\t\t/* Get next cluster status */\n\t\t\tif (cs == 1 || cs == 0xFFFFFFFF) return cs;\t/* Test for error */\n\t\t\tif (cs != 0) {\t\t\t\t\t\t/* Not free? */\n\t\t\t\tcs = fs->last_clst;\t\t\t\t/* Start at suggested cluster if it is valid */\n\t\t\t\tif (cs >= 2 && cs < fs->n_fatent) scl = cs;\n\t\t\t\tncl = 0;\n\t\t\t}\n\t\t}\n\t\tif (ncl == 0) {\t/* The new cluster cannot be contiguous and find another fragment */\n\t\t\tncl = scl;\t/* Start cluster */\n\t\t\tfor (;;) {\n\t\t\t\tncl++;\t\t\t\t\t\t\t/* Next cluster */\n\t\t\t\tif (ncl >= fs->n_fatent) {\t\t/* Check wrap-around */\n\t\t\t\t\tncl = 2;\n\t\t\t\t\tif (ncl > scl) return 0;\t/* No free cluster found? */\n\t\t\t\t}\n\t\t\t\tcs = get_fat(obj, ncl);\t\t\t/* Get the cluster status */\n\t\t\t\tif (cs == 0) break;\t\t\t\t/* Found a free cluster? */\n\t\t\t\tif (cs == 1 || cs == 0xFFFFFFFF) return cs;\t/* Test for error */\n\t\t\t\tif (ncl == scl) return 0;\t\t/* No free cluster found? */\n\t\t\t}\n\t\t}\n\t\tres = put_fat(fs, ncl, 0xFFFFFFFF);\t\t/* Mark the new cluster 'EOC' */\n\t\tif (res == FR_OK && clst != 0) {\n\t\t\tres = put_fat(fs, clst, ncl);\t\t/* Link it from the previous one if needed */\n\t\t}\n\t}\n\n\tif (res == FR_OK) {\t\t\t/* Update FSINFO if function succeeded. */\n\t\tfs->last_clst = ncl;\n\t\tif (fs->free_clst <= fs->n_fatent - 2) fs->free_clst--;\n\t\tfs->fsi_flag |= 1;\n\t} else {\n\t\tncl = (res == FR_DISK_ERR) ? 0xFFFFFFFF : 1;\t/* Failed. Generate error status */\n\t}\n\n\treturn ncl;\t\t/* Return new cluster number or error status */\n}\n\n#endif /* !FF_FS_READONLY */\n\n\n\n\n#if FF_USE_FASTSEEK\n/*-----------------------------------------------------------------------*/\n/* FAT handling - Convert offset into cluster with link map table        */\n/*-----------------------------------------------------------------------*/\n\nstatic DWORD clmt_clust (\t/* <2:Error, >=2:Cluster number */\n\tFIL* fp,\t\t/* Pointer to the file object */\n\tFSIZE_t ofs\t\t/* File offset to be converted to cluster# */\n)\n{\n\tDWORD cl, ncl, *tbl;\n\tFATFS *fs = fp->obj.fs;\n\n\n\ttbl = fp->cltbl + 1;\t/* Top of CLMT */\n\tcl = (DWORD)(ofs / SS(fs) / fs->csize);\t/* Cluster order from top of the file */\n\tfor (;;) {\n\t\tncl = *tbl++;\t\t\t/* Number of cluters in the fragment */\n\t\tif (ncl == 0) return 0;\t/* End of table? (error) */\n\t\tif (cl < ncl) break;\t/* In this fragment? */\n\t\tcl -= ncl; tbl++;\t\t/* Next fragment */\n\t}\n\treturn cl + *tbl;\t/* Return the cluster number */\n}\n\n#endif\t/* FF_USE_FASTSEEK */\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Directory handling - Fill a cluster with zeros                        */\n/*-----------------------------------------------------------------------*/\n\n#if !FF_FS_READONLY\nstatic FRESULT dir_clear (\t/* Returns FR_OK or FR_DISK_ERR */\n\tFATFS *fs,\t\t/* Filesystem object */\n\tDWORD clst\t\t/* Directory table to clear */\n)\n{\n\tDWORD sect;\n\tUINT n, szb;\n\tBYTE *ibuf;\n\n\n\tif (sync_window(fs) != FR_OK) return FR_DISK_ERR;\t/* Flush disk access window */\n\tsect = clst2sect(fs, clst);\t\t/* Top of the cluster */\n\tfs->winsect = sect;\t\t\t\t/* Set window to top of the cluster */\n\tmem_set(fs->win, 0, sizeof fs->win);\t/* Clear window buffer */\n#if FF_USE_LFN == 3\t\t/* Quick table clear by using multi-secter write */\n\t/* Allocate a temporary buffer */\n\tfor (szb = ((DWORD)fs->csize * SS(fs) >= MAX_MALLOC) ? MAX_MALLOC : fs->csize * SS(fs), ibuf = 0; szb > SS(fs) && (ibuf = ff_memalloc(szb)) == 0; szb /= 2) ;\n\tif (szb > SS(fs)) {\t\t/* Buffer allocated? */\n\t\tmem_set(ibuf, 0, szb);\n\t\tszb /= SS(fs);\t\t/* Bytes -> Sectors */\n\t\tfor (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ;\t/* Fill the cluster with 0 */\n\t\tff_memfree(ibuf);\n\t} else\n#endif\n\t{\n\t\tibuf = fs->win; szb = 1;\t/* Use window buffer (many single-sector writes may take a time) */\n\t\tfor (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ;\t/* Fill the cluster with 0 */\n\t}\n\treturn (n == fs->csize) ? FR_OK : FR_DISK_ERR;\n}\n#endif\t/* !FF_FS_READONLY */\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Directory handling - Set directory index                              */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT dir_sdi (\t/* FR_OK(0):succeeded, !=0:error */\n\tDIR* dp,\t\t/* Pointer to directory object */\n\tDWORD ofs\t\t/* Offset of directory table */\n)\n{\n\tDWORD csz, clst;\n\tFATFS *fs = dp->obj.fs;\n\n\n\tif (ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR) || ofs % SZDIRE) {\t/* Check range of offset and alignment */\n\t\treturn FR_INT_ERR;\n\t}\n\tdp->dptr = ofs;\t\t\t\t/* Set current offset */\n\tclst = dp->obj.sclust;\t\t/* Table start cluster (0:root) */\n\tif (clst == 0 && fs->fs_type >= FS_FAT32) {\t/* Replace cluster# 0 with root cluster# */\n\t\tclst = fs->dirbase;\n\t\tif (FF_FS_EXFAT) dp->obj.stat = 0;\t/* exFAT: Root dir has an FAT chain */\n\t}\n\n\tif (clst == 0) {\t/* Static table (root-directory on the FAT volume) */\n\t\tif (ofs / SZDIRE >= fs->n_rootdir) return FR_INT_ERR;\t/* Is index out of range? */\n\t\tdp->sect = fs->dirbase;\n\n\t} else {\t\t\t/* Dynamic table (sub-directory or root-directory on the FAT32/exFAT volume) */\n\t\tcsz = (DWORD)fs->csize * SS(fs);\t/* Bytes per cluster */\n\t\twhile (ofs >= csz) {\t\t\t\t/* Follow cluster chain */\n\t\t\tclst = get_fat(&dp->obj, clst);\t\t\t\t/* Get next cluster */\n\t\t\tif (clst == 0xFFFFFFFF) return FR_DISK_ERR;\t/* Disk error */\n\t\t\tif (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR;\t/* Reached to end of table or internal error */\n\t\t\tofs -= csz;\n\t\t}\n\t\tdp->sect = clst2sect(fs, clst);\n\t}\n\tdp->clust = clst;\t\t\t\t\t/* Current cluster# */\n\tif (dp->sect == 0) return FR_INT_ERR;\n\tdp->sect += ofs / SS(fs);\t\t\t/* Sector# of the directory entry */\n\tdp->dir = fs->win + (ofs % SS(fs));\t/* Pointer to the entry in the win[] */\n\n\treturn FR_OK;\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Directory handling - Move directory table index next                  */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT dir_next (\t/* FR_OK(0):succeeded, FR_NO_FILE:End of table, FR_DENIED:Could not stretch */\n\tDIR* dp,\t\t\t\t/* Pointer to the directory object */\n\tint stretch\t\t\t\t/* 0: Do not stretch table, 1: Stretch table if needed */\n)\n{\n\tDWORD ofs, clst;\n\tFATFS *fs = dp->obj.fs;\n\n\n\tofs = dp->dptr + SZDIRE;\t/* Next entry */\n\tif (ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR)) dp->sect = 0;\t/* Disable it if the offset reached the max value */\n\tif (dp->sect == 0) return FR_NO_FILE;\t/* Report EOT if it has been disabled */\n\n\tif (ofs % SS(fs) == 0) {\t/* Sector changed? */\n\t\tdp->sect++;\t\t\t\t/* Next sector */\n\n\t\tif (dp->clust == 0) {\t/* Static table */\n\t\t\tif (ofs / SZDIRE >= fs->n_rootdir) {\t/* Report EOT if it reached end of static table */\n\t\t\t\tdp->sect = 0; return FR_NO_FILE;\n\t\t\t}\n\t\t}\n\t\telse {\t\t\t\t\t/* Dynamic table */\n\t\t\tif ((ofs / SS(fs) & (fs->csize - 1)) == 0) {\t/* Cluster changed? */\n\t\t\t\tclst = get_fat(&dp->obj, dp->clust);\t\t/* Get next cluster */\n\t\t\t\tif (clst <= 1) return FR_INT_ERR;\t\t\t/* Internal error */\n\t\t\t\tif (clst == 0xFFFFFFFF) return FR_DISK_ERR;\t/* Disk error */\n\t\t\t\tif (clst >= fs->n_fatent) {\t\t\t\t\t/* It reached end of dynamic table */\n#if !FF_FS_READONLY\n\t\t\t\t\tif (!stretch) {\t\t\t\t\t\t\t\t/* If no stretch, report EOT */\n\t\t\t\t\t\tdp->sect = 0; return FR_NO_FILE;\n\t\t\t\t\t}\n\t\t\t\t\tclst = create_chain(&dp->obj, dp->clust);\t/* Allocate a cluster */\n\t\t\t\t\tif (clst == 0) return FR_DENIED;\t\t\t/* No free cluster */\n\t\t\t\t\tif (clst == 1) return FR_INT_ERR;\t\t\t/* Internal error */\n\t\t\t\t\tif (clst == 0xFFFFFFFF) return FR_DISK_ERR;\t/* Disk error */\n\t\t\t\t\tif (dir_clear(fs, clst) != FR_OK) return FR_DISK_ERR;\t/* Clean up the stretched table */\n\t\t\t\t\tif (FF_FS_EXFAT) dp->obj.stat |= 4;\t\t\t/* exFAT: The directory has been stretched */\n#else\n\t\t\t\t\tif (!stretch) dp->sect = 0;\t\t\t\t\t/* (this line is to suppress compiler warning) */\n\t\t\t\t\tdp->sect = 0; return FR_NO_FILE;\t\t\t/* Report EOT */\n#endif\n\t\t\t\t}\n\t\t\t\tdp->clust = clst;\t\t/* Initialize data for new cluster */\n\t\t\t\tdp->sect = clst2sect(fs, clst);\n\t\t\t}\n\t\t}\n\t}\n\tdp->dptr = ofs;\t\t\t\t\t\t/* Current entry */\n\tdp->dir = fs->win + ofs % SS(fs);\t/* Pointer to the entry in the win[] */\n\n\treturn FR_OK;\n}\n\n\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Directory handling - Reserve a block of directory entries             */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT dir_alloc (\t/* FR_OK(0):succeeded, !=0:error */\n\tDIR* dp,\t\t\t\t/* Pointer to the directory object */\n\tUINT nent\t\t\t\t/* Number of contiguous entries to allocate */\n)\n{\n\tFRESULT res;\n\tUINT n;\n\tFATFS *fs = dp->obj.fs;\n\n\n\tres = dir_sdi(dp, 0);\n\tif (res == FR_OK) {\n\t\tn = 0;\n\t\tdo {\n\t\t\tres = move_window(fs, dp->sect);\n\t\t\tif (res != FR_OK) break;\n#if FF_FS_EXFAT\n\t\t\tif ((fs->fs_type == FS_EXFAT) ? (int)((dp->dir[XDIR_Type] & 0x80) == 0) : (int)(dp->dir[DIR_Name] == DDEM || dp->dir[DIR_Name] == 0)) {\n#else\n\t\t\tif (dp->dir[DIR_Name] == DDEM || dp->dir[DIR_Name] == 0) {\n#endif\n\t\t\t\tif (++n == nent) break;\t/* A block of contiguous free entries is found */\n\t\t\t} else {\n\t\t\t\tn = 0;\t\t\t\t\t/* Not a blank entry. Restart to search */\n\t\t\t}\n\t\t\tres = dir_next(dp, 1);\n\t\t} while (res == FR_OK);\t/* Next entry with table stretch enabled */\n\t}\n\n\tif (res == FR_NO_FILE) res = FR_DENIED;\t/* No directory entry to allocate */\n\treturn res;\n}\n\n#endif\t/* !FF_FS_READONLY */\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* FAT: Directory handling - Load/Store start cluster number             */\n/*-----------------------------------------------------------------------*/\n\nstatic DWORD ld_clust (\t/* Returns the top cluster value of the SFN entry */\n\tFATFS* fs,\t\t\t/* Pointer to the fs object */\n\tconst BYTE* dir\t\t/* Pointer to the key entry */\n)\n{\n\tDWORD cl;\n\n\tcl = ld_word(dir + DIR_FstClusLO);\n\tif (fs->fs_type == FS_FAT32) {\n\t\tcl |= (DWORD)ld_word(dir + DIR_FstClusHI) << 16;\n\t}\n\n\treturn cl;\n}\n\n\n#if !FF_FS_READONLY\nstatic void st_clust (\n\tFATFS* fs,\t/* Pointer to the fs object */\n\tBYTE* dir,\t/* Pointer to the key entry */\n\tDWORD cl\t/* Value to be set */\n)\n{\n\tst_word(dir + DIR_FstClusLO, (WORD)cl);\n\tif (fs->fs_type == FS_FAT32) {\n\t\tst_word(dir + DIR_FstClusHI, (WORD)(cl >> 16));\n\t}\n}\n#endif\n\n\n\n#if FF_USE_LFN\n/*--------------------------------------------------------*/\n/* FAT-LFN: Compare a part of file name with an LFN entry */\n/*--------------------------------------------------------*/\n\nstatic int cmp_lfn (\t\t/* 1:matched, 0:not matched */\n\tconst WCHAR* lfnbuf,\t/* Pointer to the LFN working buffer to be compared */\n\tBYTE* dir\t\t\t\t/* Pointer to the directory entry containing the part of LFN */\n)\n{\n\tUINT i, s;\n\tWCHAR wc, uc;\n\n\n\tif (ld_word(dir + LDIR_FstClusLO) != 0) return 0;\t/* Check LDIR_FstClusLO */\n\n\ti = ((dir[LDIR_Ord] & 0x3F) - 1) * 13;\t/* Offset in the LFN buffer */\n\n\tfor (wc = 1, s = 0; s < 13; s++) {\t\t/* Process all characters in the entry */\n\t\tuc = ld_word(dir + LfnOfs[s]);\t\t/* Pick an LFN character */\n\t\tif (wc != 0) {\n\t\t\tif (i >= FF_MAX_LFN + 1 || ff_wtoupper(uc) != ff_wtoupper(lfnbuf[i++])) {\t/* Compare it */\n\t\t\t\treturn 0;\t\t\t\t\t/* Not matched */\n\t\t\t}\n\t\t\twc = uc;\n\t\t} else {\n\t\t\tif (uc != 0xFFFF) return 0;\t\t/* Check filler */\n\t\t}\n\t}\n\n\tif ((dir[LDIR_Ord] & LLEF) && wc && lfnbuf[i]) return 0;\t/* Last segment matched but different length */\n\n\treturn 1;\t\t/* The part of LFN matched */\n}\n\n\n#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 || FF_USE_LABEL || FF_FS_EXFAT\n/*-----------------------------------------------------*/\n/* FAT-LFN: Pick a part of file name from an LFN entry */\n/*-----------------------------------------------------*/\n\nstatic int pick_lfn (\t/* 1:succeeded, 0:buffer overflow or invalid LFN entry */\n\tWCHAR* lfnbuf,\t\t/* Pointer to the LFN working buffer */\n\tBYTE* dir\t\t\t/* Pointer to the LFN entry */\n)\n{\n\tUINT i, s;\n\tWCHAR wc, uc;\n\n\n\tif (ld_word(dir + LDIR_FstClusLO) != 0) return 0;\t/* Check LDIR_FstClusLO is 0 */\n\n\ti = ((dir[LDIR_Ord] & ~LLEF) - 1) * 13;\t/* Offset in the LFN buffer */\n\n\tfor (wc = 1, s = 0; s < 13; s++) {\t\t/* Process all characters in the entry */\n\t\tuc = ld_word(dir + LfnOfs[s]);\t\t/* Pick an LFN character */\n\t\tif (wc != 0) {\n\t\t\tif (i >= FF_MAX_LFN + 1) return 0;\t/* Buffer overflow? */\n\t\t\tlfnbuf[i++] = wc = uc;\t\t\t/* Store it */\n\t\t} else {\n\t\t\tif (uc != 0xFFFF) return 0;\t\t/* Check filler */\n\t\t}\n\t}\n\n\tif (dir[LDIR_Ord] & LLEF && wc != 0) {\t/* Put terminator if it is the last LFN part and not terminated */\n\t\tif (i >= FF_MAX_LFN + 1) return 0;\t/* Buffer overflow? */\n\t\tlfnbuf[i] = 0;\n\t}\n\n\treturn 1;\t\t/* The part of LFN is valid */\n}\n#endif\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------*/\n/* FAT-LFN: Create an entry of LFN entries */\n/*-----------------------------------------*/\n\nstatic void put_lfn (\n\tconst WCHAR* lfn,\t/* Pointer to the LFN */\n\tBYTE* dir,\t\t\t/* Pointer to the LFN entry to be created */\n\tBYTE ord,\t\t\t/* LFN order (1-20) */\n\tBYTE sum\t\t\t/* Checksum of the corresponding SFN */\n)\n{\n\tUINT i, s;\n\tWCHAR wc;\n\n\n\tdir[LDIR_Chksum] = sum;\t\t\t/* Set checksum */\n\tdir[LDIR_Attr] = AM_LFN;\t\t/* Set attribute. LFN entry */\n\tdir[LDIR_Type] = 0;\n\tst_word(dir + LDIR_FstClusLO, 0);\n\n\ti = (ord - 1) * 13;\t\t\t\t/* Get offset in the LFN working buffer */\n\ts = wc = 0;\n\tdo {\n\t\tif (wc != 0xFFFF) wc = lfn[i++];\t/* Get an effective character */\n\t\tst_word(dir + LfnOfs[s], wc);\t\t/* Put it */\n\t\tif (wc == 0) wc = 0xFFFF;\t\t/* Padding characters for left locations */\n\t} while (++s < 13);\n\tif (wc == 0xFFFF || !lfn[i]) ord |= LLEF;\t/* Last LFN part is the start of LFN sequence */\n\tdir[LDIR_Ord] = ord;\t\t\t/* Set the LFN order */\n}\n\n#endif\t/* !FF_FS_READONLY */\n#endif\t/* FF_USE_LFN */\n\n\n\n#if FF_USE_LFN && !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* FAT-LFN: Create a Numbered SFN                                        */\n/*-----------------------------------------------------------------------*/\n\nstatic void gen_numname (\n\tBYTE* dst,\t\t\t/* Pointer to the buffer to store numbered SFN */\n\tconst BYTE* src,\t/* Pointer to SFN */\n\tconst WCHAR* lfn,\t/* Pointer to LFN */\n\tUINT seq\t\t\t/* Sequence number */\n)\n{\n\tBYTE ns[8], c;\n\tUINT i, j;\n\tWCHAR wc;\n\tDWORD sr;\n\n\n\tmem_cpy(dst, src, 11);\n\n\tif (seq > 5) {\t/* In case of many collisions, generate a hash number instead of sequential number */\n\t\tsr = seq;\n\t\twhile (*lfn) {\t/* Create a CRC as hash value */\n\t\t\twc = *lfn++;\n\t\t\tfor (i = 0; i < 16; i++) {\n\t\t\t\tsr = (sr << 1) + (wc & 1);\n\t\t\t\twc >>= 1;\n\t\t\t\tif (sr & 0x10000) sr ^= 0x11021;\n\t\t\t}\n\t\t}\n\t\tseq = (UINT)sr;\n\t}\n\n\t/* itoa (hexdecimal) */\n\ti = 7;\n\tdo {\n\t\tc = (BYTE)((seq % 16) + '0');\n\t\tif (c > '9') c += 7;\n\t\tns[i--] = c;\n\t\tseq /= 16;\n\t} while (seq);\n\tns[i] = '~';\n\n\t/* Append the number to the SFN body */\n\tfor (j = 0; j < i && dst[j] != ' '; j++) {\n\t\tif (dbc_1st(dst[j])) {\n\t\t\tif (j == i - 1) break;\n\t\t\tj++;\n\t\t}\n\t}\n\tdo {\n\t\tdst[j++] = (i < 8) ? ns[i++] : ' ';\n\t} while (j < 8);\n}\n#endif\t/* FF_USE_LFN && !FF_FS_READONLY */\n\n\n\n#if FF_USE_LFN\n/*-----------------------------------------------------------------------*/\n/* FAT-LFN: Calculate checksum of an SFN entry                           */\n/*-----------------------------------------------------------------------*/\n\nstatic BYTE sum_sfn (\n\tconst BYTE* dir\t\t/* Pointer to the SFN entry */\n)\n{\n\tBYTE sum = 0;\n\tUINT n = 11;\n\n\tdo {\n\t\tsum = (sum >> 1) + (sum << 7) + *dir++;\n\t} while (--n);\n\treturn sum;\n}\n\n#endif\t/* FF_USE_LFN */\n\n\n\n#if FF_FS_EXFAT\n/*-----------------------------------------------------------------------*/\n/* exFAT: Checksum                                                       */\n/*-----------------------------------------------------------------------*/\n\nstatic WORD xdir_sum (\t/* Get checksum of the directoly entry block */\n\tconst BYTE* dir\t\t/* Directory entry block to be calculated */\n)\n{\n\tUINT i, szblk;\n\tWORD sum;\n\n\n\tszblk = (dir[XDIR_NumSec] + 1) * SZDIRE;\t/* Number of bytes of the entry block */\n\tfor (i = sum = 0; i < szblk; i++) {\n\t\tif (i == XDIR_SetSum) {\t/* Skip 2-byte sum field */\n\t\t\ti++;\n\t\t} else {\n\t\t\tsum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + dir[i];\n\t\t}\n\t}\n\treturn sum;\n}\n\n\n\nstatic WORD xname_sum (\t/* Get check sum (to be used as hash) of the file name */\n\tconst WCHAR* name\t/* File name to be calculated */\n)\n{\n\tWCHAR chr;\n\tWORD sum = 0;\n\n\n\twhile ((chr = *name++) != 0) {\n\t\tchr = (WCHAR)ff_wtoupper(chr);\t\t/* File name needs to be up-case converted */\n\t\tsum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + (chr & 0xFF);\n\t\tsum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + (chr >> 8);\n\t}\n\treturn sum;\n}\n\n\n#if !FF_FS_READONLY && FF_USE_MKFS\nstatic DWORD xsum32 (\t/* Returns 32-bit checksum */\n\tBYTE  dat,\t\t\t/* Byte to be calculated (byte-by-byte processing) */\n\tDWORD sum\t\t\t/* Previous sum value */\n)\n{\n\tsum = ((sum & 1) ? 0x80000000 : 0) + (sum >> 1) + dat;\n\treturn sum;\n}\n#endif\n\n\n#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2\n/*------------------------------------------------------*/\n/* exFAT: Get object information from a directory block */\n/*------------------------------------------------------*/\n\nstatic void get_xfileinfo (\n\tBYTE* dirb,\t\t\t/* Pointer to the direcotry entry block 85+C0+C1s */\n\tFILINFO* fno\t\t/* Buffer to store the extracted file information */\n)\n{\n\tWCHAR wc, hs;\n\tUINT di, si, nc;\n\n\t/* Get file name from the entry block */\n\tsi = SZDIRE * 2;\t/* 1st C1 entry */\n\tnc = 0; hs = 0; di = 0;\n\twhile (nc < dirb[XDIR_NumName]) {\n\t\tif (si >= MAXDIRB(FF_MAX_LFN)) { di = 0; break; }\t/* Truncated directory block? */\n\t\tif ((si % SZDIRE) == 0) si += 2;\t\t/* Skip entry type field */\n\t\twc = ld_word(dirb + si); si += 2; nc++;\t/* Get a character */\n\t\tif (hs == 0 && IsSurrogate(wc)) {\t/* Is it a surrogate? */\n\t\t\ths = wc; continue;\t/* Get low surrogate */\n\t\t}\n\t\twc = put_utf((DWORD)hs << 16 | wc, &fno->fname[di], FF_LFN_BUF - di);\t/* Store it in API encoding */\n\t\tif (wc == 0) { di = 0; break; }\t/* Buffer overflow or wrong encoding? */\n\t\tdi += wc;\n\t\ths = 0;\n\t}\n\tif (hs != 0) di = 0;\t\t\t\t\t/* Broken surrogate pair? */\n\tif (di == 0) fno->fname[di++] = '?';\t/* Inaccessible object name? */\n\tfno->fname[di] = 0;\t\t\t\t\t\t/* Terminate the name */\n\tfno->altname[0] = 0;\t\t\t\t\t/* exFAT does not support SFN */\n\n\tfno->fattrib = dirb[XDIR_Attr];\t\t\t/* Attribute */\n\tfno->fsize = (fno->fattrib & AM_DIR) ? 0 : ld_qword(dirb + XDIR_FileSize);\t/* Size */\n\tfno->ftime = ld_word(dirb + XDIR_ModTime + 0);\t/* Time */\n\tfno->fdate = ld_word(dirb + XDIR_ModTime + 2);\t/* Date */\n}\n\n#endif\t/* FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 */\n\n\n/*-----------------------------------*/\n/* exFAT: Get a directry entry block */\n/*-----------------------------------*/\n\nstatic FRESULT load_xdir (\t/* FR_INT_ERR: invalid entry block */\n\tDIR* dp\t\t\t\t\t/* Reading direcotry object pointing top of the entry block to load */\n)\n{\n\tFRESULT res;\n\tUINT i, sz_ent;\n\tBYTE* dirb = dp->obj.fs->dirbuf;\t/* Pointer to the on-memory direcotry entry block 85+C0+C1s */\n\n\n\t/* Load file-directory entry */\n\tres = move_window(dp->obj.fs, dp->sect);\n\tif (res != FR_OK) return res;\n\tif (dp->dir[XDIR_Type] != ET_FILEDIR) return FR_INT_ERR;\t/* Invalid order */\n\tmem_cpy(dirb + 0 * SZDIRE, dp->dir, SZDIRE);\n\tsz_ent = (dirb[XDIR_NumSec] + 1) * SZDIRE;\n\tif (sz_ent < 3 * SZDIRE || sz_ent > 19 * SZDIRE) return FR_INT_ERR;\n\n\t/* Load stream-extension entry */\n\tres = dir_next(dp, 0);\n\tif (res == FR_NO_FILE) res = FR_INT_ERR;\t/* It cannot be */\n\tif (res != FR_OK) return res;\n\tres = move_window(dp->obj.fs, dp->sect);\n\tif (res != FR_OK) return res;\n\tif (dp->dir[XDIR_Type] != ET_STREAM) return FR_INT_ERR;\t/* Invalid order */\n\tmem_cpy(dirb + 1 * SZDIRE, dp->dir, SZDIRE);\n\tif (MAXDIRB(dirb[XDIR_NumName]) > sz_ent) return FR_INT_ERR;\n\n\t/* Load file-name entries */\n\ti = 2 * SZDIRE;\t/* Name offset to load */\n\tdo {\n\t\tres = dir_next(dp, 0);\n\t\tif (res == FR_NO_FILE) res = FR_INT_ERR;\t/* It cannot be */\n\t\tif (res != FR_OK) return res;\n\t\tres = move_window(dp->obj.fs, dp->sect);\n\t\tif (res != FR_OK) return res;\n\t\tif (dp->dir[XDIR_Type] != ET_FILENAME) return FR_INT_ERR;\t/* Invalid order */\n\t\tif (i < MAXDIRB(FF_MAX_LFN)) mem_cpy(dirb + i, dp->dir, SZDIRE);\n\t} while ((i += SZDIRE) < sz_ent);\n\n\t/* Sanity check (do it for only accessible object) */\n\tif (i <= MAXDIRB(FF_MAX_LFN)) {\n\t\tif (xdir_sum(dirb) != ld_word(dirb + XDIR_SetSum)) return FR_INT_ERR;\n\t}\n\treturn FR_OK;\n}\n\n\n/*------------------------------------------------------------------*/\n/* exFAT: Initialize object allocation info with loaded entry block */\n/*------------------------------------------------------------------*/\n\nstatic void init_alloc_info (\n\tFATFS* fs,\t\t/* Filesystem object */\n\tFFOBJID* obj\t/* Object allocation information to be initialized */\n)\n{\n\tobj->sclust = ld_dword(fs->dirbuf + XDIR_FstClus);\t\t/* Start cluster */\n\tobj->objsize = ld_qword(fs->dirbuf + XDIR_FileSize);\t/* Size */\n\tobj->stat = fs->dirbuf[XDIR_GenFlags] & 2;\t\t\t\t/* Allocation status */\n\tobj->n_frag = 0;\t\t\t\t\t\t\t\t\t\t/* No last fragment info */\n}\n\n\n\n#if !FF_FS_READONLY || FF_FS_RPATH != 0\n/*------------------------------------------------*/\n/* exFAT: Load the object's directory entry block */\n/*------------------------------------------------*/\n\nstatic FRESULT load_obj_xdir (\n\tDIR* dp,\t\t\t/* Blank directory object to be used to access containing direcotry */\n\tconst FFOBJID* obj\t/* Object with its containing directory information */\n)\n{\n\tFRESULT res;\n\n\t/* Open object containing directory */\n\tdp->obj.fs = obj->fs;\n\tdp->obj.sclust = obj->c_scl;\n\tdp->obj.stat = (BYTE)obj->c_size;\n\tdp->obj.objsize = obj->c_size & 0xFFFFFF00;\n\tdp->obj.n_frag = 0;\n\tdp->blk_ofs = obj->c_ofs;\n\n\tres = dir_sdi(dp, dp->blk_ofs);\t/* Goto object's entry block */\n\tif (res == FR_OK) {\n\t\tres = load_xdir(dp);\t\t/* Load the object's entry block */\n\t}\n\treturn res;\n}\n#endif\n\n\n#if !FF_FS_READONLY\n/*----------------------------------------*/\n/* exFAT: Store the directory entry block */\n/*----------------------------------------*/\n\nstatic FRESULT store_xdir (\n\tDIR* dp\t\t\t\t/* Pointer to the direcotry object */\n)\n{\n\tFRESULT res;\n\tUINT nent;\n\tBYTE* dirb = dp->obj.fs->dirbuf;\t/* Pointer to the direcotry entry block 85+C0+C1s */\n\n\t/* Create set sum */\n\tst_word(dirb + XDIR_SetSum, xdir_sum(dirb));\n\tnent = dirb[XDIR_NumSec] + 1;\n\n\t/* Store the direcotry entry block to the directory */\n\tres = dir_sdi(dp, dp->blk_ofs);\n\twhile (res == FR_OK) {\n\t\tres = move_window(dp->obj.fs, dp->sect);\n\t\tif (res != FR_OK) break;\n\t\tmem_cpy(dp->dir, dirb, SZDIRE);\n\t\tdp->obj.fs->wflag = 1;\n\t\tif (--nent == 0) break;\n\t\tdirb += SZDIRE;\n\t\tres = dir_next(dp, 0);\n\t}\n\treturn (res == FR_OK || res == FR_DISK_ERR) ? res : FR_INT_ERR;\n}\n\n\n\n/*-------------------------------------------*/\n/* exFAT: Create a new directory enrty block */\n/*-------------------------------------------*/\n\nstatic void create_xdir (\n\tBYTE* dirb,\t\t\t/* Pointer to the direcotry entry block buffer */\n\tconst WCHAR* lfn\t/* Pointer to the object name */\n)\n{\n\tUINT i;\n\tBYTE nc1, nlen;\n\tWCHAR wc;\n\n\n\t/* Create file-directory and stream-extension entry */\n\tmem_set(dirb, 0, 2 * SZDIRE);\n\tdirb[0 * SZDIRE + XDIR_Type] = ET_FILEDIR;\n\tdirb[1 * SZDIRE + XDIR_Type] = ET_STREAM;\n\n\t/* Create file-name entries */\n\ti = SZDIRE * 2;\t/* Top of file_name entries */\n\tnlen = nc1 = 0; wc = 1;\n\tdo {\n\t\tdirb[i++] = ET_FILENAME; dirb[i++] = 0;\n\t\tdo {\t/* Fill name field */\n\t\t\tif (wc != 0 && (wc = lfn[nlen]) != 0) nlen++;\t/* Get a character if exist */\n\t\t\tst_word(dirb + i, wc); \t\t/* Store it */\n\t\t\ti += 2;\n\t\t} while (i % SZDIRE != 0);\n\t\tnc1++;\n\t} while (lfn[nlen]);\t/* Fill next entry if any char follows */\n\n\tdirb[XDIR_NumName] = nlen;\t\t/* Set name length */\n\tdirb[XDIR_NumSec] = 1 + nc1;\t/* Set secondary count (C0 + C1s) */\n\tst_word(dirb + XDIR_NameHash, xname_sum(lfn));\t/* Set name hash */\n}\n\n#endif\t/* !FF_FS_READONLY */\n#endif\t/* FF_FS_EXFAT */\n\n\n\n#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 || FF_USE_LABEL || FF_FS_EXFAT\n/*-----------------------------------------------------------------------*/\n/* Read an object from the directory                                     */\n/*-----------------------------------------------------------------------*/\n\n#define DIR_READ_FILE(dp) dir_read(dp, 0)\n#define DIR_READ_LABEL(dp) dir_read(dp, 1)\n\nstatic FRESULT dir_read (\n\tDIR* dp,\t\t/* Pointer to the directory object */\n\tint vol\t\t\t/* Filtered by 0:file/directory or 1:volume label */\n)\n{\n\tFRESULT res = FR_NO_FILE;\n\tFATFS *fs = dp->obj.fs;\n\tBYTE attr, b;\n#if FF_USE_LFN\n\tBYTE ord = 0xFF, sum = 0xFF;\n#endif\n\n\twhile (dp->sect) {\n\t\tres = move_window(fs, dp->sect);\n\t\tif (res != FR_OK) break;\n\t\tb = dp->dir[DIR_Name];\t/* Test for the entry type */\n\t\tif (b == 0) {\n\t\t\tres = FR_NO_FILE; break; /* Reached to end of the directory */\n\t\t}\n#if FF_FS_EXFAT\n\t\tif (fs->fs_type == FS_EXFAT) {\t/* On the exFAT volume */\n\t\t\tif (FF_USE_LABEL && vol) {\n\t\t\t\tif (b == ET_VLABEL) break;\t/* Volume label entry? */\n\t\t\t} else {\n\t\t\t\tif (b == ET_FILEDIR) {\t\t/* Start of the file entry block? */\n\t\t\t\t\tdp->blk_ofs = dp->dptr;\t/* Get location of the block */\n\t\t\t\t\tres = load_xdir(dp);\t/* Load the entry block */\n\t\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\t\tdp->obj.attr = fs->dirbuf[XDIR_Attr] & AM_MASK;\t/* Get attribute */\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else\n#endif\n\t\t{\t/* On the FAT/FAT32 volume */\n\t\t\tdp->obj.attr = attr = dp->dir[DIR_Attr] & AM_MASK;\t/* Get attribute */\n#if FF_USE_LFN\t\t/* LFN configuration */\n\t\t\tif (b == DDEM || b == '.' || (int)((attr & ~AM_ARC) == AM_VOL) != vol) {\t/* An entry without valid data */\n\t\t\t\tord = 0xFF;\n\t\t\t} else {\n\t\t\t\tif (attr == AM_LFN) {\t\t\t/* An LFN entry is found */\n\t\t\t\t\tif (b & LLEF) {\t\t\t/* Is it start of an LFN sequence? */\n\t\t\t\t\t\tsum = dp->dir[LDIR_Chksum];\n\t\t\t\t\t\tb &= (BYTE)~LLEF; ord = b;\n\t\t\t\t\t\tdp->blk_ofs = dp->dptr;\n\t\t\t\t\t}\n\t\t\t\t\t/* Check LFN validity and capture it */\n\t\t\t\t\tord = (b == ord && sum == dp->dir[LDIR_Chksum] && pick_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF;\n\t\t\t\t} else {\t\t\t\t\t/* An SFN entry is found */\n\t\t\t\t\tif (ord != 0 || sum != sum_sfn(dp->dir)) {\t/* Is there a valid LFN? */\n\t\t\t\t\t\tdp->blk_ofs = 0xFFFFFFFF;\t\t\t/* It has no LFN. */\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n#else\t\t/* Non LFN configuration */\n\t\t\tif (b != DDEM && b != '.' && attr != AM_LFN && (int)((attr & ~AM_ARC) == AM_VOL) == vol) {\t/* Is it a valid entry? */\n\t\t\t\tbreak;\n\t\t\t}\n#endif\n\t\t}\n\t\tres = dir_next(dp, 0);\t\t/* Next entry */\n\t\tif (res != FR_OK) break;\n\t}\n\n\tif (res != FR_OK) dp->sect = 0;\t\t/* Terminate the read operation on error or EOT */\n\treturn res;\n}\n\n#endif\t/* FF_FS_MINIMIZE <= 1 || FF_USE_LABEL || FF_FS_RPATH >= 2 */\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Directory handling - Find an object in the directory                  */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT dir_find (\t/* FR_OK(0):succeeded, !=0:error */\n\tDIR* dp\t\t\t\t\t/* Pointer to the directory object with the file name */\n)\n{\n\tFRESULT res;\n\tFATFS *fs = dp->obj.fs;\n\tBYTE c;\n#if FF_USE_LFN\n\tBYTE a, ord, sum;\n#endif\n\n\tres = dir_sdi(dp, 0);\t\t\t/* Rewind directory object */\n\tif (res != FR_OK) return res;\n#if FF_FS_EXFAT\n\tif (fs->fs_type == FS_EXFAT) {\t/* On the exFAT volume */\n\t\tBYTE nc;\n\t\tUINT di, ni;\n\t\tWORD hash = xname_sum(fs->lfnbuf);\t\t/* Hash value of the name to find */\n\n\t\twhile ((res = DIR_READ_FILE(dp)) == FR_OK) {\t/* Read an item */\n#if FF_MAX_LFN < 255\n\t\t\tif (fs->dirbuf[XDIR_NumName] > FF_MAX_LFN) continue;\t\t\t/* Skip comparison if inaccessible object name */\n#endif\n\t\t\tif (ld_word(fs->dirbuf + XDIR_NameHash) != hash) continue;\t/* Skip comparison if hash mismatched */\n\t\t\tfor (nc = fs->dirbuf[XDIR_NumName], di = SZDIRE * 2, ni = 0; nc; nc--, di += 2, ni++) {\t/* Compare the name */\n\t\t\t\tif ((di % SZDIRE) == 0) di += 2;\n\t\t\t\tif (ff_wtoupper(ld_word(fs->dirbuf + di)) != ff_wtoupper(fs->lfnbuf[ni])) break;\n\t\t\t}\n\t\t\tif (nc == 0 && !fs->lfnbuf[ni]) break;\t/* Name matched? */\n\t\t}\n\t\treturn res;\n\t}\n#endif\n\t/* On the FAT/FAT32 volume */\n#if FF_USE_LFN\n\tord = sum = 0xFF; dp->blk_ofs = 0xFFFFFFFF;\t/* Reset LFN sequence */\n#endif\n\tdo {\n\t\tres = move_window(fs, dp->sect);\n\t\tif (res != FR_OK) break;\n\t\tc = dp->dir[DIR_Name];\n\t\tif (c == 0) { res = FR_NO_FILE; break; }\t/* Reached to end of table */\n#if FF_USE_LFN\t\t/* LFN configuration */\n\t\tdp->obj.attr = a = dp->dir[DIR_Attr] & AM_MASK;\n\t\tif (c == DDEM || ((a & AM_VOL) && a != AM_LFN)) {\t/* An entry without valid data */\n\t\t\tord = 0xFF; dp->blk_ofs = 0xFFFFFFFF;\t/* Reset LFN sequence */\n\t\t} else {\n\t\t\tif (a == AM_LFN) {\t\t\t/* An LFN entry is found */\n\t\t\t\tif (!(dp->fn[NSFLAG] & NS_NOLFN)) {\n\t\t\t\t\tif (c & LLEF) {\t\t/* Is it start of LFN sequence? */\n\t\t\t\t\t\tsum = dp->dir[LDIR_Chksum];\n\t\t\t\t\t\tc &= (BYTE)~LLEF; ord = c;\t/* LFN start order */\n\t\t\t\t\t\tdp->blk_ofs = dp->dptr;\t/* Start offset of LFN */\n\t\t\t\t\t}\n\t\t\t\t\t/* Check validity of the LFN entry and compare it with given name */\n\t\t\t\t\tord = (c == ord && sum == dp->dir[LDIR_Chksum] && cmp_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF;\n\t\t\t\t}\n\t\t\t} else {\t\t\t\t\t/* An SFN entry is found */\n\t\t\t\tif (ord == 0 && sum == sum_sfn(dp->dir)) break;\t/* LFN matched? */\n\t\t\t\tif (!(dp->fn[NSFLAG] & NS_LOSS) && !mem_cmp(dp->dir, dp->fn, 11)) break;\t/* SFN matched? */\n\t\t\t\tord = 0xFF; dp->blk_ofs = 0xFFFFFFFF;\t/* Reset LFN sequence */\n\t\t\t}\n\t\t}\n#else\t\t/* Non LFN configuration */\n\t\tdp->obj.attr = dp->dir[DIR_Attr] & AM_MASK;\n\t\tif (!(dp->dir[DIR_Attr] & AM_VOL) && !mem_cmp(dp->dir, dp->fn, 11)) break;\t/* Is it a valid entry? */\n#endif\n\t\tres = dir_next(dp, 0);\t/* Next entry */\n\t} while (res == FR_OK);\n\n\treturn res;\n}\n\n\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Register an object to the directory                                   */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT dir_register (\t/* FR_OK:succeeded, FR_DENIED:no free entry or too many SFN collision, FR_DISK_ERR:disk error */\n\tDIR* dp\t\t\t\t\t\t/* Target directory with object name to be created */\n)\n{\n\tFRESULT res;\n\tFATFS *fs = dp->obj.fs;\n#if FF_USE_LFN\t\t/* LFN configuration */\n\tUINT n, nlen, nent;\n\tBYTE sn[12], sum;\n\n\n\tif (dp->fn[NSFLAG] & (NS_DOT | NS_NONAME)) return FR_INVALID_NAME;\t/* Check name validity */\n\tfor (nlen = 0; fs->lfnbuf[nlen]; nlen++) ;\t/* Get lfn length */\n\n#if FF_FS_EXFAT\n\tif (fs->fs_type == FS_EXFAT) {\t/* On the exFAT volume */\n\t\tnent = (nlen + 14) / 15 + 2;\t/* Number of entries to allocate (85+C0+C1s) */\n\t\tres = dir_alloc(dp, nent);\t\t/* Allocate directory entries */\n\t\tif (res != FR_OK) return res;\n\t\tdp->blk_ofs = dp->dptr - SZDIRE * (nent - 1);\t/* Set the allocated entry block offset */\n\n\t\tif (dp->obj.stat & 4) {\t\t\t/* Has the directory been stretched by new allocation? */\n\t\t\tdp->obj.stat &= ~4;\n\t\t\tres = fill_first_frag(&dp->obj);\t/* Fill the first fragment on the FAT if needed */\n\t\t\tif (res != FR_OK) return res;\n\t\t\tres = fill_last_frag(&dp->obj, dp->clust, 0xFFFFFFFF);\t/* Fill the last fragment on the FAT if needed */\n\t\t\tif (res != FR_OK) return res;\n\t\t\tif (dp->obj.sclust != 0) {\t\t/* Is it a sub-directory? */\n\t\t\t\tDIR dj;\n\n\t\t\t\tres = load_obj_xdir(&dj, &dp->obj);\t/* Load the object status */\n\t\t\t\tif (res != FR_OK) return res;\n\t\t\t\tdp->obj.objsize += (DWORD)fs->csize * SS(fs);\t\t\t/* Increase the directory size by cluster size */\n\t\t\t\tst_qword(fs->dirbuf + XDIR_FileSize, dp->obj.objsize);\t/* Update the allocation status */\n\t\t\t\tst_qword(fs->dirbuf + XDIR_ValidFileSize, dp->obj.objsize);\n\t\t\t\tfs->dirbuf[XDIR_GenFlags] = dp->obj.stat | 1;\n\t\t\t\tres = store_xdir(&dj);\t\t\t\t/* Store the object status */\n\t\t\t\tif (res != FR_OK) return res;\n\t\t\t}\n\t\t}\n\n\t\tcreate_xdir(fs->dirbuf, fs->lfnbuf);\t/* Create on-memory directory block to be written later */\n\t\treturn FR_OK;\n\t}\n#endif\n\t/* On the FAT/FAT32 volume */\n\tmem_cpy(sn, dp->fn, 12);\n\tif (sn[NSFLAG] & NS_LOSS) {\t\t\t/* When LFN is out of 8.3 format, generate a numbered name */\n\t\tdp->fn[NSFLAG] = NS_NOLFN;\t\t/* Find only SFN */\n\t\tfor (n = 1; n < 100; n++) {\n\t\t\tgen_numname(dp->fn, sn, fs->lfnbuf, n);\t/* Generate a numbered name */\n\t\t\tres = dir_find(dp);\t\t\t\t/* Check if the name collides with existing SFN */\n\t\t\tif (res != FR_OK) break;\n\t\t}\n\t\tif (n == 100) return FR_DENIED;\t\t/* Abort if too many collisions */\n\t\tif (res != FR_NO_FILE) return res;\t/* Abort if the result is other than 'not collided' */\n\t\tdp->fn[NSFLAG] = sn[NSFLAG];\n\t}\n\n\t/* Create an SFN with/without LFNs. */\n\tnent = (sn[NSFLAG] & NS_LFN) ? (nlen + 12) / 13 + 1 : 1;\t/* Number of entries to allocate */\n\tres = dir_alloc(dp, nent);\t\t/* Allocate entries */\n\tif (res == FR_OK && --nent) {\t/* Set LFN entry if needed */\n\t\tres = dir_sdi(dp, dp->dptr - nent * SZDIRE);\n\t\tif (res == FR_OK) {\n\t\t\tsum = sum_sfn(dp->fn);\t/* Checksum value of the SFN tied to the LFN */\n\t\t\tdo {\t\t\t\t\t/* Store LFN entries in bottom first */\n\t\t\t\tres = move_window(fs, dp->sect);\n\t\t\t\tif (res != FR_OK) break;\n\t\t\t\tput_lfn(fs->lfnbuf, dp->dir, (BYTE)nent, sum);\n\t\t\t\tfs->wflag = 1;\n\t\t\t\tres = dir_next(dp, 0);\t/* Next entry */\n\t\t\t} while (res == FR_OK && --nent);\n\t\t}\n\t}\n\n#else\t/* Non LFN configuration */\n\tres = dir_alloc(dp, 1);\t\t/* Allocate an entry for SFN */\n\n#endif\n\n\t/* Set SFN entry */\n\tif (res == FR_OK) {\n\t\tres = move_window(fs, dp->sect);\n\t\tif (res == FR_OK) {\n\t\t\tmem_set(dp->dir, 0, SZDIRE);\t/* Clean the entry */\n\t\t\tmem_cpy(dp->dir + DIR_Name, dp->fn, 11);\t/* Put SFN */\n#if FF_USE_LFN\n\t\t\tdp->dir[DIR_NTres] = dp->fn[NSFLAG] & (NS_BODY | NS_EXT);\t/* Put NT flag */\n#endif\n\t\t\tfs->wflag = 1;\n\t\t}\n\t}\n\n\treturn res;\n}\n\n#endif /* !FF_FS_READONLY */\n\n\n\n#if !FF_FS_READONLY && FF_FS_MINIMIZE == 0\n/*-----------------------------------------------------------------------*/\n/* Remove an object from the directory                                   */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT dir_remove (\t/* FR_OK:Succeeded, FR_DISK_ERR:A disk error */\n\tDIR* dp\t\t\t\t\t/* Directory object pointing the entry to be removed */\n)\n{\n\tFRESULT res;\n\tFATFS *fs = dp->obj.fs;\n#if FF_USE_LFN\t\t/* LFN configuration */\n\tDWORD last = dp->dptr;\n\n\tres = (dp->blk_ofs == 0xFFFFFFFF) ? FR_OK : dir_sdi(dp, dp->blk_ofs);\t/* Goto top of the entry block if LFN is exist */\n\tif (res == FR_OK) {\n\t\tdo {\n\t\t\tres = move_window(fs, dp->sect);\n\t\t\tif (res != FR_OK) break;\n\t\t\tif (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) {\t/* On the exFAT volume */\n\t\t\t\tdp->dir[XDIR_Type] &= 0x7F;\t/* Clear the entry InUse flag. */\n\t\t\t} else {\t\t\t\t\t\t\t\t\t/* On the FAT/FAT32 volume */\n\t\t\t\tdp->dir[DIR_Name] = DDEM;\t/* Mark the entry 'deleted'. */\n\t\t\t}\n\t\t\tfs->wflag = 1;\n\t\t\tif (dp->dptr >= last) break;\t/* If reached last entry then all entries of the object has been deleted. */\n\t\t\tres = dir_next(dp, 0);\t/* Next entry */\n\t\t} while (res == FR_OK);\n\t\tif (res == FR_NO_FILE) res = FR_INT_ERR;\n\t}\n#else\t\t\t/* Non LFN configuration */\n\n\tres = move_window(fs, dp->sect);\n\tif (res == FR_OK) {\n\t\tdp->dir[DIR_Name] = DDEM;\t/* Mark the entry 'deleted'.*/\n\t\tfs->wflag = 1;\n\t}\n#endif\n\n\treturn res;\n}\n\n#endif /* !FF_FS_READONLY && FF_FS_MINIMIZE == 0 */\n\n\n\n#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2\n/*-----------------------------------------------------------------------*/\n/* Get file information from directory entry                             */\n/*-----------------------------------------------------------------------*/\n\nstatic void get_fileinfo (\n\tDIR* dp,\t\t\t/* Pointer to the directory object */\n\tFILINFO* fno\t\t/* Pointer to the file information to be filled */\n)\n{\n\tUINT si, di;\n#if FF_USE_LFN\n\tBYTE lcf;\n\tWCHAR wc, hs;\n\tFATFS *fs = dp->obj.fs;\n#else\n\tTCHAR c;\n#endif\n\n\n\tfno->fname[0] = 0;\t\t\t/* Invaidate file info */\n\tif (dp->sect == 0) return;\t/* Exit if read pointer has reached end of directory */\n\n#if FF_USE_LFN\t\t/* LFN configuration */\n#if FF_FS_EXFAT\n\tif (fs->fs_type == FS_EXFAT) {\t/* On the exFAT volume */\n\t\tget_xfileinfo(fs->dirbuf, fno);\n\t\treturn;\n\t} else\n#endif\n\t{\t/* On the FAT/FAT32 volume */\n\t\tif (dp->blk_ofs != 0xFFFFFFFF) {\t/* Get LFN if available */\n\t\t\tsi = di = hs = 0;\n\t\t\twhile (fs->lfnbuf[si] != 0) {\n\t\t\t\twc = fs->lfnbuf[si++];\t\t/* Get an LFN character (UTF-16) */\n\t\t\t\tif (hs == 0 && IsSurrogate(wc)) {\t/* Is it a surrogate? */\n\t\t\t\t\ths = wc; continue;\t\t/* Get low surrogate */\n\t\t\t\t}\n\t\t\t\twc = put_utf((DWORD)hs << 16 | wc, &fno->fname[di], FF_LFN_BUF - di);\t/* Store it in UTF-16 or UTF-8 encoding */\n\t\t\t\tif (wc == 0) { di = 0; break; }\t/* Invalid char or buffer overflow? */\n\t\t\t\tdi += wc;\n\t\t\t\ths = 0;\n\t\t\t}\n\t\t\tif (hs != 0) di = 0;\t/* Broken surrogate pair? */\n\t\t\tfno->fname[di] = 0;\t\t/* Terminate the LFN (null string means LFN is invalid) */\n\t\t}\n\t}\n\n\tsi = di = 0;\n\twhile (si < 11) {\t\t/* Get SFN from SFN entry */\n\t\twc = dp->dir[si++];\t\t\t/* Get a char */\n\t\tif (wc == ' ') continue;\t/* Skip padding spaces */\n\t\tif (wc == RDDEM) wc = DDEM;\t/* Restore replaced DDEM character */\n\t\tif (si == 9 && di < FF_SFN_BUF) fno->altname[di++] = '.';\t/* Insert a . if extension is exist */\n#if FF_LFN_UNICODE >= 1\t/* Unicode output */\n\t\tif (dbc_1st((BYTE)wc) && si != 8 && si != 11 && dbc_2nd(dp->dir[si])) {\t/* Make a DBC if needed */\n\t\t\twc = wc << 8 | dp->dir[si++];\n\t\t}\n\t\twc = ff_oem2uni(wc, CODEPAGE);\t\t/* ANSI/OEM -> Unicode */\n\t\tif (wc == 0) { di = 0; break; }\t\t/* Wrong char in the current code page? */\n\t\twc = put_utf(wc, &fno->altname[di], FF_SFN_BUF - di);\t/* Store it in Unicode */\n\t\tif (wc == 0) { di = 0; break; }\t\t/* Buffer overflow? */\n\t\tdi += wc;\n#else\t\t\t\t\t/* ANSI/OEM output */\n\t\tfno->altname[di++] = (TCHAR)wc;\t/* Store it without any conversion */\n#endif\n\t}\n\tfno->altname[di] = 0;\t/* Terminate the SFN  (null string means SFN is invalid) */\n\n\tif (fno->fname[0] == 0) {\t/* If LFN is invalid, altname[] needs to be copied to fname[] */\n\t\tif (di == 0) {\t/* If LFN and SFN both are invalid, this object is inaccesible */\n\t\t\tfno->fname[di++] = '?';\n\t\t} else {\n\t\t\tfor (si = di = 0, lcf = NS_BODY; fno->altname[si]; si++, di++) {\t/* Copy altname[] to fname[] with case information */\n\t\t\t\twc = (WCHAR)fno->altname[si];\n\t\t\t\tif (wc == '.') lcf = NS_EXT;\n\t\t\t\tif (IsUpper(wc) && (dp->dir[DIR_NTres] & lcf)) wc += 0x20;\n\t\t\t\tfno->fname[di] = (TCHAR)wc;\n\t\t\t}\n\t\t}\n\t\tfno->fname[di] = 0;\t/* Terminate the LFN */\n\t\tif (!dp->dir[DIR_NTres]) fno->altname[0] = 0;\t/* Altname is not needed if neither LFN nor case info is exist. */\n\t}\n\n#else\t/* Non-LFN configuration */\n\tsi = di = 0;\n\twhile (si < 11) {\t\t/* Copy name body and extension */\n\t\tc = (TCHAR)dp->dir[si++];\n\t\tif (c == ' ') continue;\t\t/* Skip padding spaces */\n\t\tif (c == RDDEM) c = DDEM;\t/* Restore replaced DDEM character */\n\t\tif (si == 9) fno->fname[di++] = '.';/* Insert a . if extension is exist */\n\t\tfno->fname[di++] = c;\n\t}\n\tfno->fname[di] = 0;\n#endif\n\n\tfno->fattrib = dp->dir[DIR_Attr];\t\t\t\t\t/* Attribute */\n\tfno->fsize = ld_dword(dp->dir + DIR_FileSize);\t\t/* Size */\n\tfno->ftime = ld_word(dp->dir + DIR_ModTime + 0);\t/* Time */\n\tfno->fdate = ld_word(dp->dir + DIR_ModTime + 2);\t/* Date */\n}\n\n#endif /* FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 */\n\n\n\n#if FF_USE_FIND && FF_FS_MINIMIZE <= 1\n/*-----------------------------------------------------------------------*/\n/* Pattern matching                                                      */\n/*-----------------------------------------------------------------------*/\n\nstatic DWORD get_achar (\t/* Get a character and advances ptr */\n\tconst TCHAR** ptr\t\t/* Pointer to pointer to the ANSI/OEM or Unicode string */\n)\n{\n\tDWORD chr;\n\n\n#if FF_USE_LFN && FF_LFN_UNICODE >= 1\t/* Unicode input */\n\tchr = tchar2uni(ptr);\n\tif (chr == 0xFFFFFFFF) chr = 0;\t\t/* Wrong UTF encoding is recognized as end of the string */\n\tchr = ff_wtoupper(chr);\n\n#else\t\t\t\t\t\t\t\t\t/* ANSI/OEM input */\n\tchr = (BYTE)*(*ptr)++;\t\t\t\t/* Get a byte */\n\tif (IsLower(chr)) chr -= 0x20;\t\t/* To upper ASCII char */\n#if FF_CODE_PAGE == 0\n\tif (ExCvt && chr >= 0x80) chr = ExCvt[chr - 0x80];\t/* To upper SBCS extended char */\n#elif FF_CODE_PAGE < 900\n\tif (chr >= 0x80) chr = ExCvt[chr - 0x80];\t/* To upper SBCS extended char */\n#endif\n#if FF_CODE_PAGE == 0 || FF_CODE_PAGE >= 900\n\tif (dbc_1st((BYTE)chr)) {\t/* Get DBC 2nd byte if needed */\n\t\tchr = dbc_2nd((BYTE)**ptr) ? chr << 8 | (BYTE)*(*ptr)++ : 0;\n\t}\n#endif\n\n#endif\n\treturn chr;\n}\n\n\nstatic int pattern_matching (\t/* 0:not matched, 1:matched */\n\tconst TCHAR* pat,\t/* Matching pattern */\n\tconst TCHAR* nam,\t/* String to be tested */\n\tint skip,\t\t\t/* Number of pre-skip chars (number of ?s) */\n\tint inf\t\t\t\t/* Infinite search (* specified) */\n)\n{\n\tconst TCHAR *pp, *np;\n\tDWORD pc, nc;\n\tint nm, nx;\n\n\n\twhile (skip--) {\t\t\t\t/* Pre-skip name chars */\n\t\tif (!get_achar(&nam)) return 0;\t/* Branch mismatched if less name chars */\n\t}\n\tif (*pat == 0 && inf) return 1;\t/* (short circuit) */\n\n\tdo {\n\t\tpp = pat; np = nam;\t\t\t/* Top of pattern and name to match */\n\t\tfor (;;) {\n\t\t\tif (*pp == '?' || *pp == '*') {\t/* Wildcard? */\n\t\t\t\tnm = nx = 0;\n\t\t\t\tdo {\t\t\t\t/* Analyze the wildcard block */\n\t\t\t\t\tif (*pp++ == '?') nm++; else nx = 1;\n\t\t\t\t} while (*pp == '?' || *pp == '*');\n\t\t\t\tif (pattern_matching(pp, np, nm, nx)) return 1;\t/* Test new branch (recurs upto number of wildcard blocks in the pattern) */\n\t\t\t\tnc = *np; break;\t/* Branch mismatched */\n\t\t\t}\n\t\t\tpc = get_achar(&pp);\t/* Get a pattern char */\n\t\t\tnc = get_achar(&np);\t/* Get a name char */\n\t\t\tif (pc != nc) break;\t/* Branch mismatched? */\n\t\t\tif (pc == 0) return 1;\t/* Branch matched? (matched at end of both strings) */\n\t\t}\n\t\tget_achar(&nam);\t\t\t/* nam++ */\n\t} while (inf && nc);\t\t\t/* Retry until end of name if infinite search is specified */\n\n\treturn 0;\n}\n\n#endif /* FF_USE_FIND && FF_FS_MINIMIZE <= 1 */\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Pick a top segment and create the object name in directory form       */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT create_name (\t/* FR_OK: successful, FR_INVALID_NAME: could not create */\n\tDIR* dp,\t\t\t\t\t/* Pointer to the directory object */\n\tconst TCHAR** path\t\t\t/* Pointer to pointer to the segment in the path string */\n)\n{\n#if FF_USE_LFN\t\t/* LFN configuration */\n\tBYTE b, cf;\n\tWCHAR wc, *lfn;\n\tDWORD uc;\n\tUINT i, ni, si, di;\n\tconst TCHAR *p;\n\n\n\t/* Create LFN into LFN working buffer */\n\tp = *path; lfn = dp->obj.fs->lfnbuf; di = 0;\n\tfor (;;) {\n\t\tuc = tchar2uni(&p);\t\t\t/* Get a character */\n\t\tif (uc == 0xFFFFFFFF) return FR_INVALID_NAME;\t\t/* Invalid code or UTF decode error */\n\t\tif (uc >= 0x10000) lfn[di++] = (WCHAR)(uc >> 16);\t/* Store high surrogate if needed */\n\t\twc = (WCHAR)uc;\n\t\tif (wc < ' ' || wc == '/' || wc == '\\\\') break;\t/* Break if end of the path or a separator is found */\n\t\tif (wc < 0x80 && chk_chr(\"\\\"*:<>\\?|\\x7F\", wc)) return FR_INVALID_NAME;\t/* Reject illegal characters for LFN */\n\t\tif (di >= FF_MAX_LFN) return FR_INVALID_NAME;\t/* Reject too long name */\n\t\tlfn[di++] = wc;\t\t\t\t\t/* Store the Unicode character */\n\t}\n\twhile (*p == '/' || *p == '\\\\') p++;\t/* Skip duplicated separators if exist */\n\t*path = p;\t\t\t\t\t\t\t/* Return pointer to the next segment */\n\tcf = (wc < ' ') ? NS_LAST : 0;\t\t/* Set last segment flag if end of the path */\n\n#if FF_FS_RPATH != 0\n\tif ((di == 1 && lfn[di - 1] == '.') ||\n\t\t(di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) {\t/* Is this segment a dot name? */\n\t\tlfn[di] = 0;\n\t\tfor (i = 0; i < 11; i++) {\t\t/* Create dot name for SFN entry */\n\t\t\tdp->fn[i] = (i < di) ? '.' : ' ';\n\t\t}\n\t\tdp->fn[i] = cf | NS_DOT;\t\t/* This is a dot entry */\n\t\treturn FR_OK;\n\t}\n#endif\n\twhile (di) {\t\t\t\t\t\t/* Snip off trailing spaces and dots if exist */\n\t\twc = lfn[di - 1];\n\t\tif (wc != ' ' && wc != '.') break;\n\t\tdi--;\n\t}\n\tlfn[di] = 0;\t\t\t\t\t\t\t/* LFN is created into the working buffer */\n\tif (di == 0) return FR_INVALID_NAME;\t/* Reject null name */\n\n\t/* Create SFN in directory form */\n\tfor (si = 0; lfn[si] == ' '; si++) ;\t/* Remove leading spaces */\n\tif (si > 0 || lfn[si] == '.') cf |= NS_LOSS | NS_LFN;\t/* Is there any leading space or dot? */\n\twhile (di > 0 && lfn[di - 1] != '.') di--;\t/* Find last dot (di<=si: no extension) */\n\n\tmem_set(dp->fn, ' ', 11);\n\ti = b = 0; ni = 8;\n\tfor (;;) {\n\t\twc = lfn[si++];\t\t\t\t\t/* Get an LFN character */\n\t\tif (wc == 0) break;\t\t\t\t/* Break on end of the LFN */\n\t\tif (wc == ' ' || (wc == '.' && si != di)) {\t/* Remove embedded spaces and dots */\n\t\t\tcf |= NS_LOSS | NS_LFN;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (i >= ni || si == di) {\t\t/* End of field? */\n\t\t\tif (ni == 11) {\t\t\t\t/* Name extension overflow? */\n\t\t\t\tcf |= NS_LOSS | NS_LFN;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (si != di) cf |= NS_LOSS | NS_LFN;\t/* Name body overflow? */\n\t\t\tif (si > di) break;\t\t\t\t\t\t/* No name extension? */\n\t\t\tsi = di; i = 8; ni = 11; b <<= 2;\t\t/* Enter name extension */\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (wc >= 0x80) {\t/* Is this a non-ASCII character? */\n\t\t\tcf |= NS_LFN;\t/* LFN entry needs to be created */\n#if FF_CODE_PAGE == 0\n\t\t\tif (ExCvt) {\t/* At SBCS */\n\t\t\t\twc = ff_uni2oem(wc, CODEPAGE);\t\t\t/* Unicode ==> ANSI/OEM code */\n\t\t\t\tif (wc & 0x80) wc = ExCvt[wc & 0x7F];\t/* Convert extended character to upper (SBCS) */\n\t\t\t} else {\t\t/* At DBCS */\n\t\t\t\twc = ff_uni2oem(ff_wtoupper(wc), CODEPAGE);\t/* Unicode ==> Upper convert ==> ANSI/OEM code */\n\t\t\t}\n#elif FF_CODE_PAGE < 900\t/* SBCS cfg */\n\t\t\twc = ff_uni2oem(wc, CODEPAGE);\t\t\t/* Unicode ==> ANSI/OEM code */\n\t\t\tif (wc & 0x80) wc = ExCvt[wc & 0x7F];\t/* Convert extended character to upper (SBCS) */\n#else\t\t\t\t\t\t/* DBCS cfg */\n\t\t\twc = ff_uni2oem(ff_wtoupper(wc), CODEPAGE);\t/* Unicode ==> Upper convert ==> ANSI/OEM code */\n#endif\n\t\t}\n\n\t\tif (wc >= 0x100) {\t\t\t\t/* Is this a DBC? */\n\t\t\tif (i >= ni - 1) {\t\t\t/* Field overflow? */\n\t\t\t\tcf |= NS_LOSS | NS_LFN;\n\t\t\t\ti = ni; continue;\t\t/* Next field */\n\t\t\t}\n\t\t\tdp->fn[i++] = (BYTE)(wc >> 8);\t/* Put 1st byte */\n\t\t} else {\t\t\t\t\t\t/* SBC */\n\t\t\tif (wc == 0 || chk_chr(\"+,;=[]\", wc)) {\t/* Replace illegal characters for SFN if needed */\n\t\t\t\twc = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */\n\t\t\t} else {\n\t\t\t\tif (IsUpper(wc)) {\t\t/* ASCII upper case? */\n\t\t\t\t\tb |= 2;\n\t\t\t\t}\n\t\t\t\tif (IsLower(wc)) {\t\t/* ASCII lower case? */\n\t\t\t\t\tb |= 1; wc -= 0x20;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdp->fn[i++] = (BYTE)wc;\n\t}\n\n\tif (dp->fn[0] == DDEM) dp->fn[0] = RDDEM;\t/* If the first character collides with DDEM, replace it with RDDEM */\n\n\tif (ni == 8) b <<= 2;\t\t\t\t/* Shift capital flags if no extension */\n\tif ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) cf |= NS_LFN;\t/* LFN entry needs to be created if composite capitals */\n\tif (!(cf & NS_LFN)) {\t\t\t\t/* When LFN is in 8.3 format without extended character, NT flags are created */\n\t\tif (b & 0x01) cf |= NS_EXT;\t\t/* NT flag (Extension has small capital letters only) */\n\t\tif (b & 0x04) cf |= NS_BODY;\t/* NT flag (Body has small capital letters only) */\n\t}\n\n\tdp->fn[NSFLAG] = cf;\t/* SFN is created into dp->fn[] */\n\n\treturn FR_OK;\n\n\n#else\t/* FF_USE_LFN : Non-LFN configuration */\n\tBYTE c, d, *sfn;\n\tUINT ni, si, i;\n\tconst char *p;\n\n\t/* Create file name in directory form */\n\tp = *path; sfn = dp->fn;\n\tmem_set(sfn, ' ', 11);\n\tsi = i = 0; ni = 8;\n#if FF_FS_RPATH != 0\n\tif (p[si] == '.') { /* Is this a dot entry? */\n\t\tfor (;;) {\n\t\t\tc = (BYTE)p[si++];\n\t\t\tif (c != '.' || si >= 3) break;\n\t\t\tsfn[i++] = c;\n\t\t}\n\t\tif (c != '/' && c != '\\\\' && c > ' ') return FR_INVALID_NAME;\n\t\t*path = p + si;\t\t\t\t\t\t\t\t/* Return pointer to the next segment */\n\t\tsfn[NSFLAG] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT;\t/* Set last segment flag if end of the path */\n\t\treturn FR_OK;\n\t}\n#endif\n\tfor (;;) {\n\t\tc = (BYTE)p[si++];\t\t\t\t/* Get a byte */\n\t\tif (c <= ' ') break; \t\t\t/* Break if end of the path name */\n\t\tif (c == '/' || c == '\\\\') {\t/* Break if a separator is found */\n\t\t\twhile (p[si] == '/' || p[si] == '\\\\') si++;\t/* Skip duplicated separator if exist */\n\t\t\tbreak;\n\t\t}\n\t\tif (c == '.' || i >= ni) {\t\t/* End of body or field overflow? */\n\t\t\tif (ni == 11 || c != '.') return FR_INVALID_NAME;\t/* Field overflow or invalid dot? */\n\t\t\ti = 8; ni = 11;\t\t\t\t/* Enter file extension field */\n\t\t\tcontinue;\n\t\t}\n#if FF_CODE_PAGE == 0\n\t\tif (ExCvt && c >= 0x80) {\t\t/* Is SBC extended character? */\n\t\t\tc = ExCvt[c & 0x7F];\t\t/* To upper SBC extended character */\n\t\t}\n#elif FF_CODE_PAGE < 900\n\t\tif (c >= 0x80) {\t\t\t\t/* Is SBC extended character? */\n\t\t\tc = ExCvt[c & 0x7F];\t\t/* To upper SBC extended character */\n\t\t}\n#endif\n\t\tif (dbc_1st(c)) {\t\t\t\t/* Check if it is a DBC 1st byte */\n\t\t\td = (BYTE)p[si++];\t\t\t/* Get 2nd byte */\n\t\t\tif (!dbc_2nd(d) || i >= ni - 1) return FR_INVALID_NAME;\t/* Reject invalid DBC */\n\t\t\tsfn[i++] = c;\n\t\t\tsfn[i++] = d;\n\t\t} else {\t\t\t\t\t\t/* SBC */\n\t\t\tif (chk_chr(\"\\\"*+,:;<=>\\?[]|\\x7F\", c)) return FR_INVALID_NAME;\t/* Reject illegal chrs for SFN */\n\t\t\tif (IsLower(c)) c -= 0x20;\t/* To upper */\n\t\t\tsfn[i++] = c;\n\t\t}\n\t}\n\t*path = p + si;\t\t\t\t\t\t/* Return pointer to the next segment */\n\tif (i == 0) return FR_INVALID_NAME;\t/* Reject nul string */\n\n\tif (sfn[0] == DDEM) sfn[0] = RDDEM;\t/* If the first character collides with DDEM, replace it with RDDEM */\n\tsfn[NSFLAG] = (c <= ' ') ? NS_LAST : 0;\t\t/* Set last segment flag if end of the path */\n\n\treturn FR_OK;\n#endif /* FF_USE_LFN */\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Follow a file path                                                    */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT follow_path (\t/* FR_OK(0): successful, !=0: error code */\n\tDIR* dp,\t\t\t\t\t/* Directory object to return last directory and found object */\n\tconst TCHAR* path\t\t\t/* Full-path string to find a file or directory */\n)\n{\n\tFRESULT res;\n\tBYTE ns;\n\tFATFS *fs = dp->obj.fs;\n\n\n#if FF_FS_RPATH != 0\n\tif (*path != '/' && *path != '\\\\') {\t/* Without heading separator */\n\t\tdp->obj.sclust = fs->cdir;\t\t\t\t/* Start from current directory */\n\t} else\n#endif\n\t{\t\t\t\t\t\t\t\t\t\t/* With heading separator */\n\t\twhile (*path == '/' || *path == '\\\\') path++;\t/* Strip heading separator */\n\t\tdp->obj.sclust = 0;\t\t\t\t\t/* Start from root directory */\n\t}\n#if FF_FS_EXFAT\n\tdp->obj.n_frag = 0;\t/* Invalidate last fragment counter of the object */\n#if FF_FS_RPATH != 0\n\tif (fs->fs_type == FS_EXFAT && dp->obj.sclust) {\t/* exFAT: Retrieve the sub-directory's status */\n\t\tDIR dj;\n\n\t\tdp->obj.c_scl = fs->cdc_scl;\n\t\tdp->obj.c_size = fs->cdc_size;\n\t\tdp->obj.c_ofs = fs->cdc_ofs;\n\t\tres = load_obj_xdir(&dj, &dp->obj);\n\t\tif (res != FR_OK) return res;\n\t\tdp->obj.objsize = ld_dword(fs->dirbuf + XDIR_FileSize);\n\t\tdp->obj.stat = fs->dirbuf[XDIR_GenFlags] & 2;\n\t}\n#endif\n#endif\n\n\tif ((UINT)*path < ' ') {\t\t\t\t/* Null path name is the origin directory itself */\n\t\tdp->fn[NSFLAG] = NS_NONAME;\n\t\tres = dir_sdi(dp, 0);\n\n\t} else {\t\t\t\t\t\t\t\t/* Follow path */\n\t\tfor (;;) {\n\t\t\tres = create_name(dp, &path);\t/* Get a segment name of the path */\n\t\t\tif (res != FR_OK) break;\n\t\t\tres = dir_find(dp);\t\t\t\t/* Find an object with the segment name */\n\t\t\tns = dp->fn[NSFLAG];\n\t\t\tif (res != FR_OK) {\t\t\t\t/* Failed to find the object */\n\t\t\t\tif (res == FR_NO_FILE) {\t/* Object is not found */\n\t\t\t\t\tif (FF_FS_RPATH && (ns & NS_DOT)) {\t/* If dot entry is not exist, stay there */\n\t\t\t\t\t\tif (!(ns & NS_LAST)) continue;\t/* Continue to follow if not last segment */\n\t\t\t\t\t\tdp->fn[NSFLAG] = NS_NONAME;\n\t\t\t\t\t\tres = FR_OK;\n\t\t\t\t\t} else {\t\t\t\t\t\t\t/* Could not find the object */\n\t\t\t\t\t\tif (!(ns & NS_LAST)) res = FR_NO_PATH;\t/* Adjust error code if not last segment */\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (ns & NS_LAST) break;\t\t\t/* Last segment matched. Function completed. */\n\t\t\t/* Get into the sub-directory */\n\t\t\tif (!(dp->obj.attr & AM_DIR)) {\t\t/* It is not a sub-directory and cannot follow */\n\t\t\t\tres = FR_NO_PATH; break;\n\t\t\t}\n#if FF_FS_EXFAT\n\t\t\tif (fs->fs_type == FS_EXFAT) {\t\t/* Save containing directory information for next dir */\n\t\t\t\tdp->obj.c_scl = dp->obj.sclust;\n\t\t\t\tdp->obj.c_size = ((DWORD)dp->obj.objsize & 0xFFFFFF00) | dp->obj.stat;\n\t\t\t\tdp->obj.c_ofs = dp->blk_ofs;\n\t\t\t\tinit_alloc_info(fs, &dp->obj);\t/* Open next directory */\n\t\t\t} else\n#endif\n\t\t\t{\n\t\t\t\tdp->obj.sclust = ld_clust(fs, fs->win + dp->dptr % SS(fs));\t/* Open next directory */\n\t\t\t}\n\t\t}\n\t}\n\n\treturn res;\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Get logical drive number from path name                               */\n/*-----------------------------------------------------------------------*/\n\nstatic int get_ldnumber (\t/* Returns logical drive number (-1:invalid drive number or null pointer) */\n\tconst TCHAR** path\t\t/* Pointer to pointer to the path name */\n)\n{\n\tconst TCHAR *tp, *tt;\n\tTCHAR tc;\n\tint i, vol = -1;\n#if FF_STR_VOLUME_ID\t\t/* Find string volume ID */\n\tconst char *sp;\n\tchar c;\n#endif\n\n\ttt = tp = *path;\n\tif (!tp) return vol;\t/* Invalid path name? */\n\tdo tc = *tt++; while ((UINT)tc >= (FF_USE_LFN ? ' ' : '!') && tc != ':');\t/* Find a colon in the path */\n\n\tif (tc == ':') {\t/* DOS/Windows style volume ID? */\n\t\ti = FF_VOLUMES;\n\t\tif (IsDigit(*tp) && tp + 2 == tt) {\t/* Is there a numeric volume ID + colon? */\n\t\t\ti = (int)*tp - '0';\t/* Get the LD number */\n\t\t}\n#if FF_STR_VOLUME_ID == 1\t/* Arbitrary string is enabled */\n\t\telse {\n\t\t\ti = 0;\n\t\t\tdo {\n\t\t\t\tsp = VolumeStr[i]; tp = *path;\t/* This string volume ID and path name */\n\t\t\t\tdo {\t/* Compare the volume ID with path name */\n\t\t\t\t\tc = *sp++; tc = *tp++;\n\t\t\t\t\tif (IsLower(c)) c -= 0x20;\n\t\t\t\t\tif (IsLower(tc)) tc -= 0x20;\n\t\t\t\t} while (c && (TCHAR)c == tc);\n\t\t\t} while ((c || tp != tt) && ++i < FF_VOLUMES);\t/* Repeat for each id until pattern match */\n\t\t}\n#endif\n\t\tif (i < FF_VOLUMES) {\t/* If a volume ID is found, get the drive number and strip it */\n\t\t\tvol = i;\t\t/* Drive number */\n\t\t\t*path = tt;\t\t/* Snip the drive prefix off */\n\t\t}\n\t\treturn vol;\n\t}\n#if FF_STR_VOLUME_ID == 2\t\t/* Unix style volume ID is enabled */\n\tif (*tp == '/') {\n\t\ti = 0;\n\t\tdo {\n\t\t\tsp = VolumeStr[i]; tp = *path;\t/* This string volume ID and path name */\n\t\t\tdo {\t/* Compare the volume ID with path name */\n\t\t\t\tc = *sp++; tc = *(++tp);\n\t\t\t\tif (IsLower(c)) c -= 0x20;\n\t\t\t\tif (IsLower(tc)) tc -= 0x20;\n\t\t\t} while (c && (TCHAR)c == tc);\n\t\t} while ((c || (tc != '/' && (UINT)tc >= (FF_USE_LFN ? ' ' : '!'))) && ++i < FF_VOLUMES);\t/* Repeat for each ID until pattern match */\n\t\tif (i < FF_VOLUMES) {\t/* If a volume ID is found, get the drive number and strip it */\n\t\t\tvol = i;\t\t/* Drive number */\n\t\t\t*path = tp;\t\t/* Snip the drive prefix off */\n\t\t\treturn vol;\n\t\t}\n\t}\n#endif\n\t/* No drive prefix is found */\n#if FF_FS_RPATH != 0\n\tvol = CurrVol;\t/* Default drive is current drive */\n#else\n\tvol = 0;\t\t/* Default drive is 0 */\n#endif\n\treturn vol;\t\t/* Return the default drive */\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Load a sector and check if it is an FAT VBR                           */\n/*-----------------------------------------------------------------------*/\n\nstatic BYTE check_fs (\t/* 0:FAT, 1:exFAT, 2:Valid BS but not FAT, 3:Not a BS, 4:Disk error */\n\tFATFS* fs,\t\t\t/* Filesystem object */\n\tDWORD sect\t\t\t/* Sector# (lba) to load and check if it is an FAT-VBR or not */\n)\n{\n\tfs->wflag = 0; fs->winsect = 0xFFFFFFFF;\t\t/* Invaidate window */\n\tif (move_window(fs, sect) != FR_OK) return 4;\t/* Load boot record */\n\n\tif (ld_word(fs->win + BS_55AA) != 0xAA55) return 3;\t/* Check boot record signature (always here regardless of the sector size) */\n\n#if FF_FS_EXFAT\n\tif (!mem_cmp(fs->win + BS_JmpBoot, \"\\xEB\\x76\\x90\" \"EXFAT   \", 11)) return 1;\t/* Check if exFAT VBR */\n#endif\n\tif (fs->win[BS_JmpBoot] == 0xE9 || fs->win[BS_JmpBoot] == 0xEB || fs->win[BS_JmpBoot] == 0xE8) {\t/* Valid JumpBoot code? */\n\t\tif (!mem_cmp(fs->win + BS_FilSysType, \"FAT\", 3)) return 0;\t\t/* Is it an FAT VBR? */\n\t\tif (!mem_cmp(fs->win + BS_FilSysType32, \"FAT32\", 5)) return 0;\t/* Is it an FAT32 VBR? */\n\t}\n\treturn 2;\t/* Valid BS but not FAT */\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Determine logical drive number and mount the volume if needed         */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT find_volume (\t/* FR_OK(0): successful, !=0: an error occurred */\n\tconst TCHAR** path,\t\t\t/* Pointer to pointer to the path name (drive number) */\n\tFATFS** rfs,\t\t\t\t/* Pointer to pointer to the found filesystem object */\n\tBYTE mode\t\t\t\t\t/* !=0: Check write protection for write access */\n)\n{\n\tBYTE fmt, *pt;\n\tint vol;\n\tDSTATUS stat;\n\tDWORD bsect, fasize, tsect, sysect, nclst, szbfat, br[4];\n\tWORD nrsv;\n\tFATFS *fs;\n\tUINT i;\n\n\n\t/* Get logical drive number */\n\t*rfs = 0;\n\tvol = get_ldnumber(path);\n\tif (vol < 0) return FR_INVALID_DRIVE;\n\n\t/* Check if the filesystem object is valid or not */\n\tfs = FatFs[vol];\t\t\t\t\t/* Get pointer to the filesystem object */\n\tif (!fs) return FR_NOT_ENABLED;\t\t/* Is the filesystem object available? */\n#if FF_FS_REENTRANT\n\tif (!lock_fs(fs)) return FR_TIMEOUT;\t/* Lock the volume */\n#endif\n\t*rfs = fs;\t\t\t\t\t\t\t/* Return pointer to the filesystem object */\n\n\tmode &= (BYTE)~FA_READ;\t\t\t\t/* Desired access mode, write access or not */\n\tif (fs->fs_type != 0) {\t\t\t\t/* If the volume has been mounted */\n\t\tstat = disk_status(fs->pdrv);\n\t\tif (!(stat & STA_NOINIT)) {\t\t/* and the physical drive is kept initialized */\n\t\t\tif (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) {\t/* Check write protection if needed */\n\t\t\t\tEFSPRINTF(\"WPEN1\");\n\t\t\t\treturn FR_WRITE_PROTECTED;\n\t\t\t}\n\t\t\treturn FR_OK;\t\t\t\t/* The filesystem object is valid */\n\t\t}\n\t}\n\n\t/* The filesystem object is not valid. */\n\t/* Following code attempts to mount the volume. (analyze BPB and initialize the filesystem object) */\n\n\tfs->fs_type = 0;\t\t\t\t\t/* Clear the filesystem object */\n\tfs->pdrv = LD2PD(vol);\t\t\t\t/* Bind the logical drive and a physical drive */\n\tstat = disk_initialize(fs->pdrv);\t/* Initialize the physical drive */\n\tif (stat & STA_NOINIT) { \t\t\t/* Check if the initialization succeeded */\n\t\tEFSPRINTF(\"MDNR\");\n\t\treturn FR_NOT_READY;\t\t\t/* Failed to initialize due to no medium or hard error */\n\t}\n\tif (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check disk write protection if needed */\n\t\tEFSPRINTF(\"WPEN2\");\n\t\treturn FR_WRITE_PROTECTED;\n\t}\n#if FF_MAX_SS != FF_MIN_SS\t\t\t\t/* Get sector size (multiple sector size cfg only) */\n\tif (disk_ioctl(fs->pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK) return FR_DISK_ERR;\n\tif (SS(fs) > FF_MAX_SS || SS(fs) < FF_MIN_SS || (SS(fs) & (SS(fs) - 1))) return FR_DISK_ERR;\n#endif\n\n\t/* Find an FAT partition on the drive. Supports only generic partitioning rules, FDISK (MBR) and SFD (w/o partition). */\n\tbsect = 0;\n\tfmt = check_fs(fs, bsect);\t\t\t/* Load sector 0 and check if it is an FAT-VBR as SFD */\n\tif (fmt == 2 || (fmt < 2 && LD2PT(vol) != 0)) {\t/* Not an FAT-VBR or forced partition number */\n\t\tfor (i = 0; i < 4; i++) {\t\t/* Get partition offset */\n\t\t\tpt = fs->win + (MBR_Table + i * SZ_PTE);\n\t\t\tbr[i] = pt[PTE_System] ? ld_dword(pt + PTE_StLba) : 0;\n\t\t}\n\t\ti = LD2PT(vol);\t\t\t\t\t/* Partition number: 0:auto, 1-4:forced */\n\t\tif (i != 0) i--;\n\t\tdo {\t\t\t\t\t\t\t/* Find an FAT volume */\n\t\t\tbsect = br[i];\n\t\t\tfmt = bsect ? check_fs(fs, bsect) : 3;\t/* Check the partition */\n\t\t} while (LD2PT(vol) == 0 && fmt >= 2 && ++i < 4);\n\t}\n\tif (fmt == 4) {\n\t\tEFSPRINTF(\"BRNL\");\n\t\treturn FR_DISK_ERR;\t\t/* An error occured in the disk I/O layer */\n\t}\n\tif (fmt >= 2) {\n\t\tEFSPRINTF(\"NOFAT\");\n\t\treturn FR_NO_FILESYSTEM;\t/* No FAT volume is found */\n\t}\n\n\t/* An FAT volume is found (bsect). Following code initializes the filesystem object */\n\n#if FF_FS_EXFAT\n\tif (fmt == 1) {\n\t\tQWORD maxlba;\n\t\tDWORD so, cv, bcl;\n\n\t\tfor (i = BPB_ZeroedEx; i < BPB_ZeroedEx + 53 && fs->win[i] == 0; i++) ;\t/* Check zero filler */\n\t\tif (i < BPB_ZeroedEx + 53) return FR_NO_FILESYSTEM;\n\n\t\tif (ld_word(fs->win + BPB_FSVerEx) != 0x100) return FR_NO_FILESYSTEM;\t/* Check exFAT version (must be version 1.0) */\n\n\t\tif (1 << fs->win[BPB_BytsPerSecEx] != SS(fs)) {\t/* (BPB_BytsPerSecEx must be equal to the physical sector size) */\n\t\t\tEFSPRINTF(\"EXSPS\");\n\t\t\treturn FR_NO_FILESYSTEM;\n\t\t}\n\n\t\tmaxlba = ld_qword(fs->win + BPB_TotSecEx) + bsect;\t/* Last LBA + 1 of the volume */\n\t\tif (maxlba >= 0x100000000) return FR_NO_FILESYSTEM;\t/* (It cannot be handled in 32-bit LBA) */\n\n\t\tfs->fsize = ld_dword(fs->win + BPB_FatSzEx);\t/* Number of sectors per FAT */\n\n\t\tfs->n_fats = fs->win[BPB_NumFATsEx];\t\t\t/* Number of FATs */\n\t\tif (fs->n_fats != 1) {\n\t\t\tEFSPRINTF(\"EXFNF\");\n\t\t\treturn FR_NO_FILESYSTEM;\t/* (Supports only 1 FAT) */\n\t\t}\n\n\t\tfs->csize = 1 << fs->win[BPB_SecPerClusEx];\t\t/* Cluster size */\n\t\tif (fs->csize == 0)\treturn FR_NO_FILESYSTEM;\t/* (Must be 1..32768) */\n\n\t\tnclst = ld_dword(fs->win + BPB_NumClusEx);\t\t/* Number of clusters */\n\t\tif (nclst > MAX_EXFAT) return FR_NO_FILESYSTEM;\t/* (Too many clusters) */\n\t\tfs->n_fatent = nclst + 2;\n\n\t\t/* Boundaries and Limits */\n\t\tfs->volbase = bsect;\n\t\tfs->database = bsect + ld_dword(fs->win + BPB_DataOfsEx);\n\t\tfs->fatbase = bsect + ld_dword(fs->win + BPB_FatOfsEx);\n\t\tif (maxlba < (QWORD)fs->database + nclst * fs->csize) return FR_NO_FILESYSTEM;\t/* (Volume size must not be smaller than the size requiered) */\n\t\tfs->dirbase = ld_dword(fs->win + BPB_RootClusEx);\n\n\t\t/* Get bitmap location and check if it is contiguous (implementation assumption) */\n\t\tso = i = 0;\n\t\tfor (;;) {\t/* Find the bitmap entry in the root directory (in only first cluster) */\n\t\t\tif (i == 0) {\n\t\t\t\tif (so >= fs->csize) return FR_NO_FILESYSTEM;\t/* Not found? */\n\t\t\t\tif (move_window(fs, clst2sect(fs, fs->dirbase) + so) != FR_OK) {\n\t\t\t\t\tEFSPRINTF(\"EXBM1C\");\n\t\t\t\t\treturn FR_DISK_ERR;\n\t\t\t\t}\n\t\t\t\tso++;\n\t\t\t}\n\t\t\tif (fs->win[i] == ET_BITMAP) break;\t\t\t\t/* Is it a bitmap entry? */\n\t\t\ti = (i + SZDIRE) % SS(fs);\t/* Next entry */\n\t\t}\n\t\tbcl = ld_dword(fs->win + i + 20);\t\t\t\t\t/* Bitmap cluster */\n\t\tif (bcl < 2 || bcl >= fs->n_fatent) {\n\t\t\tEFSPRINTF(\"EXBMM\");\n\t\t\treturn FR_NO_FILESYSTEM;\n\t\t}\n\t\tfs->bitbase = fs->database + fs->csize * (bcl - 2);\t/* Bitmap sector */\n\t\tfor (;;) {\t/* Check if bitmap is contiguous */\n\t\t\tif (move_window(fs, fs->fatbase + bcl / (SS(fs) / 4)) != FR_OK) return FR_DISK_ERR;\n\t\t\tcv = ld_dword(fs->win + bcl % (SS(fs) / 4) * 4);\n\t\t\tif (cv == 0xFFFFFFFF) break;\t\t\t\t/* Last link? */\n\t\t\tif (cv != ++bcl) {\n\t\t\t\tEFSPRINTF(\"EXBMM\");\n\t\t\t\treturn FR_NO_FILESYSTEM;\t/* Fragmented? */\n\t\t\t}\n\t\t}\n\n#if !FF_FS_READONLY\n\t\tfs->last_clst = fs->free_clst = 0xFFFFFFFF;\t\t/* Initialize cluster allocation information */\n#endif\n\t\tfmt = FS_EXFAT;\t\t\t/* FAT sub-type */\n\t} else\n#endif\t/* FF_FS_EXFAT */\n\t{\n\t\tif (ld_word(fs->win + BPB_BytsPerSec) != SS(fs)) {\n\t\t\tEFSPRINTF(\"32SPS\");\n\t\t\treturn FR_NO_FILESYSTEM;\t/* (BPB_BytsPerSec must be equal to the physical sector size) */\n\t\t}\n\n\t\tfasize = ld_word(fs->win + BPB_FATSz16);\t\t/* Number of sectors per FAT */\n\t\tif (fasize == 0) fasize = ld_dword(fs->win + BPB_FATSz32);\n\t\tfs->fsize = fasize;\n\n\t\tfs->n_fats = fs->win[BPB_NumFATs];\t\t\t\t/* Number of FATs */\n\t\tif (fs->n_fats != 1 && fs->n_fats != 2) return FR_NO_FILESYSTEM;\t/* (Must be 1 or 2) */\n\t\tfasize *= fs->n_fats;\t\t\t\t\t\t\t/* Number of sectors for FAT area */\n\n\t\tfs->csize = fs->win[BPB_SecPerClus];\t\t\t/* Cluster size */\n\t\tif (fs->csize == 0 || (fs->csize & (fs->csize - 1))) return FR_NO_FILESYSTEM;\t/* (Must be power of 2) */\n\n\t\tfs->n_rootdir = ld_word(fs->win + BPB_RootEntCnt);\t/* Number of root directory entries */\n\t\tif (fs->n_rootdir % (SS(fs) / SZDIRE)) return FR_NO_FILESYSTEM;\t/* (Must be sector aligned) */\n\n\t\ttsect = ld_word(fs->win + BPB_TotSec16);\t\t/* Number of sectors on the volume */\n\t\tif (tsect == 0) tsect = ld_dword(fs->win + BPB_TotSec32);\n\n\t\tnrsv = ld_word(fs->win + BPB_RsvdSecCnt);\t\t/* Number of reserved sectors */\n\t\tif (nrsv == 0) return FR_NO_FILESYSTEM;\t\t\t/* (Must not be 0) */\n\n\t\t/* Determine the FAT sub type */\n\t\tsysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE);\t/* RSV + FAT + DIR */\n\t\tif (tsect < sysect) return FR_NO_FILESYSTEM;\t/* (Invalid volume size) */\n\t\tnclst = (tsect - sysect) / fs->csize;\t\t\t/* Number of clusters */\n\t\tif (nclst == 0) return FR_NO_FILESYSTEM;\t\t/* (Invalid volume size) */\n\t\tfmt = 0;\n\t\tif (nclst <= MAX_FAT32) fmt = FS_FAT32;\n\t\tif (nclst <= MAX_FAT16) fmt = FS_FAT16;\n\t\tif (nclst <= MAX_FAT12) fmt = FS_FAT12;\n\t\tif (fmt == 0) return FR_NO_FILESYSTEM;\n\n\t\t/* Boundaries and Limits */\n\t\tfs->n_fatent = nclst + 2;\t\t\t\t\t\t/* Number of FAT entries */\n\t\tfs->volbase = bsect;\t\t\t\t\t\t\t/* Volume start sector */\n\t\tfs->fatbase = bsect + nrsv; \t\t\t\t\t/* FAT start sector */\n\t\tfs->database = bsect + sysect;\t\t\t\t\t/* Data start sector */\n\t\tif (fmt == FS_FAT32) {\n\t\t\tif (ld_word(fs->win + BPB_FSVer32) != 0) return FR_NO_FILESYSTEM;\t/* (Must be FAT32 revision 0.0) */\n\t\t\tif (fs->n_rootdir != 0) return FR_NO_FILESYSTEM;\t/* (BPB_RootEntCnt must be 0) */\n\t\t\tfs->dirbase = ld_dword(fs->win + BPB_RootClus32);\t/* Root directory start cluster */\n\t\t\tszbfat = fs->n_fatent * 4;\t\t\t\t\t/* (Needed FAT size) */\n\t\t} else {\n\t\t\tif (fs->n_rootdir == 0)\treturn FR_NO_FILESYSTEM;\t/* (BPB_RootEntCnt must not be 0) */\n\t\t\tfs->dirbase = fs->fatbase + fasize;\t\t\t/* Root directory start sector */\n\t\t\tszbfat = (fmt == FS_FAT16) ?\t\t\t\t/* (Needed FAT size) */\n\t\t\t\tfs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);\n\t\t}\n\t\tif (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) return FR_NO_FILESYSTEM;\t/* (BPB_FATSz must not be less than the size needed) */\n\n#if !FF_FS_READONLY\n\t\t/* Get FSInfo if available */\n\t\tfs->last_clst = fs->free_clst = 0xFFFFFFFF;\t\t/* Initialize cluster allocation information */\n\t\tfs->fsi_flag = 0x80;\n#if (FF_FS_NOFSINFO & 3) != 3\n\t\tif (fmt == FS_FAT32\t\t\t\t/* Allow to update FSInfo only if BPB_FSInfo32 == 1 */\n\t\t\t&& ld_word(fs->win + BPB_FSInfo32) == 1\n\t\t\t&& move_window(fs, bsect + 1) == FR_OK)\n\t\t{\n\t\t\tfs->fsi_flag = 0;\n\t\t\tif (ld_word(fs->win + BS_55AA) == 0xAA55\t/* Load FSInfo data if available */\n\t\t\t\t&& ld_dword(fs->win + FSI_LeadSig) == 0x41615252\n\t\t\t\t&& ld_dword(fs->win + FSI_StrucSig) == 0x61417272)\n\t\t\t{\n#if (FF_FS_NOFSINFO & 1) == 0\n\t\t\t\tfs->free_clst = ld_dword(fs->win + FSI_Free_Count);\n#endif\n#if (FF_FS_NOFSINFO & 2) == 0\n\t\t\t\tfs->last_clst = ld_dword(fs->win + FSI_Nxt_Free);\n#endif\n\t\t\t}\n\t\t}\n#endif\t/* (FF_FS_NOFSINFO & 3) != 3 */\n#endif\t/* !FF_FS_READONLY */\n\t}\n\n\tfs->fs_type = fmt;\t\t/* FAT sub-type */\n\tfs->id = ++Fsid;\t\t/* Volume mount ID */\n#if FF_USE_LFN == 1\n\tfs->lfnbuf = LfnBuf;\t/* Static LFN working buffer */\n#if FF_FS_EXFAT\n\tfs->dirbuf = DirBuf;\t/* Static directory block scratchpad buffer */\n#endif\n#endif\n#if FF_FS_RPATH != 0\n\tfs->cdir = 0;\t\t\t/* Initialize current directory */\n#endif\n#if FF_FS_LOCK != 0\t\t\t/* Clear file lock semaphores */\n\tclear_lock(fs);\n#endif\n\treturn FR_OK;\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Check if the file/directory object is valid or not                    */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT validate (\t/* Returns FR_OK or FR_INVALID_OBJECT */\n\tFFOBJID* obj,\t\t\t/* Pointer to the FFOBJID, the 1st member in the FIL/DIR object, to check validity */\n\tFATFS** rfs\t\t\t\t/* Pointer to pointer to the owner filesystem object to return */\n)\n{\n\tFRESULT res = FR_INVALID_OBJECT;\n\n\n\tif (obj && obj->fs && obj->fs->fs_type && obj->id == obj->fs->id) {\t/* Test if the object is valid */\n#if FF_FS_REENTRANT\n\t\tif (lock_fs(obj->fs)) {\t/* Obtain the filesystem object */\n\t\t\tif (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */\n\t\t\t\tres = FR_OK;\n\t\t\t} else {\n\t\t\t\tunlock_fs(obj->fs, FR_OK);\n\t\t\t}\n\t\t} else {\n\t\t\tres = FR_TIMEOUT;\n\t\t}\n#else\n\t\tif (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */\n\t\t\tres = FR_OK;\n\t\t}\n#endif\n\t}\n\t*rfs = (res == FR_OK) ? obj->fs : 0;\t/* Corresponding filesystem object */\n\treturn res;\n}\n\n\n\n\n/*---------------------------------------------------------------------------\n\n   Public Functions (FatFs API)\n\n----------------------------------------------------------------------------*/\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Mount/Unmount a Logical Drive                                         */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_mount (\n\tFATFS* fs,\t\t\t/* Pointer to the filesystem object (NULL:unmount)*/\n\tconst TCHAR* path,\t/* Logical drive number to be mounted/unmounted */\n\tBYTE opt\t\t\t/* Mode option 0:Do not mount (delayed mount), 1:Mount immediately */\n)\n{\n\tFATFS *cfs;\n\tint vol;\n\tFRESULT res;\n\tconst TCHAR *rp = path;\n\n\n\t/* Get logical drive number */\n\tvol = get_ldnumber(&rp);\n\tif (vol < 0) {\n\t\tEFSPRINTF(\"IDRIVE!\");\n\t\treturn FR_INVALID_DRIVE;\n\t}\n\tcfs = FatFs[vol];\t\t\t\t\t/* Pointer to fs object */\n\n\tif (cfs) {\n#if FF_FS_LOCK != 0\n\t\tclear_lock(cfs);\n#endif\n#if FF_FS_REENTRANT\t\t\t\t\t\t/* Discard sync object of the current volume */\n\t\tif (!ff_del_syncobj(cfs->sobj)) return FR_INT_ERR;\n#endif\n\t\tcfs->fs_type = 0;\t\t\t\t/* Clear old fs object */\n\t}\n\n\tif (fs) {\n\t\tfs->fs_type = 0;\t\t\t\t/* Clear new fs object */\n#if FF_FS_REENTRANT\t\t\t\t\t\t/* Create sync object for the new volume */\n\t\tif (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR;\n#endif\n\t}\n\tFatFs[vol] = fs;\t\t\t\t\t/* Register new fs object */\n\n\tif (opt == 0) return FR_OK;\t\t\t/* Do not mount now, it will be mounted later */\n\n\tres = find_volume(&path, &fs, 0);\t/* Force mounted the volume */\n\tLEAVE_FF(fs, res);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Open or Create a File                                                 */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_open (\n\tFIL* fp,\t\t\t/* Pointer to the blank file object */\n\tconst TCHAR* path,\t/* Pointer to the file name */\n\tBYTE mode\t\t\t/* Access mode and file open mode flags */\n)\n{\n\tFRESULT res;\n\tDIR dj;\n\tFATFS *fs;\n#if !FF_FS_READONLY\n\tDWORD dw, cl, bcs, clst, sc;\n\tFSIZE_t ofs;\n#endif\n\tDEF_NAMBUF\n\n\n\tif (!fp) return FR_INVALID_OBJECT;\n\n\t/* Get logical drive number */\n\tmode &= FF_FS_READONLY ? FA_READ : FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_CREATE_NEW | FA_OPEN_ALWAYS | FA_OPEN_APPEND;\n\tres = find_volume(&path, &fs, mode);\n\tif (res == FR_OK) {\n\t\tdj.obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\t\tres = follow_path(&dj, path);\t/* Follow the file path */\n#if !FF_FS_READONLY\t/* Read/Write configuration */\n\t\tif (res == FR_OK) {\n\t\t\tif (dj.fn[NSFLAG] & NS_NONAME) {\t/* Origin directory itself? */\n\t\t\t\tres = FR_INVALID_NAME;\n\t\t\t}\n#if FF_FS_LOCK != 0\n\t\t\telse {\n\t\t\t\tres = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0);\t\t/* Check if the file can be used */\n\t\t\t}\n#endif\n\t\t}\n\t\t/* Create or Open a file */\n\t\tif (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) {\n\t\t\tif (res != FR_OK) {\t\t\t\t\t/* No file, create new */\n\t\t\t\tif (res == FR_NO_FILE) {\t\t/* There is no file to open, create a new entry */\n#if FF_FS_LOCK != 0\n\t\t\t\t\tres = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES;\n#else\n\t\t\t\t\tres = dir_register(&dj);\n#endif\n\t\t\t\t}\n\t\t\t\tmode |= FA_CREATE_ALWAYS;\t\t/* File is created */\n\t\t\t}\n\t\t\telse {\t\t\t\t\t\t\t\t/* Any object with the same name is already existing */\n\t\t\t\tif (dj.obj.attr & (AM_RDO | AM_DIR)) {\t/* Cannot overwrite it (R/O or DIR) */\n\t\t\t\t\tres = FR_DENIED;\n\t\t\t\t} else {\n\t\t\t\t\tif (mode & FA_CREATE_NEW) res = FR_EXIST;\t/* Cannot create as new file */\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (res == FR_OK && (mode & FA_CREATE_ALWAYS)) {\t/* Truncate the file if overwrite mode */\n#if FF_FS_EXFAT\n\t\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\t\t/* Get current allocation info */\n\t\t\t\t\tfp->obj.fs = fs;\n\t\t\t\t\tinit_alloc_info(fs, &fp->obj);\n\t\t\t\t\t/* Set directory entry block initial state */\n\t\t\t\t\tmem_set(fs->dirbuf + 2, 0, 30);\t\t/* Clear 85 entry except for NumSec */\n\t\t\t\t\tmem_set(fs->dirbuf + 38, 0, 26);\t/* Clear C0 entry except for NumName and NameHash */\n\t\t\t\t\tfs->dirbuf[XDIR_Attr] = AM_ARC;\n\t\t\t\t\tst_dword(fs->dirbuf + XDIR_CrtTime, GET_FATTIME());\n\t\t\t\t\tfs->dirbuf[XDIR_GenFlags] = 1;\n\t\t\t\t\tres = store_xdir(&dj);\n\t\t\t\t\tif (res == FR_OK && fp->obj.sclust != 0) {\t/* Remove the cluster chain if exist */\n\t\t\t\t\t\tres = remove_chain(&fp->obj, fp->obj.sclust, 0);\n\t\t\t\t\t\tfs->last_clst = fp->obj.sclust - 1;\t\t/* Reuse the cluster hole */\n\t\t\t\t\t}\n\t\t\t\t} else\n#endif\n\t\t\t\t{\n\t\t\t\t\t/* Set directory entry initial state */\n\t\t\t\t\tcl = ld_clust(fs, dj.dir);\t\t\t/* Get current cluster chain */\n\t\t\t\t\tst_dword(dj.dir + DIR_CrtTime, GET_FATTIME());\t/* Set created time */\n\t\t\t\t\tdj.dir[DIR_Attr] = AM_ARC;\t\t\t/* Reset attribute */\n\t\t\t\t\tst_clust(fs, dj.dir, 0);\t\t\t/* Reset file allocation info */\n\t\t\t\t\tst_dword(dj.dir + DIR_FileSize, 0);\n\t\t\t\t\tfs->wflag = 1;\n\t\t\t\t\tif (cl != 0) {\t\t\t\t\t\t/* Remove the cluster chain if exist */\n\t\t\t\t\t\tdw = fs->winsect;\n\t\t\t\t\t\tres = remove_chain(&dj.obj, cl, 0);\n\t\t\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\t\t\tres = move_window(fs, dw);\n\t\t\t\t\t\t\tfs->last_clst = cl - 1;\t\t/* Reuse the cluster hole */\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\t/* Open an existing file */\n\t\t\tif (res == FR_OK) {\t\t\t\t\t/* Is the object exsiting? */\n\t\t\t\tif (dj.obj.attr & AM_DIR) {\t\t/* File open against a directory */\n\t\t\t\t\tres = FR_NO_FILE;\n\t\t\t\t} else {\n\t\t\t\t\tif ((mode & FA_WRITE) && (dj.obj.attr & AM_RDO)) { /* Write mode open against R/O file */\n\t\t\t\t\t\tres = FR_DENIED;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (res == FR_OK) {\n\t\t\tif (mode & FA_CREATE_ALWAYS) mode |= FA_MODIFIED;\t/* Set file change flag if created or overwritten */\n\t\t\tfp->dir_sect = fs->winsect;\t\t\t/* Pointer to the directory entry */\n\t\t\tfp->dir_ptr = dj.dir;\n#if FF_FS_LOCK != 0\n\t\t\tfp->obj.lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0);\t/* Lock the file for this session */\n\t\t\tif (fp->obj.lockid == 0) res = FR_INT_ERR;\n#endif\n\t\t}\n#else\t\t/* R/O configuration */\n\t\tif (res == FR_OK) {\n\t\t\tif (dj.fn[NSFLAG] & NS_NONAME) {\t/* Is it origin directory itself? */\n\t\t\t\tres = FR_INVALID_NAME;\n\t\t\t} else {\n\t\t\t\tif (dj.obj.attr & AM_DIR) {\t\t/* Is it a directory? */\n\t\t\t\t\tres = FR_NO_FILE;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n#endif\n\n\t\tif (res == FR_OK) {\n#if FF_FS_EXFAT\n\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\tfp->obj.c_scl = dj.obj.sclust;\t\t\t\t\t\t\t/* Get containing directory info */\n\t\t\t\tfp->obj.c_size = ((DWORD)dj.obj.objsize & 0xFFFFFF00) | dj.obj.stat;\n\t\t\t\tfp->obj.c_ofs = dj.blk_ofs;\n\t\t\t\tinit_alloc_info(fs, &fp->obj);\n\t\t\t} else\n#endif\n\t\t\t{\n\t\t\t\tfp->obj.sclust = ld_clust(fs, dj.dir);\t\t\t\t\t/* Get object allocation info */\n\t\t\t\tfp->obj.objsize = ld_dword(dj.dir + DIR_FileSize);\n\t\t\t}\n#if FF_USE_FASTSEEK\n\t\t\tfp->cltbl = 0;\t\t\t/* Disable fast seek mode */\n#endif\n\t\t\tfp->obj.fs = fs;\t \t/* Validate the file object */\n\t\t\tfp->obj.id = fs->id;\n\t\t\tfp->flag = mode;\t\t/* Set file access mode */\n\t\t\tfp->err = 0;\t\t\t/* Clear error flag */\n\t\t\tfp->sect = 0;\t\t\t/* Invalidate current data sector */\n\t\t\tfp->fptr = 0;\t\t\t/* Set file pointer top of the file */\n#if !FF_FS_READONLY\n#if !FF_FS_TINY\n\t\t\tmem_set(fp->buf, 0, sizeof fp->buf);\t/* Clear sector buffer */\n#endif\n\t\t\tif ((mode & FA_SEEKEND) && fp->obj.objsize > 0) {\t/* Seek to end of file if FA_OPEN_APPEND is specified */\n\t\t\t\tfp->fptr = fp->obj.objsize;\t\t\t/* Offset to seek */\n\t\t\t\tbcs = (DWORD)fs->csize * SS(fs);\t/* Cluster size in byte */\n\t\t\t\tclst = fp->obj.sclust;\t\t\t\t/* Follow the cluster chain */\n\t\t\t\tfor (ofs = fp->obj.objsize; res == FR_OK && ofs > bcs; ofs -= bcs) {\n\t\t\t\t\tclst = get_fat(&fp->obj, clst);\n\t\t\t\t\tif (clst <= 1) res = FR_INT_ERR;\n\t\t\t\t\tif (clst == 0xFFFFFFFF) res = FR_DISK_ERR;\n\t\t\t\t}\n\t\t\t\tfp->clust = clst;\n\t\t\t\tif (res == FR_OK && ofs % SS(fs)) {\t/* Fill sector buffer if not on the sector boundary */\n\t\t\t\t\tif ((sc = clst2sect(fs, clst)) == 0) {\n\t\t\t\t\t\tres = FR_INT_ERR;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfp->sect = sc + (DWORD)(ofs / SS(fs));\n#if !FF_FS_TINY\n\t\t\t\t\t\tif (disk_read(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) res = FR_DISK_ERR;\n#endif\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n#endif\n\t\t}\n\n\t\tFREE_NAMBUF();\n\t}\n\n\tif (res != FR_OK) fp->obj.fs = 0;\t/* Invalidate file object on error */\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Read File                                                             */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_read (\n\tFIL* fp, \t/* Pointer to the file object */\n\tvoid* buff,\t/* Pointer to data buffer */\n\tUINT btr,\t/* Number of bytes to read */\n\tUINT* br\t/* Pointer to number of bytes read */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDWORD clst, sect;\n\tFSIZE_t remain;\n\tUINT rcnt, cc, csect;\n\tBYTE *rbuff = (BYTE*)buff;\n\n\tUINT br_tmp;\n\tif (!br)\n\t\tbr = &br_tmp;\n\t*br = 0;\t/* Clear read byte counter */\n\tres = validate(&fp->obj, &fs);\t\t\t\t/* Check validity of the file object */\n\tif (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {\n\t\tEFSPRINTF(\"FOV\");\n\t\tLEAVE_FF(fs, res);\t/* Check validity */\n\t}\n\tif (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */\n\tremain = fp->obj.objsize - fp->fptr;\n\tif (btr > remain) btr = (UINT)remain;\t\t/* Truncate btr by remaining bytes */\n\n\tfor ( ;  btr;\t\t\t\t\t\t\t\t/* Repeat until btr bytes read */\n\t\tbtr -= rcnt, *br += rcnt, rbuff += rcnt, fp->fptr += rcnt) {\n\t\tif (fp->fptr % SS(fs) == 0) {\t\t\t/* On the sector boundary? */\n\t\t\tcsect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1));\t/* Sector offset in the cluster */\n\t\t\tif (csect == 0) {\t\t\t\t\t/* On the cluster boundary? */\n\t\t\t\tif (fp->fptr == 0) {\t\t\t/* On the top of the file? */\n\t\t\t\t\tclst = fp->obj.sclust;\t\t/* Follow cluster chain from the origin */\n\t\t\t\t} else {\t\t\t\t\t\t/* Middle or end of the file */\n#if FF_USE_FASTSEEK\n\t\t\t\t\tif (fp->cltbl) {\n\t\t\t\t\t\tclst = clmt_clust(fp, fp->fptr);\t/* Get cluster# from the CLMT */\n\t\t\t\t\t} else\n#endif\n\t\t\t\t\t{\n\t\t\t\t\t\tclst = get_fat(&fp->obj, fp->clust);\t/* Follow cluster chain on the FAT */\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (clst < 2) {\n\t\t\t\t\tEFSPRINTF(\"CCHK\");\n\t\t\t\t\tABORT(fs, FR_INT_ERR);\n\t\t\t\t}\n\t\t\t\tif (clst == 0xFFFFFFFF) {\n\t\t\t\t\tEFSPRINTF(\"DSKC\");\n\t\t\t\t\tABORT(fs, FR_DISK_ERR);\n\t\t\t\t}\n\t\t\t\tfp->clust = clst;\t\t\t\t/* Update current cluster */\n\t\t\t}\n\t\t\tsect = clst2sect(fs, fp->clust);\t/* Get current sector */\n\t\t\tif (sect == 0) ABORT(fs, FR_INT_ERR);\n\t\t\tsect += csect;\n\t\t\tcc = btr / SS(fs);\t\t\t\t\t/* When remaining bytes >= sector size, */\n\t\t\tif (cc > 0) {\t\t\t\t\t\t/* Read maximum contiguous sectors directly */\n\t\t\t\tif (csect + cc > fs->csize) {\t/* Clip at cluster boundary */\n\t\t\t\t\tcc = fs->csize - csect;\n\t\t\t\t}\n\t\t\t\tif (disk_read(fs->pdrv, rbuff, sect, cc) != RES_OK) {\n\t\t\t\t\tEFSPRINTF(\"RLIO\");\n\t\t\t\t\tABORT(fs, FR_DISK_ERR);\n\t\t\t\t}\n#if !FF_FS_READONLY && FF_FS_MINIMIZE <= 2\t\t/* Replace one of the read sectors with cached data if it contains a dirty sector */\n#if FF_FS_TINY\n\t\t\t\tif (fs->wflag && fs->winsect - sect < cc) {\n\t\t\t\t\tmem_cpy(rbuff + ((fs->winsect - sect) * SS(fs)), fs->win, SS(fs));\n\t\t\t\t}\n#else\n\t\t\t\tif ((fp->flag & FA_DIRTY) && fp->sect - sect < cc) {\n\t\t\t\t\tmem_cpy(rbuff + ((fp->sect - sect) * SS(fs)), fp->buf, SS(fs));\n\t\t\t\t}\n#endif\n#endif\n\t\t\t\trcnt = SS(fs) * cc;\t\t\t\t/* Number of bytes transferred */\n\t\t\t\tcontinue;\n\t\t\t}\n#if !FF_FS_TINY\n\t\t\tif (fp->sect != sect) {\t\t\t/* Load data sector if not in cache */\n#if !FF_FS_READONLY\n\t\t\t\tif (fp->flag & FA_DIRTY) {\t\t/* Write-back dirty sector cache */\n\t\t\t\t\tif (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) {\n\t\t\t\t\t\tEFSPRINTF(\"RDC\");\n\t\t\t\t\t\tABORT(fs, FR_DISK_ERR);\n\t\t\t\t\t}\n\t\t\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t\t\t}\n#endif\n\t\t\t\tif (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) {\n\t\t\t\t\tEFSPRINTF(\"RSC\");\n\t\t\t\t\tABORT(fs, FR_DISK_ERR);\t/* Fill sector cache */\n\t\t\t\t}\n\t\t\t}\n#endif\n\t\t\tfp->sect = sect;\n\t\t}\n\t\trcnt = SS(fs) - (UINT)fp->fptr % SS(fs);\t/* Number of bytes left in the sector */\n\t\tif (rcnt > btr) rcnt = btr;\t\t\t\t\t/* Clip it by btr if needed */\n#if FF_FS_TINY\n\t\tif (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR);\t/* Move sector window */\n\t\tmem_cpy(rbuff, fs->win + fp->fptr % SS(fs), rcnt);\t/* Extract partial sector */\n#else\n\t\tmem_cpy(rbuff, fp->buf + fp->fptr % SS(fs), rcnt);\t/* Extract partial sector */\n#endif\n\t}\n\n\tLEAVE_FF(fs, FR_OK);\n}\n\n\n\n\n#ifdef FF_FASTFS\n/*-----------------------------------------------------------------------*/\n/* Fast Read Aligned Sized File Without a Cache                         */\n/*-----------------------------------------------------------------------*/\n#if FF_USE_FASTSEEK\nFRESULT f_read_fast (\n\tFIL* fp,\t\t\t/* Pointer to the file object */\n\tconst void* buff,\t/* Pointer to the data to be written */\n\tUINT btr\t\t\t/* Number of bytes to read */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tUINT csize_bytes;\n\tDWORD clst;\n\tUINT count = 0;\n\tFSIZE_t work_sector = 0;\n\tFSIZE_t sector_base = 0;\n\tBYTE *wbuff = (BYTE*)buff;\n\n\t// TODO support sector reading inside a cluster\n\n\tres = validate(&fp->obj, &fs);\t\t\t/* Check validity of the file object */\n\tif (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {\n\t\tEFSPRINTF(\"FOV\");\n\t\tLEAVE_FF(fs, res);\t/* Check validity */\n\t}\n\n\tif (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */\n\tFSIZE_t remain = fp->obj.objsize - fp->fptr;\n\tif (btr > remain) btr = (UINT)remain;\t\t/* Truncate btr by remaining bytes */\n\n\tcsize_bytes = fs->csize * SS(fs);\n\n\tif (!fp->fptr) {\t/* On the top of the file? */\n\t\tclst = fp->obj.sclust;\t/* Follow from the origin */\n\t} else {\n\t\tif (fp->cltbl) clst = clmt_clust(fp, fp->fptr);\t/* Get cluster# from the CLMT */\n\t\telse { EFSPRINTF(\"CLTBL\"); ABORT(fs, FR_CLTBL_NO_INIT); }\n\t}\n\tif (clst < 2) { EFSPRINTF(\"CCHK\"); ABORT(fs, FR_INT_ERR); }\n\telse if (clst == 0xFFFFFFFF) { EFSPRINTF(\"DSKC\"); ABORT(fs, FR_DISK_ERR); }\n\n\tfp->clust = clst;\t/* Set working cluster */\n\t\n\tsector_base = clst2sect(fs, fp->clust);\n\tcount += fs->csize;\n\tbtr -= csize_bytes;\n\tfp->fptr += csize_bytes;\n\n\twhile (btr) {\n\t\tclst = clmt_clust(fp, fp->fptr);\t/* Get cluster# from the CLMT */\n\n\t\tif (clst < 2) { EFSPRINTF(\"CCHK2\"); ABORT(fs, FR_INT_ERR); }\n\t\telse if (clst == 0xFFFFFFFF) { EFSPRINTF(\"DSKC\"); ABORT(fs, FR_DISK_ERR); }\n\n\t\tfp->clust = clst;\n\n\t\twork_sector = clst2sect(fs, fp->clust);\n\t\tif ((work_sector - sector_base) == count) count += fs->csize;\n\t\telse {\n\t\t\tif (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t\twbuff += count * SS(fs);\n\n\t\t\tsector_base = work_sector;\n\t\t\tcount = fs->csize;\n\t\t}\n\n\t\tfp->fptr += MIN(btr, csize_bytes);\n\t\tbtr -= MIN(btr, csize_bytes);\n\n\t\t// TODO: what about if data is smaller than cluster?\n\t\t// Must read-write back that cluster.\n\n\t\tif (!btr) {\t/* Final cluster/sectors read. */\n\t\t\tif (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t}\n\t}\n\n\tLEAVE_FF(fs, FR_OK);\n}\n#endif\n#endif\n\n\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Write File                                                            */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_write (\n\tFIL* fp,\t\t\t/* Pointer to the file object */\n\tconst void* buff,\t/* Pointer to the data to be written */\n\tUINT btw,\t\t\t/* Number of bytes to write */\n\tUINT* bw\t\t\t/* Pointer to number of bytes written */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDWORD clst, sect;\n\tUINT wcnt, cc, csect;\n\tconst BYTE *wbuff = (const BYTE*)buff;\n\n\tUINT bw_tmp;\n\tif (!bw)\n\t\tbw = &bw_tmp;\n\t*bw = 0;\t/* Clear write byte counter */\n\tres = validate(&fp->obj, &fs);\t\t\t/* Check validity of the file object */\n\tif (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {\n\t\tEFSPRINTF(\"FOV\");\n\t\tLEAVE_FF(fs, res);\t/* Check validity */\n\t}\n\tif (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED);\t/* Check access mode */\n\n\t/* Check fptr wrap-around (file size cannot reach 4 GiB at FAT volume) */\n\tif ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) {\n\t\tbtw = (UINT)(0xFFFFFFFF - (DWORD)fp->fptr);\n\t}\n\n\tfor ( ;  btw;\t\t\t\t\t\t\t/* Repeat until all data written */\n\t\tbtw -= wcnt, *bw += wcnt, wbuff += wcnt, fp->fptr += wcnt, fp->obj.objsize = (fp->fptr > fp->obj.objsize) ? fp->fptr : fp->obj.objsize) {\n\t\tif (fp->fptr % SS(fs) == 0) {\t\t/* On the sector boundary? */\n\t\t\tcsect = (UINT)(fp->fptr / SS(fs)) & (fs->csize - 1);\t/* Sector offset in the cluster */\n\t\t\tif (csect == 0) {\t\t\t\t/* On the cluster boundary? */\n\t\t\t\tif (fp->fptr == 0) {\t\t/* On the top of the file? */\n\t\t\t\t\tclst = fp->obj.sclust;\t/* Follow from the origin */\n\t\t\t\t\tif (clst == 0) {\t\t/* If no cluster is allocated, */\n\t\t\t\t\t\tclst = create_chain(&fp->obj, 0);\t/* create a new cluster chain */\n\t\t\t\t\t}\n\t\t\t\t} else {\t\t\t\t\t/* On the middle or end of the file */\n#if FF_USE_FASTSEEK\n\t\t\t\t\tif (fp->cltbl) {\n\t\t\t\t\t\tclst = clmt_clust(fp, fp->fptr);\t/* Get cluster# from the CLMT */\n\t\t\t\t\t} else\n#endif\n\t\t\t\t\t{\n\t\t\t\t\t\tclst = create_chain(&fp->obj, fp->clust);\t/* Follow or stretch cluster chain on the FAT */\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (clst == 0) {\n\t\t\t\t\tEFSPRINTF(\"DSKFULL\");\n\t\t\t\t\tbreak;\t\t/* Could not allocate a new cluster (disk full) */\n\t\t\t\t}\n\t\t\t\tif (clst == 1) {\n\t\t\t\t\tEFSPRINTF(\"CCHK\");\n\t\t\t\t\tABORT(fs, FR_INT_ERR);\n\t\t\t\t}\n\t\t\t\tif (clst == 0xFFFFFFFF) {\n\t\t\t\t\tEFSPRINTF(\"DERR\");\n\t\t\t\t\tABORT(fs, FR_DISK_ERR);\n\t\t\t\t}\n\t\t\t\tfp->clust = clst;\t\t\t/* Update current cluster */\n\t\t\t\tif (fp->obj.sclust == 0) fp->obj.sclust = clst;\t/* Set start cluster if the first write */\n\t\t\t}\n#if FF_FS_TINY\n\t\t\tif (fs->winsect == fp->sect && sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR);\t/* Write-back sector cache */\n#else\n\t\t\tif (fp->flag & FA_DIRTY) {\t\t/* Write-back sector cache */\n\t\t\t\tif (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t\t}\n#endif\n\t\t\tsect = clst2sect(fs, fp->clust);\t/* Get current sector */\n\t\t\tif (sect == 0) ABORT(fs, FR_INT_ERR);\n\t\t\tsect += csect;\n\t\t\tcc = btw / SS(fs);\t\t\t\t/* When remaining bytes >= sector size, */\n\t\t\tif (cc > 0) {\t\t\t\t\t/* Write maximum contiguous sectors directly */\n\t\t\t\tif (csect + cc > fs->csize) {\t/* Clip at cluster boundary */\n\t\t\t\t\tcc = fs->csize - csect;\n\t\t\t\t}\n\t\t\t\tif (disk_write(fs->pdrv, wbuff, sect, cc) != RES_OK) {\n\t\t\t\t\tEFSPRINTF(\"WLIO\");\n\t\t\t\t\tABORT(fs, FR_DISK_ERR);\n\t\t\t\t}\n#if FF_FS_MINIMIZE <= 2\n#if FF_FS_TINY\n\t\t\t\tif (fs->winsect - sect < cc) {\t/* Refill sector cache if it gets invalidated by the direct write */\n\t\t\t\t\tmem_cpy(fs->win, wbuff + ((fs->winsect - sect) * SS(fs)), SS(fs));\n\t\t\t\t\tfs->wflag = 0;\n\t\t\t\t}\n#else\n\t\t\t\tif (fp->sect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */\n\t\t\t\t\tmem_cpy(fp->buf, wbuff + ((fp->sect - sect) * SS(fs)), SS(fs));\n\t\t\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t\t\t}\n#endif\n#endif\n\t\t\t\twcnt = SS(fs) * cc;\t\t/* Number of bytes transferred */\n\t\t\t\tcontinue;\n\t\t\t}\n#if FF_FS_TINY\n\t\t\tif (fp->fptr >= fp->obj.objsize) {\t/* Avoid silly cache filling on the growing edge */\n\t\t\t\tif (sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR);\n\t\t\t\tfs->winsect = sect;\n\t\t\t}\n#else\n\t\t\tif (fp->sect != sect && \t\t/* Fill sector cache with file data */\n\t\t\t\tfp->fptr < fp->obj.objsize &&\n\t\t\t\tdisk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) {\n\t\t\t\t\tABORT(fs, FR_DISK_ERR);\n\t\t\t}\n#endif\n\t\t\tfp->sect = sect;\n\t\t}\n\t\twcnt = SS(fs) - (UINT)fp->fptr % SS(fs);\t/* Number of bytes left in the sector */\n\t\tif (wcnt > btw) wcnt = btw;\t\t\t\t\t/* Clip it by btw if needed */\n#if FF_FS_TINY\n\t\tif (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR);\t/* Move sector window */\n\t\tmem_cpy(fs->win + fp->fptr % SS(fs), wbuff, wcnt);\t/* Fit data to the sector */\n\t\tfs->wflag = 1;\n#else\n\t\tmem_cpy(fp->buf + fp->fptr % SS(fs), wbuff, wcnt);\t/* Fit data to the sector */\n\t\tfp->flag |= FA_DIRTY;\n#endif\n\t}\n\n\tfp->flag |= FA_MODIFIED;\t\t\t\t/* Set file change flag */\n\n\tLEAVE_FF(fs, FR_OK);\n}\n\n\n\n\n#ifdef FF_FASTFS\n/*-----------------------------------------------------------------------*/\n/* Fast Write Aligned Sized File Without a Cache                         */\n/*-----------------------------------------------------------------------*/\n#if FF_USE_FASTSEEK\nFRESULT f_write_fast (\n\tFIL* fp,\t\t\t/* Pointer to the file object */\n\tconst void* buff,\t/* Pointer to the data to be written */\n\tUINT btw\t\t\t/* Number of bytes to write */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tUINT csize_bytes;\n\tDWORD clst;\n\tUINT count = 0;\n\tFSIZE_t work_sector = 0;\n\tFSIZE_t sector_base = 0;\n\tconst BYTE *wbuff = (const BYTE*)buff;\n\n\t// TODO support sector writing inside a cluster\n\n\tres = validate(&fp->obj, &fs);\t\t\t/* Check validity of the file object */\n\tif (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {\n\t\tEFSPRINTF(\"FOV\");\n\t\tLEAVE_FF(fs, res);\t/* Check validity */\n\t}\n\n\tif (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED);\t/* Check access mode */\n\t/* Check fptr wrap-around (file size cannot reach 4 GiB at FAT volume) */\n\tif ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) {\n\t\tbtw = (UINT)(0xFFFFFFFF - (DWORD)fp->fptr);\n\t}\n\n\tcsize_bytes = fs->csize * SS(fs);\n\n\tif (!fp->fptr) {\t/* On the top of the file? */\n\t\tclst = fp->obj.sclust;\t/* Follow from the origin */\n\t} else {\n\t\tif (fp->cltbl) clst = clmt_clust(fp, fp->fptr);\t/* Get cluster# from the CLMT */\n\t\telse { EFSPRINTF(\"CLTBL\"); ABORT(fs, FR_CLTBL_NO_INIT); }\n\t}\n\n\tif (clst < 2) { EFSPRINTF(\"CCHK\"); ABORT(fs, FR_INT_ERR); }\n\telse if (clst == 0xFFFFFFFF) { EFSPRINTF(\"DERR\"); ABORT(fs, FR_DISK_ERR); }\n\n\tfp->clust = clst;\t/* Set working cluster */\n\t\n\tsector_base = clst2sect(fs, fp->clust);\n\tcount += fs->csize;\n\tbtw -= csize_bytes;\n\tfp->fptr += csize_bytes;\n\n\twhile (btw) {\n\t\tclst = clmt_clust(fp, fp->fptr);\t/* Get cluster# from the CLMT */\n\n\t\tif (clst < 2) { EFSPRINTF(\"CCHK2\"); ABORT(fs, FR_INT_ERR); }\n\t\telse if (clst == 0xFFFFFFFF) { EFSPRINTF(\"DERR\"); ABORT(fs, FR_DISK_ERR); }\n\n\t\tfp->clust = clst;\n\n\t\twork_sector = clst2sect(fs, fp->clust);\n\t\tif ((work_sector - sector_base) == count) count += fs->csize;\n\t\telse {\n\t\t\tif (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t\twbuff += count * SS(fs);\n\n\t\t\tsector_base = work_sector;\n\t\t\tcount = fs->csize;\n\t\t}\n\n\t\tfp->fptr += MIN(btw, csize_bytes);\n\t\tbtw -= MIN(btw, csize_bytes);\n\n\t\t// what about if data is smaller than cluster?\n\t\t// Probably must read-write back that cluster.\n\t\tif (!btw) {\t/* Final cluster/sectors write. */\n\t\t\tif (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t}\n\t}\n\n\tfp->flag |= FA_MODIFIED;\t/* Set file change flag */\n\n\tLEAVE_FF(fs, FR_OK);\n}\n#endif\n#endif\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Synchronize the File                                                  */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_sync (\n\tFIL* fp\t\t/* Pointer to the file object */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDWORD tm;\n\tBYTE *dir;\n\n\n\tres = validate(&fp->obj, &fs);\t/* Check validity of the file object */\n\tif (res == FR_OK) {\n\t\tif (fp->flag & FA_MODIFIED) {\t/* Is there any change to the file? */\n#if !FF_FS_TINY\n\t\t\tif (fp->flag & FA_DIRTY) {\t/* Write-back cached data if needed */\n\t\t\t\tif (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) LEAVE_FF(fs, FR_DISK_ERR);\n\t\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t\t}\n#endif\n\t\t\t/* Update the directory entry */\n\t\t\ttm = GET_FATTIME();\t\t\t\t/* Modified time */\n#if FF_FS_EXFAT\n\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\tres = fill_first_frag(&fp->obj);\t/* Fill first fragment on the FAT if needed */\n\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\tres = fill_last_frag(&fp->obj, fp->clust, 0xFFFFFFFF);\t/* Fill last fragment on the FAT if needed */\n\t\t\t\t}\n\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\tDIR dj;\n\t\t\t\t\tDEF_NAMBUF\n\n\t\t\t\t\tINIT_NAMBUF(fs);\n\t\t\t\t\tres = load_obj_xdir(&dj, &fp->obj);\t/* Load directory entry block */\n\t\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\t\tfs->dirbuf[XDIR_Attr] |= AM_ARC;\t\t\t\t/* Set archive attribute to indicate that the file has been changed */\n\t\t\t\t\t\tfs->dirbuf[XDIR_GenFlags] = fp->obj.stat | 1;\t/* Update file allocation information */\n\t\t\t\t\t\tst_dword(fs->dirbuf + XDIR_FstClus, fp->obj.sclust);\n\t\t\t\t\t\tst_qword(fs->dirbuf + XDIR_FileSize, fp->obj.objsize);\n\t\t\t\t\t\tst_qword(fs->dirbuf + XDIR_ValidFileSize, fp->obj.objsize);\n\t\t\t\t\t\tst_dword(fs->dirbuf + XDIR_ModTime, tm);\t\t/* Update modified time */\n\t\t\t\t\t\tfs->dirbuf[XDIR_ModTime10] = 0;\n\t\t\t\t\t\tst_dword(fs->dirbuf + XDIR_AccTime, 0);\n\t\t\t\t\t\tres = store_xdir(&dj);\t/* Restore it to the directory */\n\t\t\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\t\t\tres = sync_fs(fs);\n\t\t\t\t\t\t\tfp->flag &= (BYTE)~FA_MODIFIED;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tFREE_NAMBUF();\n\t\t\t\t}\n\t\t\t} else\n#endif\n\t\t\t{\n\t\t\t\tres = move_window(fs, fp->dir_sect);\n\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\tdir = fp->dir_ptr;\n\t\t\t\t\tdir[DIR_Attr] |= AM_ARC;\t\t\t\t\t\t/* Set archive attribute to indicate that the file has been changed */\n\t\t\t\t\tst_clust(fp->obj.fs, dir, fp->obj.sclust);\t\t/* Update file allocation information  */\n\t\t\t\t\tst_dword(dir + DIR_FileSize, (DWORD)fp->obj.objsize);\t/* Update file size */\n\t\t\t\t\tst_dword(dir + DIR_ModTime, tm);\t\t\t\t/* Update modified time */\n\t\t\t\t\tst_word(dir + DIR_LstAccDate, 0);\n\t\t\t\t\tfs->wflag = 1;\n\t\t\t\t\tres = sync_fs(fs);\t\t\t\t\t/* Restore it to the directory */\n\t\t\t\t\tfp->flag &= (BYTE)~FA_MODIFIED;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n#endif /* !FF_FS_READONLY */\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Close File                                                            */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_close (\n\tFIL* fp\t\t/* Pointer to the file object to be closed */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\n#if !FF_FS_READONLY\n\tres = f_sync(fp);\t\t\t\t\t/* Flush cached data */\n\tif (res == FR_OK)\n#endif\n\t{\n\t\tres = validate(&fp->obj, &fs);\t/* Lock volume */\n\t\tif (res == FR_OK) {\n#if FF_FS_LOCK != 0\n\t\t\tres = dec_lock(fp->obj.lockid);\t\t/* Decrement file open counter */\n\t\t\tif (res == FR_OK) fp->obj.fs = 0;\t/* Invalidate file object */\n#else\n\t\t\tfp->obj.fs = 0;\t/* Invalidate file object */\n#endif\n#if FF_FS_REENTRANT\n\t\t\tunlock_fs(fs, FR_OK);\t\t/* Unlock volume */\n#endif\n\t\t}\n\t}\n\treturn res;\n}\n\n\n\n\n#if FF_FS_RPATH >= 1\n/*-----------------------------------------------------------------------*/\n/* Change Current Directory or Current Drive, Get Current Directory      */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_chdrive (\n\tconst TCHAR* path\t\t/* Drive number to set */\n)\n{\n\tint vol;\n\n\n\t/* Get logical drive number */\n\tvol = get_ldnumber(&path);\n\tif (vol < 0) return FR_INVALID_DRIVE;\n\tCurrVol = (BYTE)vol;\t/* Set it as current volume */\n\n\treturn FR_OK;\n}\n\n\n\nFRESULT f_chdir (\n\tconst TCHAR* path\t/* Pointer to the directory path */\n)\n{\n#if FF_STR_VOLUME_ID == 2\n\tUINT i;\n#endif\n\tFRESULT res;\n\tDIR dj;\n\tFATFS *fs;\n\tDEF_NAMBUF\n\n\n\t/* Get logical drive */\n\tres = find_volume(&path, &fs, 0);\n\tif (res == FR_OK) {\n\t\tdj.obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\t\tres = follow_path(&dj, path);\t\t/* Follow the path */\n\t\tif (res == FR_OK) {\t\t\t\t\t/* Follow completed */\n\t\t\tif (dj.fn[NSFLAG] & NS_NONAME) {\t/* Is it the start directory itself? */\n\t\t\t\tfs->cdir = dj.obj.sclust;\n#if FF_FS_EXFAT\n\t\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\t\tfs->cdc_scl = dj.obj.c_scl;\n\t\t\t\t\tfs->cdc_size = dj.obj.c_size;\n\t\t\t\t\tfs->cdc_ofs = dj.obj.c_ofs;\n\t\t\t\t}\n#endif\n\t\t\t} else {\n\t\t\t\tif (dj.obj.attr & AM_DIR) {\t/* It is a sub-directory */\n#if FF_FS_EXFAT\n\t\t\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\t\t\tfs->cdir = ld_dword(fs->dirbuf + XDIR_FstClus);\t\t/* Sub-directory cluster */\n\t\t\t\t\t\tfs->cdc_scl = dj.obj.sclust;\t\t\t\t\t\t/* Save containing directory information */\n\t\t\t\t\t\tfs->cdc_size = ((DWORD)dj.obj.objsize & 0xFFFFFF00) | dj.obj.stat;\n\t\t\t\t\t\tfs->cdc_ofs = dj.blk_ofs;\n\t\t\t\t\t} else\n#endif\n\t\t\t\t\t{\n\t\t\t\t\t\tfs->cdir = ld_clust(fs, dj.dir);\t\t\t\t\t/* Sub-directory cluster */\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tres = FR_NO_PATH;\t\t/* Reached but a file */\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tFREE_NAMBUF();\n\t\tif (res == FR_NO_FILE) res = FR_NO_PATH;\n#if FF_STR_VOLUME_ID == 2\t/* Also current drive is changed at Unix style volume ID */\n\t\tif (res == FR_OK) {\n\t\t\tfor (i = FF_VOLUMES - 1; i && fs != FatFs[i]; i--) ;\t/* Set current drive */\n\t\t\tCurrVol = (BYTE)i;\n\t\t}\n#endif\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n\n#if FF_FS_RPATH >= 2\nFRESULT f_getcwd (\n\tTCHAR* buff,\t/* Pointer to the directory path */\n\tUINT len\t\t/* Size of buff in unit of TCHAR */\n)\n{\n\tFRESULT res;\n\tDIR dj;\n\tFATFS *fs;\n\tUINT i, n;\n\tDWORD ccl;\n\tTCHAR *tp = buff;\n#if FF_VOLUMES >= 2\n\tUINT vl;\n#endif\n#if FF_STR_VOLUME_ID\n\tconst char *vp;\n#endif\n\tFILINFO fno;\n\tDEF_NAMBUF\n\n\n\t/* Get logical drive */\n\tbuff[0] = 0;\t/* Set null string to get current volume */\n\tres = find_volume((const TCHAR**)&buff, &fs, 0);\t/* Get current volume */\n\tif (res == FR_OK) {\n\t\tdj.obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\n\t\t/* Follow parent directories and create the path */\n\t\ti = len;\t\t\t/* Bottom of buffer (directory stack base) */\n\t\tif (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) {\t/* (Cannot do getcwd on exFAT and returns root path) */\n\t\t\tdj.obj.sclust = fs->cdir;\t\t\t\t/* Start to follow upper directory from current directory */\n\t\t\twhile ((ccl = dj.obj.sclust) != 0) {\t/* Repeat while current directory is a sub-directory */\n\t\t\t\tres = dir_sdi(&dj, 1 * SZDIRE);\t/* Get parent directory */\n\t\t\t\tif (res != FR_OK) break;\n\t\t\t\tres = move_window(fs, dj.sect);\n\t\t\t\tif (res != FR_OK) break;\n\t\t\t\tdj.obj.sclust = ld_clust(fs, dj.dir);\t/* Goto parent directory */\n\t\t\t\tres = dir_sdi(&dj, 0);\n\t\t\t\tif (res != FR_OK) break;\n\t\t\t\tdo {\t\t\t\t\t\t\t/* Find the entry links to the child directory */\n\t\t\t\t\tres = DIR_READ_FILE(&dj);\n\t\t\t\t\tif (res != FR_OK) break;\n\t\t\t\t\tif (ccl == ld_clust(fs, dj.dir)) break;\t/* Found the entry */\n\t\t\t\t\tres = dir_next(&dj, 0);\n\t\t\t\t} while (res == FR_OK);\n\t\t\t\tif (res == FR_NO_FILE) res = FR_INT_ERR;/* It cannot be 'not found'. */\n\t\t\t\tif (res != FR_OK) break;\n\t\t\t\tget_fileinfo(&dj, &fno);\t\t/* Get the directory name and push it to the buffer */\n\t\t\t\tfor (n = 0; fno.fname[n]; n++) ;\t/* Name length */\n\t\t\t\tif (i < n + 1) {\t/* Insufficient space to store the path name? */\n\t\t\t\t\tres = FR_NOT_ENOUGH_CORE; break;\n\t\t\t\t}\n\t\t\t\twhile (n) buff[--i] = fno.fname[--n];\t/* Stack the name */\n\t\t\t\tbuff[--i] = '/';\n\t\t\t}\n\t\t}\n\t\tif (res == FR_OK) {\n\t\t\tif (i == len) buff[--i] = '/';\t/* Is it the root-directory? */\n#if FF_VOLUMES >= 2\t\t\t/* Put drive prefix */\n\t\t\tvl = 0;\n#if FF_STR_VOLUME_ID >= 1\t/* String volume ID */\n\t\t\tfor (n = 0, vp = (const char*)VolumeStr[CurrVol]; vp[n]; n++) ;\n\t\t\tif (i >= n + 2) {\n\t\t\t\tif (FF_STR_VOLUME_ID == 2) *tp++ = (TCHAR)'/';\n\t\t\t\tfor (vl = 0; vl < n; *tp++ = (TCHAR)vp[vl], vl++) ;\n\t\t\t\tif (FF_STR_VOLUME_ID == 1) *tp++ = (TCHAR)':';\n\t\t\t\tvl++;\n\t\t\t}\n#else\t\t\t\t\t\t/* Numeric volume ID */\n\t\t\tif (i >= 3) {\n\t\t\t\t*tp++ = (TCHAR)'0' + CurrVol;\n\t\t\t\t*tp++ = (TCHAR)':';\n\t\t\t\tvl = 2;\n\t\t\t}\n#endif\n\t\t\tif (vl == 0) res = FR_NOT_ENOUGH_CORE;\n#endif\n\t\t\t/* Add current directory path */\n\t\t\tif (res == FR_OK) {\n\t\t\t\tdo *tp++ = buff[i++]; while (i < len);\t/* Copy stacked path string */\n\t\t\t}\n\t\t}\n\t\tFREE_NAMBUF();\n\t}\n\n\t*tp = 0;\n\tLEAVE_FF(fs, res);\n}\n\n#endif /* FF_FS_RPATH >= 2 */\n#endif /* FF_FS_RPATH >= 1 */\n\n\n\n#if FF_FS_MINIMIZE <= 2\n/*-----------------------------------------------------------------------*/\n/* Seek File Read/Write Pointer                                          */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_lseek (\n\tFIL* fp,\t\t/* Pointer to the file object */\n\tFSIZE_t ofs\t\t/* File pointer from top of file */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDWORD clst, bcs, nsect;\n\tFSIZE_t ifptr;\n#if FF_USE_FASTSEEK\n\tDWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl;\n#endif\n\n\tres = validate(&fp->obj, &fs);\t\t/* Check validity of the file object */\n\tif (res == FR_OK) res = (FRESULT)fp->err;\n#if FF_FS_EXFAT && !FF_FS_READONLY\n\tif (res == FR_OK && fs->fs_type == FS_EXFAT) {\n\t\tres = fill_last_frag(&fp->obj, fp->clust, 0xFFFFFFFF);\t/* Fill last fragment on the FAT if needed */\n\t}\n#endif\n\tif (res != FR_OK) LEAVE_FF(fs, res);\n\n#if FF_USE_FASTSEEK\n\tif (fp->cltbl) {\t/* Fast seek */\n\t\tif (ofs == CREATE_LINKMAP) {\t/* Create CLMT */\n\t\t\ttbl = fp->cltbl;\n\t\t\ttlen = *tbl++; ulen = 2;\t/* Given table size and required table size */\n\t\t\tcl = fp->obj.sclust;\t\t/* Origin of the chain */\n\t\t\tif (cl != 0) {\n\t\t\t\tdo {\n\t\t\t\t\t/* Get a fragment */\n\t\t\t\t\ttcl = cl; ncl = 0; ulen += 2;\t/* Top, length and used items */\n\t\t\t\t\tdo {\n\t\t\t\t\t\tpcl = cl; ncl++;\n\t\t\t\t\t\tcl = get_fat(&fp->obj, cl);\n\t\t\t\t\t\tif (cl <= 1) ABORT(fs, FR_INT_ERR);\n\t\t\t\t\t\tif (cl == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);\n\t\t\t\t\t} while (cl == pcl + 1);\n\t\t\t\t\tif (ulen <= tlen) {\t\t/* Store the length and top of the fragment */\n\t\t\t\t\t\t*tbl++ = ncl; *tbl++ = tcl;\n\t\t\t\t\t}\n\t\t\t\t} while (cl < fs->n_fatent);\t/* Repeat until end of chain */\n\t\t\t}\n\t\t\t*fp->cltbl = ulen;\t/* Number of items used */\n\t\t\tif (ulen <= tlen) {\n\t\t\t\t*tbl = 0;\t\t/* Terminate table */\n\t\t\t} else {\n\t\t\t\tres = FR_NOT_ENOUGH_CORE;\t/* Given table size is smaller than required */\n\t\t\t}\n\t\t} else {\t\t\t\t\t\t/* Fast seek */\n\t\t\tif (ofs > fp->obj.objsize) ofs = fp->obj.objsize;\t/* Clip offset at the file size */\n\t\t\tfp->fptr = ofs;\t\t\t\t/* Set file pointer */\n\t\t\tif (ofs > 0) {\n\t\t\t\tfp->clust = clmt_clust(fp, ofs - 1);\n\t\t\t\tdsc = clst2sect(fs, fp->clust);\n\t\t\t\tif (dsc == 0) ABORT(fs, FR_INT_ERR);\n\t\t\t\tdsc += (DWORD)((ofs - 1) / SS(fs)) & (fs->csize - 1);\n\t\t\t\tif (fp->fptr % SS(fs) && dsc != fp->sect) {\t/* Refill sector cache if needed */\n#if !FF_FS_TINY\n#if !FF_FS_READONLY\n\t\t\t\t\tif (fp->flag & FA_DIRTY) {\t\t/* Write-back dirty sector cache */\n\t\t\t\t\t\tif (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t\t\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t\t\t\t}\n#endif\n\t\t\t\t\tif (disk_read(fs->pdrv, fp->buf, dsc, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);\t/* Load current sector */\n#endif\n\t\t\t\t\tfp->sect = dsc;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else\n#endif\n\n\t/* Normal Seek */\n\t{\n#if FF_FS_EXFAT\n\t\tif (fs->fs_type != FS_EXFAT && ofs >= 0x100000000) ofs = 0xFFFFFFFF;\t/* Clip at 4 GiB - 1 if at FATxx */\n#endif\n\t\tif (ofs > fp->obj.objsize && (FF_FS_READONLY || !(fp->flag & FA_WRITE))) {\t/* In read-only mode, clip offset with the file size */\n\t\t\tofs = fp->obj.objsize;\n\t\t}\n\t\tifptr = fp->fptr;\n\t\tfp->fptr = nsect = 0;\n\t\tif (ofs > 0) {\n\t\t\tbcs = (DWORD)fs->csize * SS(fs);\t/* Cluster size (byte) */\n\t\t\tif (ifptr > 0 &&\n\t\t\t\t(ofs - 1) / bcs >= (ifptr - 1) / bcs) {\t/* When seek to same or following cluster, */\n\t\t\t\tfp->fptr = (ifptr - 1) & ~(FSIZE_t)(bcs - 1);\t/* start from the current cluster */\n\t\t\t\tofs -= fp->fptr;\n\t\t\t\tclst = fp->clust;\n\t\t\t} else {\t\t\t\t\t\t\t\t\t/* When seek to back cluster, */\n\t\t\t\tclst = fp->obj.sclust;\t\t\t\t\t/* start from the first cluster */\n#if !FF_FS_READONLY\n\t\t\t\tif (clst == 0) {\t\t\t\t\t\t/* If no cluster chain, create a new chain */\n\t\t\t\t\tclst = create_chain(&fp->obj, 0);\n\t\t\t\t\tif (clst == 1) ABORT(fs, FR_INT_ERR);\n\t\t\t\t\tif (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);\n\t\t\t\t\tfp->obj.sclust = clst;\n\t\t\t\t}\n#endif\n\t\t\t\tfp->clust = clst;\n\t\t\t}\n\t\t\tif (clst != 0) {\n\t\t\t\twhile (ofs > bcs) {\t\t\t\t\t\t/* Cluster following loop */\n\t\t\t\t\tofs -= bcs; fp->fptr += bcs;\n#if !FF_FS_READONLY\n\t\t\t\t\tif (fp->flag & FA_WRITE) {\t\t\t/* Check if in write mode or not */\n\t\t\t\t\t\tif (FF_FS_EXFAT && fp->fptr > fp->obj.objsize) {\t/* No FAT chain object needs correct objsize to generate FAT value */\n\t\t\t\t\t\t\tfp->obj.objsize = fp->fptr;\n\t\t\t\t\t\t\tfp->flag |= FA_MODIFIED;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tclst = create_chain(&fp->obj, clst);\t/* Follow chain with forceed stretch */\n\t\t\t\t\t\tif (clst == 0) {\t\t\t\t/* Clip file size in case of disk full */\n\t\t\t\t\t\t\tofs = 0; break;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else\n#endif\n\t\t\t\t\t{\n\t\t\t\t\t\tclst = get_fat(&fp->obj, clst);\t/* Follow cluster chain if not in write mode */\n\t\t\t\t\t}\n\t\t\t\t\tif (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);\n\t\t\t\t\tif (clst <= 1 || clst >= fs->n_fatent) ABORT(fs, FR_INT_ERR);\n\t\t\t\t\tfp->clust = clst;\n\t\t\t\t}\n\t\t\t\tfp->fptr += ofs;\n\t\t\t\tif (ofs % SS(fs)) {\n\t\t\t\t\tnsect = clst2sect(fs, clst);\t/* Current sector */\n\t\t\t\t\tif (nsect == 0) ABORT(fs, FR_INT_ERR);\n\t\t\t\t\tnsect += (DWORD)(ofs / SS(fs));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!FF_FS_READONLY && fp->fptr > fp->obj.objsize) {\t/* Set file change flag if the file size is extended */\n\t\t\tfp->obj.objsize = fp->fptr;\n\t\t\tfp->flag |= FA_MODIFIED;\n\t\t}\n\t\tif (fp->fptr % SS(fs) && nsect != fp->sect) {\t/* Fill sector cache if needed */\n#if !FF_FS_TINY\n#if !FF_FS_READONLY\n\t\t\tif (fp->flag & FA_DIRTY) {\t\t\t/* Write-back dirty sector cache */\n\t\t\t\tif (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t\t}\n#endif\n\t\t\tif (disk_read(fs->pdrv, fp->buf, nsect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);\t/* Fill sector cache */\n#endif\n\t\t\tfp->sect = nsect;\n\t\t}\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n#ifdef FF_FASTFS\n#if FF_USE_FASTSEEK\n/*-----------------------------------------------------------------------*/\n/* Seek File Read/Write Pointer                                          */\n/*-----------------------------------------------------------------------*/\n\nDWORD *f_expand_cltbl (\n\tFIL* fp,\t\t/* Pointer to the file object */\n\tUINT tblsz,\t\t/* Size of table */\n\tFSIZE_t ofs\t\t/* File pointer from top of file */\n)\n{\n\tif (fp->flag & FA_WRITE) f_lseek(fp, ofs);\t/* Expand file if write is enabled */\n\tif (!fp->cltbl) {\t/* Allocate memory for cluster link table */\n\t\tfp->cltbl = (DWORD *)ff_memalloc(tblsz);\n\t\tfp->cltbl[0] = tblsz;\n\t}\n\tif (f_lseek(fp, CREATE_LINKMAP)) {\t/* Create cluster link table */\n\t\tff_memfree(fp->cltbl);\n\t\tfp->cltbl = NULL;\n\t\tEFSPRINTF(\"CLTBLSZ\");\n\t\treturn NULL;\n\t}\n\tf_lseek(fp, 0);\n\n\treturn fp->cltbl;\n}\n#endif\n#endif\n\n\n\n\n#if FF_FS_MINIMIZE <= 1\n/*-----------------------------------------------------------------------*/\n/* Create a Directory Object                                             */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_opendir (\n\tDIR* dp,\t\t\t/* Pointer to directory object to create */\n\tconst TCHAR* path\t/* Pointer to the directory path */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDEF_NAMBUF\n\n\n\tif (!dp) return FR_INVALID_OBJECT;\n\n\t/* Get logical drive */\n\tres = find_volume(&path, &fs, 0);\n\tif (res == FR_OK) {\n\t\tdp->obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\t\tres = follow_path(dp, path);\t\t\t/* Follow the path to the directory */\n\t\tif (res == FR_OK) {\t\t\t\t\t\t/* Follow completed */\n\t\t\tif (!(dp->fn[NSFLAG] & NS_NONAME)) {\t/* It is not the origin directory itself */\n\t\t\t\tif (dp->obj.attr & AM_DIR) {\t\t/* This object is a sub-directory */\n#if FF_FS_EXFAT\n\t\t\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\t\t\tdp->obj.c_scl = dp->obj.sclust;\t\t\t\t\t\t\t/* Get containing directory inforamation */\n\t\t\t\t\t\tdp->obj.c_size = ((DWORD)dp->obj.objsize & 0xFFFFFF00) | dp->obj.stat;\n\t\t\t\t\t\tdp->obj.c_ofs = dp->blk_ofs;\n\t\t\t\t\t\tinit_alloc_info(fs, &dp->obj);\t/* Get object allocation info */\n\t\t\t\t\t} else\n#endif\n\t\t\t\t\t{\n\t\t\t\t\t\tdp->obj.sclust = ld_clust(fs, dp->dir);\t/* Get object allocation info */\n\t\t\t\t\t}\n\t\t\t\t} else {\t\t\t\t\t\t/* This object is a file */\n\t\t\t\t\tres = FR_NO_PATH;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (res == FR_OK) {\n\t\t\t\tdp->obj.id = fs->id;\n\t\t\t\tres = dir_sdi(dp, 0);\t\t\t/* Rewind directory */\n#if FF_FS_LOCK != 0\n\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\tif (dp->obj.sclust != 0) {\n\t\t\t\t\t\tdp->obj.lockid = inc_lock(dp, 0);\t/* Lock the sub directory */\n\t\t\t\t\t\tif (!dp->obj.lockid) res = FR_TOO_MANY_OPEN_FILES;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdp->obj.lockid = 0;\t/* Root directory need not to be locked */\n\t\t\t\t\t}\n\t\t\t\t}\n#endif\n\t\t\t}\n\t\t}\n\t\tFREE_NAMBUF();\n\t\tif (res == FR_NO_FILE) res = FR_NO_PATH;\n\t}\n\tif (res != FR_OK) dp->obj.fs = 0;\t\t/* Invalidate the directory object if function faild */\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Close Directory                                                       */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_closedir (\n\tDIR *dp\t\t/* Pointer to the directory object to be closed */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\n\n\tres = validate(&dp->obj, &fs);\t/* Check validity of the file object */\n\tif (res == FR_OK) {\n#if FF_FS_LOCK != 0\n\t\tif (dp->obj.lockid) res = dec_lock(dp->obj.lockid);\t/* Decrement sub-directory open counter */\n\t\tif (res == FR_OK) dp->obj.fs = 0;\t/* Invalidate directory object */\n#else\n\t\tdp->obj.fs = 0;\t/* Invalidate directory object */\n#endif\n#if FF_FS_REENTRANT\n\t\tunlock_fs(fs, FR_OK);\t\t/* Unlock volume */\n#endif\n\t}\n\treturn res;\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Read Directory Entries in Sequence                                    */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_readdir (\n\tDIR* dp,\t\t\t/* Pointer to the open directory object */\n\tFILINFO* fno\t\t/* Pointer to file information to return */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDEF_NAMBUF\n\n\n\tres = validate(&dp->obj, &fs);\t/* Check validity of the directory object */\n\tif (res == FR_OK) {\n\t\tif (!fno) {\n\t\t\tres = dir_sdi(dp, 0);\t\t\t/* Rewind the directory object */\n\t\t} else {\n\t\t\tINIT_NAMBUF(fs);\n\t\t\tres = DIR_READ_FILE(dp);\t\t/* Read an item */\n\t\t\tif (res == FR_NO_FILE) res = FR_OK;\t/* Ignore end of directory */\n\t\t\tif (res == FR_OK) {\t\t\t\t/* A valid entry is found */\n\t\t\t\tget_fileinfo(dp, fno);\t\t/* Get the object information */\n\t\t\t\tres = dir_next(dp, 0);\t\t/* Increment index for next */\n\t\t\t\tif (res == FR_NO_FILE) res = FR_OK;\t/* Ignore end of directory now */\n\t\t\t}\n\t\t\tFREE_NAMBUF();\n\t\t}\n\t}\n\tLEAVE_FF(fs, res);\n}\n\n\n\n#if FF_USE_FIND\n/*-----------------------------------------------------------------------*/\n/* Find Next File                                                        */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_findnext (\n\tDIR* dp,\t\t/* Pointer to the open directory object */\n\tFILINFO* fno\t/* Pointer to the file information structure */\n)\n{\n\tFRESULT res;\n\n\n\tfor (;;) {\n\t\tres = f_readdir(dp, fno);\t\t/* Get a directory item */\n\t\tif (res != FR_OK || !fno || !fno->fname[0]) break;\t/* Terminate if any error or end of directory */\n\t\tif (pattern_matching(dp->pat, fno->fname, 0, 0)) break;\t\t/* Test for the file name */\n#if FF_USE_LFN && FF_USE_FIND == 2\n\t\tif (pattern_matching(dp->pat, fno->altname, 0, 0)) break;\t/* Test for alternative name if exist */\n#endif\n\t}\n\treturn res;\n}\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Find First File                                                       */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_findfirst (\n\tDIR* dp,\t\t\t\t/* Pointer to the blank directory object */\n\tFILINFO* fno,\t\t\t/* Pointer to the file information structure */\n\tconst TCHAR* path,\t\t/* Pointer to the directory to open */\n\tconst TCHAR* pattern\t/* Pointer to the matching pattern */\n)\n{\n\tFRESULT res;\n\n\n\tdp->pat = pattern;\t\t/* Save pointer to pattern string */\n\tres = f_opendir(dp, path);\t\t/* Open the target directory */\n\tif (res == FR_OK) {\n\t\tres = f_findnext(dp, fno);\t/* Find the first item */\n\t}\n\treturn res;\n}\n\n#endif\t/* FF_USE_FIND */\n\n\n\n#if FF_FS_MINIMIZE == 0\n/*-----------------------------------------------------------------------*/\n/* Get File Status                                                       */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_stat (\n\tconst TCHAR* path,\t/* Pointer to the file path */\n\tFILINFO* fno\t\t/* Pointer to file information to return */\n)\n{\n\tFRESULT res;\n\tDIR dj;\n\tDEF_NAMBUF\n\n\n\t/* Get logical drive */\n\tres = find_volume(&path, &dj.obj.fs, 0);\n\tif (res == FR_OK) {\n\t\tINIT_NAMBUF(dj.obj.fs);\n\t\tres = follow_path(&dj, path);\t/* Follow the file path */\n\t\tif (res == FR_OK) {\t\t\t\t/* Follow completed */\n\t\t\tif (dj.fn[NSFLAG] & NS_NONAME) {\t/* It is origin directory */\n\t\t\t\tres = FR_INVALID_NAME;\n\t\t\t} else {\t\t\t\t\t\t\t/* Found an object */\n\t\t\t\tif (fno) get_fileinfo(&dj, fno);\n\t\t\t}\n\t\t}\n\t\tFREE_NAMBUF();\n\t}\n\n\tLEAVE_FF(dj.obj.fs, res);\n}\n\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Get Number of Free Clusters                                           */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_getfree (\n\tconst TCHAR* path,\t/* Logical drive number */\n\tDWORD* nclst,\t\t/* Pointer to a variable to return number of free clusters */\n\tFATFS** fatfs\t\t/* Pointer to return pointer to corresponding filesystem object */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDWORD nfree, clst, sect, stat;\n\tUINT i;\n\tFFOBJID obj;\n\n\n\t/* Get logical drive */\n\tres = find_volume(&path, &fs, 0);\n\tif (res == FR_OK) {\n\t\tif (fatfs) *fatfs = fs;\t/* Return ptr to the fs object */\n\t\t/* If free_clst is valid, return it without full FAT scan */\n\t\tif (fs->free_clst <= fs->n_fatent - 2) {\n\t\t\t*nclst = fs->free_clst;\n\t\t} else {\n\t\t\t/* Scan FAT to obtain number of free clusters */\n\t\t\tnfree = 0;\n\t\t\tif (fs->fs_type == FS_FAT12) {\t/* FAT12: Scan bit field FAT entries */\n\t\t\t\tclst = 2; obj.fs = fs;\n\t\t\t\tdo {\n\t\t\t\t\tstat = get_fat(&obj, clst);\n\t\t\t\t\tif (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }\n\t\t\t\t\tif (stat == 1) { res = FR_INT_ERR; break; }\n\t\t\t\t\tif (stat == 0) nfree++;\n\t\t\t\t} while (++clst < fs->n_fatent);\n\t\t\t} else {\n#if FF_FS_EXFAT\n\t\t\t\tif (fs->fs_type == FS_EXFAT) {\t/* exFAT: Scan allocation bitmap */\n\t\t\t\t\tBYTE bm;\n\t\t\t\t\tUINT b;\n\n\t\t\t\t\tclst = fs->n_fatent - 2;\t/* Number of clusters */\n\t\t\t\t\tsect = fs->bitbase;\t\t\t/* Bitmap sector */\n\t\t\t\t\ti = 0;\t\t\t\t\t\t/* Offset in the sector */\n\t\t\t\t\tdo {\t/* Counts numbuer of bits with zero in the bitmap */\n\t\t\t\t\t\tif (i == 0) {\n\t\t\t\t\t\t\tres = move_window(fs, sect++);\n\t\t\t\t\t\t\tif (res != FR_OK) break;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (b = 8, bm = fs->win[i]; b && clst; b--, clst--) {\n\t\t\t\t\t\t\tif (!(bm & 1)) nfree++;\n\t\t\t\t\t\t\tbm >>= 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ti = (i + 1) % SS(fs);\n\t\t\t\t\t} while (clst);\n\t\t\t\t} else\n#endif\n\t\t\t\t{\t/* FAT16/32: Scan WORD/DWORD FAT entries */\n\t\t\t\t\tclst = fs->n_fatent;\t/* Number of entries */\n\t\t\t\t\tsect = fs->fatbase;\t\t/* Top of the FAT */\n\t\t\t\t\ti = 0;\t\t\t\t\t/* Offset in the sector */\n\t\t\t\t\tdo {\t/* Counts numbuer of entries with zero in the FAT */\n\t\t\t\t\t\tif (i == 0) {\n\t\t\t\t\t\t\tres = move_window(fs, sect++);\n\t\t\t\t\t\t\tif (res != FR_OK) break;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (fs->fs_type == FS_FAT16) {\n\t\t\t\t\t\t\tif (ld_word(fs->win + i) == 0) nfree++;\n\t\t\t\t\t\t\ti += 2;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif ((ld_dword(fs->win + i) & 0x0FFFFFFF) == 0) nfree++;\n\t\t\t\t\t\t\ti += 4;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ti %= SS(fs);\n\t\t\t\t\t} while (--clst);\n\t\t\t\t}\n\t\t\t}\n\t\t\t*nclst = nfree;\t\t\t/* Return the free clusters */\n\t\t\tfs->free_clst = nfree;\t/* Now free_clst is valid */\n\t\t\tfs->fsi_flag |= 1;\t\t/* FAT32: FSInfo is to be updated */\n\t\t}\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Truncate File                                                         */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_truncate (\n\tFIL* fp\t\t/* Pointer to the file object */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDWORD ncl;\n\n\n\tres = validate(&fp->obj, &fs);\t/* Check validity of the file object */\n\tif (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res);\n\tif (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED);\t/* Check access mode */\n\n\tif (fp->fptr < fp->obj.objsize) {\t/* Process when fptr is not on the eof */\n\t\tif (fp->fptr == 0) {\t/* When set file size to zero, remove entire cluster chain */\n\t\t\tres = remove_chain(&fp->obj, fp->obj.sclust, 0);\n\t\t\tfp->obj.sclust = 0;\n\t\t} else {\t\t\t\t/* When truncate a part of the file, remove remaining clusters */\n\t\t\tncl = get_fat(&fp->obj, fp->clust);\n\t\t\tres = FR_OK;\n\t\t\tif (ncl == 0xFFFFFFFF) res = FR_DISK_ERR;\n\t\t\tif (ncl == 1) res = FR_INT_ERR;\n\t\t\tif (res == FR_OK && ncl < fs->n_fatent) {\n\t\t\t\tres = remove_chain(&fp->obj, ncl, fp->clust);\n\t\t\t}\n\t\t}\n\t\tfp->obj.objsize = fp->fptr;\t/* Set file size to current read/write point */\n\t\tfp->flag |= FA_MODIFIED;\n#if !FF_FS_TINY\n\t\tif (res == FR_OK && (fp->flag & FA_DIRTY)) {\n\t\t\tif (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) {\n\t\t\t\tres = FR_DISK_ERR;\n\t\t\t} else {\n\t\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t\t}\n\t\t}\n#endif\n\t\tif (res != FR_OK) ABORT(fs, res);\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Delete a File/Directory                                               */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_unlink (\n\tconst TCHAR* path\t\t/* Pointer to the file or directory path */\n)\n{\n\tFRESULT res;\n\tDIR dj, sdj;\n\tDWORD dclst = 0;\n\tFATFS *fs;\n#if FF_FS_EXFAT\n\tFFOBJID obj;\n#endif\n\tDEF_NAMBUF\n\n\n\t/* Get logical drive */\n\tres = find_volume(&path, &fs, FA_WRITE);\n\tif (res == FR_OK) {\n\t\tdj.obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\t\tres = follow_path(&dj, path);\t\t/* Follow the file path */\n\t\tif (FF_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT)) {\n\t\t\tres = FR_INVALID_NAME;\t\t\t/* Cannot remove dot entry */\n\t\t}\n#if FF_FS_LOCK != 0\n\t\tif (res == FR_OK) res = chk_lock(&dj, 2);\t/* Check if it is an open object */\n#endif\n\t\tif (res == FR_OK) {\t\t\t\t\t/* The object is accessible */\n\t\t\tif (dj.fn[NSFLAG] & NS_NONAME) {\n\t\t\t\tres = FR_INVALID_NAME;\t\t/* Cannot remove the origin directory */\n\t\t\t} else {\n\t\t\t\tif (dj.obj.attr & AM_RDO) {\n\t\t\t\t\tres = FR_DENIED;\t\t/* Cannot remove R/O object */\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (res == FR_OK) {\n#if FF_FS_EXFAT\n\t\t\t\tobj.fs = fs;\n\t\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\t\tinit_alloc_info(fs, &obj);\n\t\t\t\t\tdclst = obj.sclust;\n\t\t\t\t} else\n#endif\n\t\t\t\t{\n\t\t\t\t\tdclst = ld_clust(fs, dj.dir);\n\t\t\t\t}\n\t\t\t\tif (dj.obj.attr & AM_DIR) {\t\t\t/* Is it a sub-directory? */\n#if FF_FS_RPATH != 0\n\t\t\t\t\tif (dclst == fs->cdir) {\t\t \t/* Is it the current directory? */\n\t\t\t\t\t\tres = FR_DENIED;\n\t\t\t\t\t} else\n#endif\n\t\t\t\t\t{\n\t\t\t\t\t\tsdj.obj.fs = fs;\t\t\t\t/* Open the sub-directory */\n\t\t\t\t\t\tsdj.obj.sclust = dclst;\n#if FF_FS_EXFAT\n\t\t\t\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\t\t\t\tsdj.obj.objsize = obj.objsize;\n\t\t\t\t\t\t\tsdj.obj.stat = obj.stat;\n\t\t\t\t\t\t}\n#endif\n\t\t\t\t\t\tres = dir_sdi(&sdj, 0);\n\t\t\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\t\t\tres = DIR_READ_FILE(&sdj);\t\t\t/* Test if the directory is empty */\n\t\t\t\t\t\t\tif (res == FR_OK) res = FR_DENIED;\t/* Not empty? */\n\t\t\t\t\t\t\tif (res == FR_NO_FILE) res = FR_OK;\t/* Empty? */\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (res == FR_OK) {\n\t\t\t\tres = dir_remove(&dj);\t\t\t/* Remove the directory entry */\n\t\t\t\tif (res == FR_OK && dclst != 0) {\t/* Remove the cluster chain if exist */\n#if FF_FS_EXFAT\n\t\t\t\t\tres = remove_chain(&obj, dclst, 0);\n#else\n\t\t\t\t\tres = remove_chain(&dj.obj, dclst, 0);\n#endif\n\t\t\t\t}\n\t\t\t\tif (res == FR_OK) res = sync_fs(fs);\n\t\t\t}\n\t\t}\n\t\tFREE_NAMBUF();\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Create a Directory                                                    */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_mkdir (\n\tconst TCHAR* path\t\t/* Pointer to the directory path */\n)\n{\n\tFRESULT res;\n\tDIR dj;\n\tFFOBJID sobj;\n\tFATFS *fs;\n\tDWORD dcl, pcl, tm;\n\tDEF_NAMBUF\n\n\n\tres = find_volume(&path, &fs, FA_WRITE);\t/* Get logical drive */\n\tif (res == FR_OK) {\n\t\tdj.obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\t\tres = follow_path(&dj, path);\t\t\t/* Follow the file path */\n\t\tif (res == FR_OK) res = FR_EXIST;\t\t/* Name collision? */\n\t\tif (FF_FS_RPATH && res == FR_NO_FILE && (dj.fn[NSFLAG] & NS_DOT)) {\t/* Invalid name? */\n\t\t\tres = FR_INVALID_NAME;\n\t\t}\n\t\tif (res == FR_NO_FILE) {\t\t\t\t/* It is clear to create a new directory */\n\t\t\tsobj.fs = fs;\t\t\t\t\t\t/* New object id to create a new chain */\n\t\t\tdcl = create_chain(&sobj, 0);\t\t/* Allocate a cluster for the new directory */\n\t\t\tres = FR_OK;\n\t\t\tif (dcl == 0) res = FR_DENIED;\t\t/* No space to allocate a new cluster? */\n\t\t\tif (dcl == 1) res = FR_INT_ERR;\t\t/* Any insanity? */\n\t\t\tif (dcl == 0xFFFFFFFF) res = FR_DISK_ERR;\t/* Disk error? */\n\t\t\ttm = GET_FATTIME();\n\t\t\tif (res == FR_OK) {\n\t\t\t\tres = dir_clear(fs, dcl);\t\t/* Clean up the new table */\n\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\tif (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) {\t/* Create dot entries (FAT only) */\n\t\t\t\t\t\tmem_set(fs->win + DIR_Name, ' ', 11);\t/* Create \".\" entry */\n\t\t\t\t\t\tfs->win[DIR_Name] = '.';\n\t\t\t\t\t\tfs->win[DIR_Attr] = AM_DIR;\n\t\t\t\t\t\tst_dword(fs->win + DIR_ModTime, tm);\n\t\t\t\t\t\tst_clust(fs, fs->win, dcl);\n\t\t\t\t\t\tmem_cpy(fs->win + SZDIRE, fs->win, SZDIRE); /* Create \"..\" entry */\n\t\t\t\t\t\tfs->win[SZDIRE + 1] = '.'; pcl = dj.obj.sclust;\n\t\t\t\t\t\tst_clust(fs, fs->win + SZDIRE, pcl);\n\t\t\t\t\t\tfs->wflag = 1;\n\t\t\t\t\t}\n\t\t\t\t\tres = dir_register(&dj);\t/* Register the object to the parent directoy */\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (res == FR_OK) {\n#if FF_FS_EXFAT\n\t\t\t\tif (fs->fs_type == FS_EXFAT) {\t/* Initialize directory entry block */\n\t\t\t\t\tst_dword(fs->dirbuf + XDIR_ModTime, tm);\t/* Created time */\n\t\t\t\t\tst_dword(fs->dirbuf + XDIR_FstClus, dcl);\t/* Table start cluster */\n\t\t\t\t\tst_dword(fs->dirbuf + XDIR_FileSize, (DWORD)fs->csize * SS(fs));\t/* File size needs to be valid */\n\t\t\t\t\tst_dword(fs->dirbuf + XDIR_ValidFileSize, (DWORD)fs->csize * SS(fs));\n\t\t\t\t\tfs->dirbuf[XDIR_GenFlags] = 3;\t\t\t\t/* Initialize the object flag */\n\t\t\t\t\tfs->dirbuf[XDIR_Attr] = AM_DIR;\t\t\t\t/* Attribute */\n\t\t\t\t\tres = store_xdir(&dj);\n\t\t\t\t} else\n#endif\n\t\t\t\t{\n\t\t\t\t\tst_dword(dj.dir + DIR_ModTime, tm);\t/* Created time */\n\t\t\t\t\tst_clust(fs, dj.dir, dcl);\t\t\t/* Table start cluster */\n\t\t\t\t\tdj.dir[DIR_Attr] = AM_DIR;\t\t\t/* Attribute */\n\t\t\t\t\tfs->wflag = 1;\n\t\t\t\t}\n\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\tres = sync_fs(fs);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tremove_chain(&sobj, dcl, 0);\t\t/* Could not register, remove the allocated cluster */\n\t\t\t}\n\t\t}\n\t\tFREE_NAMBUF();\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Rename a File/Directory                                               */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_rename (\n\tconst TCHAR* path_old,\t/* Pointer to the object name to be renamed */\n\tconst TCHAR* path_new\t/* Pointer to the new name */\n)\n{\n\tFRESULT res;\n\tDIR djo, djn;\n\tFATFS *fs;\n\tBYTE buf[FF_FS_EXFAT ? SZDIRE * 2 : SZDIRE], *dir;\n\tDWORD dw;\n\tDEF_NAMBUF\n\n\n\tget_ldnumber(&path_new);\t\t\t\t\t\t/* Snip the drive number of new name off */\n\tres = find_volume(&path_old, &fs, FA_WRITE);\t/* Get logical drive of the old object */\n\tif (res == FR_OK) {\n\t\tdjo.obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\t\tres = follow_path(&djo, path_old);\t\t/* Check old object */\n\t\tif (res == FR_OK && (djo.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME;\t/* Check validity of name */\n#if FF_FS_LOCK != 0\n\t\tif (res == FR_OK) {\n\t\t\tres = chk_lock(&djo, 2);\n\t\t}\n#endif\n\t\tif (res == FR_OK) {\t\t\t\t\t\t/* Object to be renamed is found */\n#if FF_FS_EXFAT\n\t\t\tif (fs->fs_type == FS_EXFAT) {\t/* At exFAT volume */\n\t\t\t\tBYTE nf, nn;\n\t\t\t\tWORD nh;\n\n\t\t\t\tmem_cpy(buf, fs->dirbuf, SZDIRE * 2);\t/* Save 85+C0 entry of old object */\n\t\t\t\tmem_cpy(&djn, &djo, sizeof djo);\n\t\t\t\tres = follow_path(&djn, path_new);\t\t/* Make sure if new object name is not in use */\n\t\t\t\tif (res == FR_OK) {\t\t\t\t\t\t/* Is new name already in use by any other object? */\n\t\t\t\t\tres = (djn.obj.sclust == djo.obj.sclust && djn.dptr == djo.dptr) ? FR_NO_FILE : FR_EXIST;\n\t\t\t\t}\n\t\t\t\tif (res == FR_NO_FILE) { \t\t\t\t/* It is a valid path and no name collision */\n\t\t\t\t\tres = dir_register(&djn);\t\t\t/* Register the new entry */\n\t\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\t\tnf = fs->dirbuf[XDIR_NumSec]; nn = fs->dirbuf[XDIR_NumName];\n\t\t\t\t\t\tnh = ld_word(fs->dirbuf + XDIR_NameHash);\n\t\t\t\t\t\tmem_cpy(fs->dirbuf, buf, SZDIRE * 2);\t/* Restore 85+C0 entry */\n\t\t\t\t\t\tfs->dirbuf[XDIR_NumSec] = nf; fs->dirbuf[XDIR_NumName] = nn;\n\t\t\t\t\t\tst_word(fs->dirbuf + XDIR_NameHash, nh);\n\t\t\t\t\t\tif (!(fs->dirbuf[XDIR_Attr] & AM_DIR)) fs->dirbuf[XDIR_Attr] |= AM_ARC;\t/* Set archive attribute if it is a file */\n/* Start of critical section where an interruption can cause a cross-link */\n\t\t\t\t\t\tres = store_xdir(&djn);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else\n#endif\n\t\t\t{\t/* At FAT/FAT32 volume */\n\t\t\t\tmem_cpy(buf, djo.dir, SZDIRE);\t\t\t/* Save directory entry of the object */\n\t\t\t\tmem_cpy(&djn, &djo, sizeof (DIR));\t\t/* Duplicate the directory object */\n\t\t\t\tres = follow_path(&djn, path_new);\t\t/* Make sure if new object name is not in use */\n\t\t\t\tif (res == FR_OK) {\t\t\t\t\t\t/* Is new name already in use by any other object? */\n\t\t\t\t\tres = (djn.obj.sclust == djo.obj.sclust && djn.dptr == djo.dptr) ? FR_NO_FILE : FR_EXIST;\n\t\t\t\t}\n\t\t\t\tif (res == FR_NO_FILE) { \t\t\t\t/* It is a valid path and no name collision */\n\t\t\t\t\tres = dir_register(&djn);\t\t\t/* Register the new entry */\n\t\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\t\tdir = djn.dir;\t\t\t\t\t/* Copy directory entry of the object except name */\n\t\t\t\t\t\tmem_cpy(dir + 13, buf + 13, SZDIRE - 13);\n\t\t\t\t\t\tdir[DIR_Attr] = buf[DIR_Attr];\n\t\t\t\t\t\tif (!(dir[DIR_Attr] & AM_DIR)) dir[DIR_Attr] |= AM_ARC;\t/* Set archive attribute if it is a file */\n\t\t\t\t\t\tfs->wflag = 1;\n\t\t\t\t\t\tif ((dir[DIR_Attr] & AM_DIR) && djo.obj.sclust != djn.obj.sclust) {\t/* Update .. entry in the sub-directory if needed */\n\t\t\t\t\t\t\tdw = clst2sect(fs, ld_clust(fs, dir));\n\t\t\t\t\t\t\tif (dw == 0) {\n\t\t\t\t\t\t\t\tres = FR_INT_ERR;\n\t\t\t\t\t\t\t} else {\n/* Start of critical section where an interruption can cause a cross-link */\n\t\t\t\t\t\t\t\tres = move_window(fs, dw);\n\t\t\t\t\t\t\t\tdir = fs->win + SZDIRE * 1;\t/* Ptr to .. entry */\n\t\t\t\t\t\t\t\tif (res == FR_OK && dir[1] == '.') {\n\t\t\t\t\t\t\t\t\tst_clust(fs, dir, djn.obj.sclust);\n\t\t\t\t\t\t\t\t\tfs->wflag = 1;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (res == FR_OK) {\n\t\t\t\tres = dir_remove(&djo);\t\t/* Remove old entry */\n\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\tres = sync_fs(fs);\n\t\t\t\t}\n\t\t\t}\n/* End of the critical section */\n\t\t}\n\t\tFREE_NAMBUF();\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n#endif /* !FF_FS_READONLY */\n#endif /* FF_FS_MINIMIZE == 0 */\n#endif /* FF_FS_MINIMIZE <= 1 */\n#endif /* FF_FS_MINIMIZE <= 2 */\n\n\n\n#if FF_USE_CHMOD && !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Change Attribute                                                      */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_chmod (\n\tconst TCHAR* path,\t/* Pointer to the file path */\n\tBYTE attr,\t\t\t/* Attribute bits */\n\tBYTE mask\t\t\t/* Attribute mask to change */\n)\n{\n\tFRESULT res;\n\tDIR dj;\n\tFATFS *fs;\n\tDEF_NAMBUF\n\n\n\tres = find_volume(&path, &fs, FA_WRITE);\t/* Get logical drive */\n\tif (res == FR_OK) {\n\t\tdj.obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\t\tres = follow_path(&dj, path);\t/* Follow the file path */\n\t\tif (res == FR_OK && (dj.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME;\t/* Check object validity */\n\t\tif (res == FR_OK) {\n\t\t\tmask &= AM_RDO|AM_HID|AM_SYS|AM_ARC;\t/* Valid attribute mask */\n#if FF_FS_EXFAT\n\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\tfs->dirbuf[XDIR_Attr] = (attr & mask) | (fs->dirbuf[XDIR_Attr] & (BYTE)~mask);\t/* Apply attribute change */\n\t\t\t\tres = store_xdir(&dj);\n\t\t\t} else\n#endif\n\t\t\t{\n\t\t\t\tdj.dir[DIR_Attr] = (attr & mask) | (dj.dir[DIR_Attr] & (BYTE)~mask);\t/* Apply attribute change */\n\t\t\t\tfs->wflag = 1;\n\t\t\t}\n\t\t\tif (res == FR_OK) {\n\t\t\t\tres = sync_fs(fs);\n\t\t\t}\n\t\t}\n\t\tFREE_NAMBUF();\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Change Timestamp                                                      */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_utime (\n\tconst TCHAR* path,\t/* Pointer to the file/directory name */\n\tconst FILINFO* fno\t/* Pointer to the timestamp to be set */\n)\n{\n\tFRESULT res;\n\tDIR dj;\n\tFATFS *fs;\n\tDEF_NAMBUF\n\n\n\tres = find_volume(&path, &fs, FA_WRITE);\t/* Get logical drive */\n\tif (res == FR_OK) {\n\t\tdj.obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\t\tres = follow_path(&dj, path);\t/* Follow the file path */\n\t\tif (res == FR_OK && (dj.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME;\t/* Check object validity */\n\t\tif (res == FR_OK) {\n#if FF_FS_EXFAT\n\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\tst_dword(fs->dirbuf + XDIR_ModTime, (DWORD)fno->fdate << 16 | fno->ftime);\n\t\t\t\tres = store_xdir(&dj);\n\t\t\t} else\n#endif\n\t\t\t{\n\t\t\t\tst_dword(dj.dir + DIR_ModTime, (DWORD)fno->fdate << 16 | fno->ftime);\n\t\t\t\tfs->wflag = 1;\n\t\t\t}\n\t\t\tif (res == FR_OK) {\n\t\t\t\tres = sync_fs(fs);\n\t\t\t}\n\t\t}\n\t\tFREE_NAMBUF();\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n#endif\t/* FF_USE_CHMOD && !FF_FS_READONLY */\n\n\n\n#if FF_USE_LABEL\n/*-----------------------------------------------------------------------*/\n/* Get Volume Label                                                      */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_getlabel (\n\tconst TCHAR* path,\t/* Logical drive number */\n\tTCHAR* label,\t\t/* Buffer to store the volume label */\n\tDWORD* vsn\t\t\t/* Variable to store the volume serial number */\n)\n{\n\tFRESULT res;\n\tDIR dj;\n\tFATFS *fs;\n\tUINT si, di;\n\tWCHAR wc;\n\n\t/* Get logical drive */\n\tres = find_volume(&path, &fs, 0);\n\n\t/* Get volume label */\n\tif (res == FR_OK && label) {\n\t\tdj.obj.fs = fs; dj.obj.sclust = 0;\t/* Open root directory */\n\t\tres = dir_sdi(&dj, 0);\n\t\tif (res == FR_OK) {\n\t\t \tres = DIR_READ_LABEL(&dj);\t\t/* Find a volume label entry */\n\t\t \tif (res == FR_OK) {\n#if FF_FS_EXFAT\n\t\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\t\tWCHAR hs;\n\n\t\t\t\t\tfor (si = di = hs = 0; si < dj.dir[XDIR_NumLabel]; si++) {\t/* Extract volume label from 83 entry */\n\t\t\t\t\t\twc = ld_word(dj.dir + XDIR_Label + si * 2);\n\t\t\t\t\t\tif (hs == 0 && IsSurrogate(wc)) {\t/* Is the code a surrogate? */\n\t\t\t\t\t\t\ths = wc; continue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\twc = put_utf((DWORD)hs << 16 | wc, &label[di], 4);\n\t\t\t\t\t\tif (wc == 0) { di = 0; break; }\n\t\t\t\t\t\tdi += wc;\n\t\t\t\t\t\ths = 0;\n\t\t\t\t\t}\n\t\t\t\t\tif (hs != 0) di = 0;\t/* Broken surrogate pair? */\n\t\t\t\t\tlabel[di] = 0;\n\t\t\t\t} else\n#endif\n\t\t\t\t{\n\t\t\t\t\tsi = di = 0;\t\t/* Extract volume label from AM_VOL entry */\n\t\t\t\t\twhile (si < 11) {\n\t\t\t\t\t\twc = dj.dir[si++];\n#if FF_USE_LFN && FF_LFN_UNICODE >= 1 \t/* Unicode output */\n\t\t\t\t\t\tif (dbc_1st((BYTE)wc) && si < 11) wc = wc << 8 | dj.dir[si++];\t/* Is it a DBC? */\n\t\t\t\t\t\twc = ff_oem2uni(wc, CODEPAGE);\t\t\t\t\t/* Convert it into Unicode */\n\t\t\t\t\t\tif (wc != 0) wc = put_utf(wc, &label[di], 4);\t/* Put it in Unicode */\n\t\t\t\t\t\tif (wc == 0) { di = 0; break; }\n\t\t\t\t\t\tdi += wc;\n#else\t\t\t\t\t\t\t\t\t/* ANSI/OEM output */\n\t\t\t\t\t\tlabel[di++] = (TCHAR)wc;\n#endif\n\t\t\t\t\t}\n\t\t\t\t\tdo {\t\t\t\t/* Truncate trailing spaces */\n\t\t\t\t\t\tlabel[di] = 0;\n\t\t\t\t\t\tif (di == 0) break;\n\t\t\t\t\t} while (label[--di] == ' ');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (res == FR_NO_FILE) {\t/* No label entry and return nul string */\n\t\t\tlabel[0] = 0;\n\t\t\tres = FR_OK;\n\t\t}\n\t}\n\n\t/* Get volume serial number */\n\tif (res == FR_OK && vsn) {\n\t\tres = move_window(fs, fs->volbase);\n\t\tif (res == FR_OK) {\n\t\t\tswitch (fs->fs_type) {\n\t\t\tcase FS_EXFAT:\n\t\t\t\tdi = BPB_VolIDEx; break;\n\n\t\t\tcase FS_FAT32:\n\t\t\t\tdi = BS_VolID32; break;\n\n\t\t\tdefault:\n\t\t\t\tdi = BS_VolID;\n\t\t\t}\n\t\t\t*vsn = ld_dword(fs->win + di);\n\t\t}\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Set Volume Label                                                      */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_setlabel (\n\tconst TCHAR* label\t/* Volume label to set with heading logical drive number */\n)\n{\n\tFRESULT res;\n\tDIR dj;\n\tFATFS *fs;\n\tBYTE dirvn[22];\n\tUINT di;\n\tWCHAR wc;\n\tstatic const char badchr[] = \"+.,;=[]/\\\\\\\"*:<>\\?|\\x7F\";\t/* [0..] for FAT, [7..] for exFAT */\n#if FF_USE_LFN\n\tDWORD dc;\n#endif\n\n\t/* Get logical drive */\n\tres = find_volume(&label, &fs, FA_WRITE);\n\tif (res != FR_OK) LEAVE_FF(fs, res);\n\n#if FF_FS_EXFAT\n\tif (fs->fs_type == FS_EXFAT) {\t/* On the exFAT volume */\n\t\tmem_set(dirvn, 0, 22);\n\t\tdi = 0;\n\t\twhile ((UINT)*label >= ' ') {\t/* Create volume label */\n\t\t\tdc = tchar2uni(&label);\t/* Get a Unicode character */\n\t\t\tif (dc >= 0x10000) {\n\t\t\t\tif (dc == 0xFFFFFFFF || di >= 10) {\t/* Wrong surrogate or buffer overflow */\n\t\t\t\t\tdc = 0;\n\t\t\t\t} else {\n\t\t\t\t\tst_word(dirvn + di * 2, (WCHAR)(dc >> 16)); di++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (dc == 0 || chk_chr(badchr + 7, (int)dc) || di >= 11) {\t/* Check validity of the volume label */\n\t\t\t\tLEAVE_FF(fs, FR_INVALID_NAME);\n\t\t\t}\n\t\t\tst_word(dirvn + di * 2, (WCHAR)dc); di++;\n\t\t}\n\t} else\n#endif\n\t{\t/* On the FAT/FAT32 volume */\n\t\tmem_set(dirvn, ' ', 11);\n\t\tdi = 0;\n\t\twhile ((UINT)*label >= ' ') {\t/* Create volume label */\n#if FF_USE_LFN\n\t\t\tdc = tchar2uni(&label);\n\t\t\twc = (dc < 0x10000) ? ff_uni2oem(ff_wtoupper(dc), CODEPAGE) : 0;\n#else\t\t\t\t\t\t\t\t\t/* ANSI/OEM input */\n\t\t\twc = (BYTE)*label++;\n\t\t\tif (dbc_1st((BYTE)wc)) wc = dbc_2nd((BYTE)*label) ? wc << 8 | (BYTE)*label++ : 0;\n\t\t\tif (IsLower(wc)) wc -= 0x20;\t\t/* To upper ASCII characters */\n#if FF_CODE_PAGE == 0\n\t\t\tif (ExCvt && wc >= 0x80) wc = ExCvt[wc - 0x80];\t/* To upper extended characters (SBCS cfg) */\n#elif FF_CODE_PAGE < 900\n\t\t\tif (wc >= 0x80) wc = ExCvt[wc - 0x80];\t/* To upper extended characters (SBCS cfg) */\n#endif\n#endif\n\t\t\tif (wc == 0 || chk_chr(badchr + 0, (int)wc) || di >= (UINT)((wc >= 0x100) ? 10 : 11)) {\t/* Reject invalid characters for volume label */\n\t\t\t\tLEAVE_FF(fs, FR_INVALID_NAME);\n\t\t\t}\n\t\t\tif (wc >= 0x100) dirvn[di++] = (BYTE)(wc >> 8);\n\t\t\tdirvn[di++] = (BYTE)wc;\n\t\t}\n\t\tif (dirvn[0] == DDEM) LEAVE_FF(fs, FR_INVALID_NAME);\t/* Reject illegal name (heading DDEM) */\n\t\twhile (di && dirvn[di - 1] == ' ') di--;\t\t\t\t/* Snip trailing spaces */\n\t}\n\n\t/* Set volume label */\n\tdj.obj.fs = fs; dj.obj.sclust = 0;\t/* Open root directory */\n\tres = dir_sdi(&dj, 0);\n\tif (res == FR_OK) {\n\t\tres = DIR_READ_LABEL(&dj);\t/* Get volume label entry */\n\t\tif (res == FR_OK) {\n\t\t\tif (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) {\n\t\t\t\tdj.dir[XDIR_NumLabel] = (BYTE)di;\t/* Change the volume label */\n\t\t\t\tmem_cpy(dj.dir + XDIR_Label, dirvn, 22);\n\t\t\t} else {\n\t\t\t\tif (di != 0) {\n\t\t\t\t\tmem_cpy(dj.dir, dirvn, 11);\t/* Change the volume label */\n\t\t\t\t} else {\n\t\t\t\t\tdj.dir[DIR_Name] = DDEM;\t/* Remove the volume label */\n\t\t\t\t}\n\t\t\t}\n\t\t\tfs->wflag = 1;\n\t\t\tres = sync_fs(fs);\n\t\t} else {\t\t\t/* No volume label entry or an error */\n\t\t\tif (res == FR_NO_FILE) {\n\t\t\t\tres = FR_OK;\n\t\t\t\tif (di != 0) {\t/* Create a volume label entry */\n\t\t\t\t\tres = dir_alloc(&dj, 1);\t/* Allocate an entry */\n\t\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\t\tmem_set(dj.dir, 0, SZDIRE);\t/* Clean the entry */\n\t\t\t\t\t\tif (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) {\n\t\t\t\t\t\t\tdj.dir[XDIR_Type] = ET_VLABEL;\t/* Create volume label entry */\n\t\t\t\t\t\t\tdj.dir[XDIR_NumLabel] = (BYTE)di;\n\t\t\t\t\t\t\tmem_cpy(dj.dir + XDIR_Label, dirvn, 22);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdj.dir[DIR_Attr] = AM_VOL;\t\t/* Create volume label entry */\n\t\t\t\t\t\t\tmem_cpy(dj.dir, dirvn, 11);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfs->wflag = 1;\n\t\t\t\t\t\tres = sync_fs(fs);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n#endif /* !FF_FS_READONLY */\n#endif /* FF_USE_LABEL */\n\n\n\n#if FF_USE_EXPAND && !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Allocate a Contiguous Blocks to the File                              */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_expand (\n\tFIL* fp,\t\t/* Pointer to the file object */\n\tFSIZE_t fsz,\t/* File size to be expanded to */\n\tBYTE opt\t\t/* Operation mode 0:Find and prepare or 1:Find and allocate */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDWORD n, clst, stcl, scl, ncl, tcl, lclst;\n\n\n\tres = validate(&fp->obj, &fs);\t\t/* Check validity of the file object */\n\tif (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res);\n\tif (fsz == 0 || fp->obj.objsize != 0 || !(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED);\n#if FF_FS_EXFAT\n\tif (fs->fs_type != FS_EXFAT && fsz >= 0x100000000) LEAVE_FF(fs, FR_DENIED);\t/* Check if in size limit */\n#endif\n\tn = (DWORD)fs->csize * SS(fs);\t/* Cluster size */\n\ttcl = (DWORD)(fsz / n) + ((fsz & (n - 1)) ? 1 : 0);\t/* Number of clusters required */\n\tstcl = fs->last_clst; lclst = 0;\n\tif (stcl < 2 || stcl >= fs->n_fatent) stcl = 2;\n\n#if FF_FS_EXFAT\n\tif (fs->fs_type == FS_EXFAT) {\n\t\tscl = find_bitmap(fs, stcl, tcl);\t\t\t/* Find a contiguous cluster block */\n\t\tif (scl == 0) res = FR_DENIED;\t\t\t\t/* No contiguous cluster block was found */\n\t\tif (scl == 0xFFFFFFFF) res = FR_DISK_ERR;\n\t\tif (res == FR_OK) {\t/* A contiguous free area is found */\n\t\t\tif (opt) {\t\t/* Allocate it now */\n\t\t\t\tres = change_bitmap(fs, scl, tcl, 1);\t/* Mark the cluster block 'in use' */\n\t\t\t\tlclst = scl + tcl - 1;\n\t\t\t} else {\t\t/* Set it as suggested point for next allocation */\n\t\t\t\tlclst = scl - 1;\n\t\t\t}\n\t\t}\n\t} else\n#endif\n\t{\n\t\tscl = clst = stcl; ncl = 0;\n\t\tfor (;;) {\t/* Find a contiguous cluster block */\n\t\t\tn = get_fat(&fp->obj, clst);\n\t\t\tif (++clst >= fs->n_fatent) clst = 2;\n\t\t\tif (n == 1) { res = FR_INT_ERR; break; }\n\t\t\tif (n == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }\n\t\t\tif (n == 0) {\t/* Is it a free cluster? */\n\t\t\t\tif (++ncl == tcl) break;\t/* Break if a contiguous cluster block is found */\n\t\t\t} else {\n\t\t\t\tscl = clst; ncl = 0;\t\t/* Not a free cluster */\n\t\t\t}\n\t\t\tif (clst == stcl) { res = FR_DENIED; break; }\t/* No contiguous cluster? */\n\t\t}\n\t\tif (res == FR_OK) {\t/* A contiguous free area is found */\n\t\t\tif (opt) {\t\t/* Allocate it now */\n\t\t\t\tfor (clst = scl, n = tcl; n; clst++, n--) {\t/* Create a cluster chain on the FAT */\n\t\t\t\t\tres = put_fat(fs, clst, (n == 1) ? 0xFFFFFFFF : clst + 1);\n\t\t\t\t\tif (res != FR_OK) break;\n\t\t\t\t\tlclst = clst;\n\t\t\t\t}\n\t\t\t} else {\t\t/* Set it as suggested point for next allocation */\n\t\t\t\tlclst = scl - 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (res == FR_OK) {\n\t\tfs->last_clst = lclst;\t\t/* Set suggested start cluster to start next */\n\t\tif (opt) {\t/* Is it allocated now? */\n\t\t\tfp->obj.sclust = scl;\t\t/* Update object allocation information */\n\t\t\tfp->obj.objsize = fsz;\n\t\t\tif (FF_FS_EXFAT) fp->obj.stat = 2;\t/* Set status 'contiguous chain' */\n\t\t\tfp->flag |= FA_MODIFIED;\n\t\t\tif (fs->free_clst <= fs->n_fatent - 2) {\t/* Update FSINFO */\n\t\t\t\tfs->free_clst -= tcl;\n\t\t\t\tfs->fsi_flag |= 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n#endif /* FF_USE_EXPAND && !FF_FS_READONLY */\n\n\n\n#if FF_USE_FORWARD\n/*-----------------------------------------------------------------------*/\n/* Forward Data to the Stream Directly                                   */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_forward (\n\tFIL* fp, \t\t\t\t\t\t/* Pointer to the file object */\n\tUINT (*func)(const BYTE*,UINT),\t/* Pointer to the streaming function */\n\tUINT btf,\t\t\t\t\t\t/* Number of bytes to forward */\n\tUINT* bf\t\t\t\t\t\t/* Pointer to number of bytes forwarded */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDWORD clst, sect;\n\tFSIZE_t remain;\n\tUINT rcnt, csect;\n\tBYTE *dbuf;\n\n\n\t*bf = 0;\t/* Clear transfer byte counter */\n\tres = validate(&fp->obj, &fs);\t\t/* Check validity of the file object */\n\tif (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res);\n\tif (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED);\t/* Check access mode */\n\n\tremain = fp->obj.objsize - fp->fptr;\n\tif (btf > remain) btf = (UINT)remain;\t\t\t/* Truncate btf by remaining bytes */\n\n\tfor ( ;  btf && (*func)(0, 0);\t\t\t\t\t/* Repeat until all data transferred or stream goes busy */\n\t\tfp->fptr += rcnt, *bf += rcnt, btf -= rcnt) {\n\t\tcsect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1));\t/* Sector offset in the cluster */\n\t\tif (fp->fptr % SS(fs) == 0) {\t\t\t\t/* On the sector boundary? */\n\t\t\tif (csect == 0) {\t\t\t\t\t\t/* On the cluster boundary? */\n\t\t\t\tclst = (fp->fptr == 0) ?\t\t\t/* On the top of the file? */\n\t\t\t\t\tfp->obj.sclust : get_fat(&fp->obj, fp->clust);\n\t\t\t\tif (clst <= 1) ABORT(fs, FR_INT_ERR);\n\t\t\t\tif (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);\n\t\t\t\tfp->clust = clst;\t\t\t\t\t/* Update current cluster */\n\t\t\t}\n\t\t}\n\t\tsect = clst2sect(fs, fp->clust);\t\t\t/* Get current data sector */\n\t\tif (sect == 0) ABORT(fs, FR_INT_ERR);\n\t\tsect += csect;\n#if FF_FS_TINY\n\t\tif (move_window(fs, sect) != FR_OK) ABORT(fs, FR_DISK_ERR);\t/* Move sector window to the file data */\n\t\tdbuf = fs->win;\n#else\n\t\tif (fp->sect != sect) {\t\t/* Fill sector cache with file data */\n#if !FF_FS_READONLY\n\t\t\tif (fp->flag & FA_DIRTY) {\t\t/* Write-back dirty sector cache */\n\t\t\t\tif (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t\t}\n#endif\n\t\t\tif (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t}\n\t\tdbuf = fp->buf;\n#endif\n\t\tfp->sect = sect;\n\t\trcnt = SS(fs) - (UINT)fp->fptr % SS(fs);\t/* Number of bytes left in the sector */\n\t\tif (rcnt > btf) rcnt = btf;\t\t\t\t\t/* Clip it by btr if needed */\n\t\trcnt = (*func)(dbuf + ((UINT)fp->fptr % SS(fs)), rcnt);\t/* Forward the file data */\n\t\tif (rcnt == 0) ABORT(fs, FR_INT_ERR);\n\t}\n\n\tLEAVE_FF(fs, FR_OK);\n}\n#endif /* FF_USE_FORWARD */\n\n\n\n#if FF_USE_MKFS && !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Create an FAT/exFAT volume                                            */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_mkfs (\n\tconst TCHAR* path,\t/* Logical drive number */\n\tBYTE opt,\t\t\t/* Format option */\n\tDWORD au,\t\t\t/* Size of allocation unit (cluster) [byte] */\n\tvoid* work,\t\t\t/* Pointer to working buffer (null: use heap memory) */\n\tUINT len\t\t\t/* Size of working buffer [byte] */\n)\n{\n\tconst UINT n_fats = 1;\t\t/* Number of FATs for FAT/FAT32 volume (1 or 2) */\n\tconst UINT n_rootdir = 512;\t/* Number of root directory entries for FAT volume */\n\tstatic const WORD cst[] = {1, 4, 16, 64, 256, 512, 0};\t/* Cluster size boundary for FAT volume (4Ks unit) */\n\tstatic const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0};\t/* Cluster size boundary for FAT32 volume (128Ks unit) */\n\tBYTE fmt, sys, *buf, *pte, pdrv, part;\n\tWORD ss;\t/* Sector size */\n\tDWORD szb_buf, sz_buf, sz_blk, n_clst, pau, sect, nsect, n;\n\tDWORD b_vol, b_fat, b_data;\t\t\t\t/* Base LBA for volume, fat, data */\n\tDWORD sz_vol, sz_rsv, sz_fat, sz_dir;\t/* Size for volume, fat, dir, data */\n\tUINT i;\n\tint vol;\n\tDSTATUS stat;\n#if FF_USE_TRIM || FF_FS_EXFAT\n\tDWORD tbl[3];\n#endif\n\n\n\t/* Check mounted drive and clear work area */\n\tvol = get_ldnumber(&path);\t\t\t\t\t/* Get target logical drive */\n\tif (vol < 0) return FR_INVALID_DRIVE;\n\tif (FatFs[vol]) FatFs[vol]->fs_type = 0;\t/* Clear the volume if mounted */\n\tpdrv = LD2PD(vol);\t/* Physical drive */\n\tpart = LD2PT(vol);\t/* Partition (0:create as new, 1-4:get from partition table) */\n\n\t/* Check physical drive status */\n\tstat = disk_initialize(pdrv);\n\tif (stat & STA_NOINIT) return FR_NOT_READY;\n\tif (stat & STA_PROTECT) return FR_WRITE_PROTECTED;\n\tif (disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_blk) != RES_OK || !sz_blk || sz_blk > 32768 || (sz_blk & (sz_blk - 1))) sz_blk = 1;\t/* Erase block to align data area */\n#if FF_MAX_SS != FF_MIN_SS\t\t/* Get sector size of the medium if variable sector size cfg. */\n\tif (disk_ioctl(pdrv, GET_SECTOR_SIZE, &ss) != RES_OK) return FR_DISK_ERR;\n\tif (ss > FF_MAX_SS || ss < FF_MIN_SS || (ss & (ss - 1))) return FR_DISK_ERR;\n#else\n\tss = FF_MAX_SS;\n#endif\n\tif ((au != 0 && au < ss) || au > 0x1000000 || (au & (au - 1))) return FR_INVALID_PARAMETER;\t/* Check if au is valid */\n\tau /= ss;\t/* Cluster size in unit of sector */\n\n\t/* Get working buffer */\n#if FF_USE_LFN == 3\n\tif (!work) {\t/* Use heap memory for working buffer */\n\t\tfor (szb_buf = MAX_MALLOC, buf = 0; szb_buf >= ss && (buf = ff_memalloc(szb_buf)) == 0; szb_buf /= 2) ;\n\t\tsz_buf = szb_buf / ss;\t\t/* Size of working buffer (sector) */\n\t} else\n#endif\n\t{\n\t\tbuf = (BYTE*)work;\t\t/* Working buffer */\n\t\tsz_buf = len / ss;\t\t/* Size of working buffer (sector) */\n\t\tszb_buf = sz_buf * ss;\t/* Size of working buffer (byte) */\n\t}\n\tif (!buf || sz_buf == 0) return FR_NOT_ENOUGH_CORE;\n\n\t/* Determine where the volume to be located (b_vol, sz_vol) */\n\tif (FF_MULTI_PARTITION && part != 0) {\n\t\t/* Get partition information from partition table in the MBR */\n\t\tif (disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\t/* Load MBR */\n\t\tif (ld_word(buf + BS_55AA) != 0xAA55) LEAVE_MKFS(FR_MKFS_ABORTED);\t/* Check if MBR is valid */\n\t\tpte = buf + (MBR_Table + (part - 1) * SZ_PTE);\n\t\tif (pte[PTE_System] == 0) LEAVE_MKFS(FR_MKFS_ABORTED);\t/* No partition? */\n\t\tb_vol = ld_dword(pte + PTE_StLba);\t\t/* Get volume start sector */\n\t\tsz_vol = ld_dword(pte + PTE_SizLba);\t/* Get volume size */\n\t} else {\n\t\t/* Create a single-partition in this function */\n\t\tif (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\tb_vol = (opt & FM_SFD) ? 0 : 63;\t\t/* Volume start sector */\n\t\tif (sz_vol < b_vol) LEAVE_MKFS(FR_MKFS_ABORTED);\n\t\tsz_vol -= b_vol;\t\t\t\t\t\t/* Volume size */\n\t}\n\tif (sz_vol < 128) LEAVE_MKFS(FR_MKFS_ABORTED);\t/* Check if volume size is >=128s */\n\n\t/* Pre-determine the FAT type */\n\tdo {\n\t\tif (FF_FS_EXFAT && (opt & FM_EXFAT)) {\t/* exFAT possible? */\n\t\t\tif ((opt & FM_ANY) == FM_EXFAT || sz_vol >= 0x4000000 || au > 128) {\t/* exFAT only, vol >= 64Ms or au > 128s ? */\n\t\t\t\tfmt = FS_EXFAT; break;\n\t\t\t}\n\t\t}\n\t\tif (au > 128) LEAVE_MKFS(FR_INVALID_PARAMETER);\t/* Too large au for FAT/FAT32 */\n\t\tif (opt & FM_FAT32) {\t/* FAT32 possible? */\n\t\t\tif ((opt & FM_ANY) == FM_FAT32 || !(opt & FM_FAT)) {\t/* FAT32 only or no-FAT? */\n\t\t\t\tfmt = FS_FAT32; break;\n\t\t\t}\n\t\t}\n\t\tif (!(opt & FM_FAT)) LEAVE_MKFS(FR_INVALID_PARAMETER);\t/* no-FAT? */\n\t\tfmt = FS_FAT16;\n\t} while (0);\n\n#if FF_FS_EXFAT\n\tif (fmt == FS_EXFAT) {\t/* Create an exFAT volume */\n\t\tDWORD szb_bit, szb_case, sum, nb, cl;\n\t\tWCHAR ch, si;\n\t\tUINT j, st;\n\t\tBYTE b;\n\n\t\tif (sz_vol < 0x1000) LEAVE_MKFS(FR_MKFS_ABORTED);\t/* Too small volume? */\n#if FF_USE_TRIM\n\t\ttbl[0] = b_vol; tbl[1] = b_vol + sz_vol - 1;\t/* Inform the device the volume area may be erased */\n\t\tdisk_ioctl(pdrv, CTRL_TRIM, tbl);\n#endif\n\t\t/* Determine FAT location, data location and number of clusters */\n\t\tif (au == 0) {\t/* au auto-selection */\n\t\t\tau = 8;\n\t\t\tif (sz_vol >= 0x80000) au = 64;\t\t/* >= 512Ks */\n\t\t\tif (sz_vol >= 0x4000000) au = 256;\t/* >= 64Ms */\n\t\t}\n\t\tb_fat = b_vol + 32;\t\t\t\t\t\t\t\t\t\t/* FAT start at offset 32 */\n\t\tsz_fat = ((sz_vol / au + 2) * 4 + ss - 1) / ss;\t\t\t/* Number of FAT sectors */\n\t\tb_data = (b_fat + sz_fat + sz_blk - 1) & ~(sz_blk - 1);\t/* Align data area to the erase block boundary */\n\t\tif (b_data - b_vol >= sz_vol / 2) LEAVE_MKFS(FR_MKFS_ABORTED);\t/* Too small volume? */\n\t\tn_clst = (sz_vol - (b_data - b_vol)) / au;\t\t\t\t/* Number of clusters */\n\t\tif (n_clst <16) LEAVE_MKFS(FR_MKFS_ABORTED);\t\t\t/* Too few clusters? */\n\t\tif (n_clst > MAX_EXFAT) LEAVE_MKFS(FR_MKFS_ABORTED);\t/* Too many clusters? */\n\n\t\tszb_bit = (n_clst + 7) / 8;\t\t\t\t\t\t/* Size of allocation bitmap */\n\t\ttbl[0] = (szb_bit + au * ss - 1) / (au * ss);\t/* Number of allocation bitmap clusters */\n\n\t\t/* Create a compressed up-case table */\n\t\tsect = b_data + au * tbl[0];\t/* Table start sector */\n\t\tsum = 0;\t\t\t\t\t\t/* Table checksum to be stored in the 82 entry */\n\t\tst = 0; si = 0; i = 0; j = 0; szb_case = 0;\n\t\tdo {\n\t\t\tswitch (st) {\n\t\t\tcase 0:\n\t\t\t\tch = (WCHAR)ff_wtoupper(si);\t/* Get an up-case char */\n\t\t\t\tif (ch != si) {\n\t\t\t\t\tsi++; break;\t\t/* Store the up-case char if exist */\n\t\t\t\t}\n\t\t\t\tfor (j = 1; (WCHAR)(si + j) && (WCHAR)(si + j) == ff_wtoupper((WCHAR)(si + j)); j++) ;\t/* Get run length of no-case block */\n\t\t\t\tif (j >= 128) {\n\t\t\t\t\tch = 0xFFFF; st = 2; break;\t/* Compress the no-case block if run is >= 128 */\n\t\t\t\t}\n\t\t\t\tst = 1;\t\t\t/* Do not compress short run */\n\t\t\t\t/* go to next case */\n\t\t\tcase 1:\n\t\t\t\tch = si++;\t\t/* Fill the short run */\n\t\t\t\tif (--j == 0) st = 0;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tch = (WCHAR)j; si += (WCHAR)j;\t/* Number of chars to skip */\n\t\t\t\tst = 0;\n\t\t\t}\n\t\t\tsum = xsum32(buf[i + 0] = (BYTE)ch, sum);\t\t/* Put it into the write buffer */\n\t\t\tsum = xsum32(buf[i + 1] = (BYTE)(ch >> 8), sum);\n\t\t\ti += 2; szb_case += 2;\n\t\t\tif (si == 0 || i == szb_buf) {\t\t/* Write buffered data when buffer full or end of process */\n\t\t\t\tn = (i + ss - 1) / ss;\n\t\t\t\tif (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\t\tsect += n; i = 0;\n\t\t\t}\n\t\t} while (si);\n\t\ttbl[1] = (szb_case + au * ss - 1) / (au * ss);\t/* Number of up-case table clusters */\n\t\ttbl[2] = 1;\t\t\t\t\t\t\t\t\t\t/* Number of root dir clusters */\n\n\t\t/* Initialize the allocation bitmap */\n\t\tsect = b_data; nsect = (szb_bit + ss - 1) / ss;\t/* Start of bitmap and number of sectors */\n\t\tnb = tbl[0] + tbl[1] + tbl[2];\t\t\t\t\t/* Number of clusters in-use by system */\n\t\tdo {\n\t\t\tmem_set(buf, 0, szb_buf);\n\t\t\tfor (i = 0; nb >= 8 && i < szb_buf; buf[i++] = 0xFF, nb -= 8) ;\n\t\t\tfor (b = 1; nb != 0 && i < szb_buf; buf[i] |= b, b <<= 1, nb--) ;\n\t\t\tn = (nsect > sz_buf) ? sz_buf : nsect;\t\t/* Write the buffered data */\n\t\t\tif (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\tsect += n; nsect -= n;\n\t\t} while (nsect);\n\n\t\t/* Initialize the FAT */\n\t\tsect = b_fat; nsect = sz_fat;\t/* Start of FAT and number of FAT sectors */\n\t\tj = nb = cl = 0;\n\t\tdo {\n\t\t\tmem_set(buf, 0, szb_buf); i = 0;\t/* Clear work area and reset write index */\n\t\t\tif (cl == 0) {\t/* Set entry 0 and 1 */\n\t\t\t\tst_dword(buf + i, 0xFFFFFFF8); i += 4; cl++;\n\t\t\t\tst_dword(buf + i, 0xFFFFFFFF); i += 4; cl++;\n\t\t\t}\n\t\t\tdo {\t\t\t/* Create chains of bitmap, up-case and root dir */\n\t\t\t\twhile (nb != 0 && i < szb_buf) {\t\t\t/* Create a chain */\n\t\t\t\t\tst_dword(buf + i, (nb > 1) ? cl + 1 : 0xFFFFFFFF);\n\t\t\t\t\ti += 4; cl++; nb--;\n\t\t\t\t}\n\t\t\t\tif (nb == 0 && j < 3) nb = tbl[j++];\t/* Next chain */\n\t\t\t} while (nb != 0 && i < szb_buf);\n\t\t\tn = (nsect > sz_buf) ? sz_buf : nsect;\t/* Write the buffered data */\n\t\t\tif (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\tsect += n; nsect -= n;\n\t\t} while (nsect);\n\n\t\t/* Initialize the root directory */\n\t\tmem_set(buf, 0, szb_buf);\n\t\tbuf[SZDIRE * 0 + 0] = ET_VLABEL;\t\t/* Volume label entry */\n\t\tbuf[SZDIRE * 1 + 0] = ET_BITMAP;\t\t/* Bitmap entry */\n\t\tst_dword(buf + SZDIRE * 1 + 20, 2);\t\t\t\t/* cluster */\n\t\tst_dword(buf + SZDIRE * 1 + 24, szb_bit);\t\t/* size */\n\t\tbuf[SZDIRE * 2 + 0] = ET_UPCASE;\t\t/* Up-case table entry */\n\t\tst_dword(buf + SZDIRE * 2 + 4, sum);\t\t\t/* sum */\n\t\tst_dword(buf + SZDIRE * 2 + 20, 2 + tbl[0]);\t/* cluster */\n\t\tst_dword(buf + SZDIRE * 2 + 24, szb_case);\t\t/* size */\n\t\tsect = b_data + au * (tbl[0] + tbl[1]);\tnsect = au;\t/* Start of the root directory and number of sectors */\n\t\tdo {\t/* Fill root directory sectors */\n\t\t\tn = (nsect > sz_buf) ? sz_buf : nsect;\n\t\t\tif (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\tmem_set(buf, 0, ss);\n\t\t\tsect += n; nsect -= n;\n\t\t} while (nsect);\n\n\t\t/* Create two set of the exFAT VBR blocks */\n\t\tsect = b_vol;\n\t\tfor (n = 0; n < 2; n++) {\n\t\t\t/* Main record (+0) */\n\t\t\tmem_set(buf, 0, ss);\n\t\t\tmem_cpy(buf + BS_JmpBoot, \"\\xEB\\x76\\x90\" \"EXFAT   \", 11);\t/* Boot jump code (x86), OEM name */\n\t\t\tst_dword(buf + BPB_VolOfsEx, b_vol);\t\t\t\t\t/* Volume offset in the physical drive [sector] */\n\t\t\tst_dword(buf + BPB_TotSecEx, sz_vol);\t\t\t\t\t/* Volume size [sector] */\n\t\t\tst_dword(buf + BPB_FatOfsEx, b_fat - b_vol);\t\t\t/* FAT offset [sector] */\n\t\t\tst_dword(buf + BPB_FatSzEx, sz_fat);\t\t\t\t\t/* FAT size [sector] */\n\t\t\tst_dword(buf + BPB_DataOfsEx, b_data - b_vol);\t\t\t/* Data offset [sector] */\n\t\t\tst_dword(buf + BPB_NumClusEx, n_clst);\t\t\t\t\t/* Number of clusters */\n\t\t\tst_dword(buf + BPB_RootClusEx, 2 + tbl[0] + tbl[1]);\t/* Root dir cluster # */\n\t\t\tst_dword(buf + BPB_VolIDEx, GET_FATTIME());\t\t\t\t/* VSN */\n\t\t\tst_word(buf + BPB_FSVerEx, 0x100);\t\t\t\t\t\t/* Filesystem version (1.00) */\n\t\t\tfor (buf[BPB_BytsPerSecEx] = 0, i = ss; i >>= 1; buf[BPB_BytsPerSecEx]++) ;\t/* Log2 of sector size [byte] */\n\t\t\tfor (buf[BPB_SecPerClusEx] = 0, i = au; i >>= 1; buf[BPB_SecPerClusEx]++) ;\t/* Log2 of cluster size [sector] */\n\t\t\tbuf[BPB_NumFATsEx] = 1;\t\t\t\t\t/* Number of FATs */\n\t\t\tbuf[BPB_DrvNumEx] = 0x80;\t\t\t\t/* Drive number (for int13) */\n\t\t\tst_word(buf + BS_BootCodeEx, 0xFEEB);\t/* Boot code (x86) */\n\t\t\tst_word(buf + BS_55AA, 0xAA55);\t\t\t/* Signature (placed here regardless of sector size) */\n\t\t\tfor (i = sum = 0; i < ss; i++) {\t\t/* VBR checksum */\n\t\t\t\tif (i != BPB_VolFlagEx && i != BPB_VolFlagEx + 1 && i != BPB_PercInUseEx) sum = xsum32(buf[i], sum);\n\t\t\t}\n\t\t\tif (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\t/* Extended bootstrap record (+1..+8) */\n\t\t\tmem_set(buf, 0, ss);\n\t\t\tst_word(buf + ss - 2, 0xAA55);\t/* Signature (placed at end of sector) */\n\t\t\tfor (j = 1; j < 9; j++) {\n\t\t\t\tfor (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ;\t/* VBR checksum */\n\t\t\t\tif (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\t}\n\t\t\t/* OEM/Reserved record (+9..+10) */\n\t\t\tmem_set(buf, 0, ss);\n\t\t\tfor ( ; j < 11; j++) {\n\t\t\t\tfor (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ;\t/* VBR checksum */\n\t\t\t\tif (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\t}\n\t\t\t/* Sum record (+11) */\n\t\t\tfor (i = 0; i < ss; i += 4) st_dword(buf + i, sum);\t\t/* Fill with checksum value */\n\t\t\tif (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t}\n\n\t} else\n#endif\t/* FF_FS_EXFAT */\n\t{\t/* Create an FAT/FAT32 volume */\n\t\tdo {\n\t\t\tpau = au;\n\t\t\t/* Pre-determine number of clusters and FAT sub-type */\n\t\t\tif (fmt == FS_FAT32) {\t/* FAT32 volume */\n\t\t\t\tif (pau == 0) {\t/* au auto-selection */\n\t\t\t\t\tn = sz_vol / 0x20000;\t/* Volume size in unit of 128KS */\n\t\t\t\t\tfor (i = 0, pau = 1; cst32[i] && cst32[i] <= n; i++, pau <<= 1) ;\t/* Get from table */\n\t\t\t\t}\n\t\t\t\tn_clst = sz_vol / pau;\t/* Number of clusters */\n\t\t\t\tsz_fat = (n_clst * 4 + 8 + ss - 1) / ss;\t/* FAT size [sector] */\n\t\t\t\tsz_rsv = 32;\t/* Number of reserved sectors */\n\t\t\t\tsz_dir = 0;\t\t/* No static directory */\n\t\t\t\tif (n_clst <= MAX_FAT16 || n_clst > MAX_FAT32) LEAVE_MKFS(FR_MKFS_ABORTED);\n\t\t\t} else {\t\t\t\t/* FAT volume */\n\t\t\t\tif (pau == 0) {\t/* au auto-selection */\n\t\t\t\t\tn = sz_vol / 0x1000;\t/* Volume size in unit of 4KS */\n\t\t\t\t\tfor (i = 0, pau = 1; cst[i] && cst[i] <= n; i++, pau <<= 1) ;\t/* Get from table */\n\t\t\t\t}\n\t\t\t\tn_clst = sz_vol / pau;\n\t\t\t\tif (n_clst > MAX_FAT12) {\n\t\t\t\t\tn = n_clst * 2 + 4;\t\t/* FAT size [byte] */\n\t\t\t\t} else {\n\t\t\t\t\tfmt = FS_FAT12;\n\t\t\t\t\tn = (n_clst * 3 + 1) / 2 + 3;\t/* FAT size [byte] */\n\t\t\t\t}\n\t\t\t\tsz_fat = (n + ss - 1) / ss;\t\t/* FAT size [sector] */\n\t\t\t\tsz_rsv = 1;\t\t\t\t\t\t/* Number of reserved sectors */\n\t\t\t\tsz_dir = (DWORD)n_rootdir * SZDIRE / ss;\t/* Rootdir size [sector] */\n\t\t\t}\n\t\t\tb_fat = b_vol + sz_rsv;\t\t\t\t\t\t/* FAT base */\n\t\t\tb_data = b_fat + sz_fat * n_fats + sz_dir;\t/* Data base */\n\n\t\t\t/* Align data base to erase block boundary (for flash memory media) */\n\t\t\tn = ((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data;\t/* Next nearest erase block from current data base */\n\t\t\tif (fmt == FS_FAT32) {\t\t/* FAT32: Move FAT base */\n\t\t\t\tsz_rsv += n; b_fat += n;\n\t\t\t} else {\t\t\t\t\t/* FAT: Expand FAT size */\n\t\t\t\tsz_fat += n / n_fats;\n\t\t\t}\n\n\t\t\t/* Determine number of clusters and final check of validity of the FAT sub-type */\n\t\t\tif (sz_vol < b_data + pau * 16 - b_vol) LEAVE_MKFS(FR_MKFS_ABORTED);\t/* Too small volume */\n\t\t\tn_clst = (sz_vol - sz_rsv - sz_fat * n_fats - sz_dir) / pau;\n\t\t\tif (fmt == FS_FAT32) {\n\t\t\t\tif (n_clst <= MAX_FAT16) {\t/* Too few clusters for FAT32 */\n\t\t\t\t\tif (au == 0 && (au = pau / 2) != 0) continue;\t/* Adjust cluster size and retry */\n\t\t\t\t\tLEAVE_MKFS(FR_MKFS_ABORTED);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (fmt == FS_FAT16) {\n\t\t\t\tif (n_clst > MAX_FAT16) {\t/* Too many clusters for FAT16 */\n\t\t\t\t\tif (au == 0 && (pau * 2) <= 64) {\n\t\t\t\t\t\tau = pau * 2; continue;\t\t/* Adjust cluster size and retry */\n\t\t\t\t\t}\n\t\t\t\t\tif ((opt & FM_FAT32)) {\n\t\t\t\t\t\tfmt = FS_FAT32; continue;\t/* Switch type to FAT32 and retry */\n\t\t\t\t\t}\n\t\t\t\t\tif (au == 0 && (au = pau * 2) <= 128) continue;\t/* Adjust cluster size and retry */\n\t\t\t\t\tLEAVE_MKFS(FR_MKFS_ABORTED);\n\t\t\t\t}\n\t\t\t\tif  (n_clst <= MAX_FAT12) {\t/* Too few clusters for FAT16 */\n\t\t\t\t\tif (au == 0 && (au = pau * 2) <= 128) continue;\t/* Adjust cluster size and retry */\n\t\t\t\t\tLEAVE_MKFS(FR_MKFS_ABORTED);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (fmt == FS_FAT12 && n_clst > MAX_FAT12) LEAVE_MKFS(FR_MKFS_ABORTED);\t/* Too many clusters for FAT12 */\n\n\t\t\t/* Ok, it is the valid cluster configuration */\n\t\t\tbreak;\n\t\t} while (1);\n\n#if FF_USE_TRIM\n\t\ttbl[0] = b_vol; tbl[1] = b_vol + sz_vol - 1;\t/* Inform the device the volume area can be erased */\n\t\tdisk_ioctl(pdrv, CTRL_TRIM, tbl);\n#endif\n\t\t/* Create FAT VBR */\n\t\tmem_set(buf, 0, ss);\n\t\tmem_cpy(buf + BS_JmpBoot, \"\\xEB\\xFE\\x90\" \"MSDOS5.0\", 11);/* Boot jump code (x86), OEM name */\n\t\tst_word(buf + BPB_BytsPerSec, ss);\t\t\t\t/* Sector size [byte] */\n\t\tbuf[BPB_SecPerClus] = (BYTE)pau;\t\t\t\t/* Cluster size [sector] */\n\t\tst_word(buf + BPB_RsvdSecCnt, (WORD)sz_rsv);\t/* Size of reserved area */\n\t\tbuf[BPB_NumFATs] = (BYTE)n_fats;\t\t\t\t/* Number of FATs */\n\t\tst_word(buf + BPB_RootEntCnt, (WORD)((fmt == FS_FAT32) ? 0 : n_rootdir));\t/* Number of root directory entries */\n\t\tif (sz_vol < 0x10000) {\n\t\t\tst_word(buf + BPB_TotSec16, (WORD)sz_vol);\t/* Volume size in 16-bit LBA */\n\t\t} else {\n\t\t\tst_dword(buf + BPB_TotSec32, sz_vol);\t\t/* Volume size in 32-bit LBA */\n\t\t}\n\t\tbuf[BPB_Media] = 0xF8;\t\t\t\t\t\t\t/* Media descriptor byte */\n\t\tst_word(buf + BPB_SecPerTrk, 63);\t\t\t\t/* Number of sectors per track (for int13) */\n\t\tst_word(buf + BPB_NumHeads, 255);\t\t\t\t/* Number of heads (for int13) */\n\t\tst_dword(buf + BPB_HiddSec, b_vol);\t\t\t\t/* Volume offset in the physical drive [sector] */\n\t\tif (fmt == FS_FAT32) {\n\t\t\tst_dword(buf + BS_VolID32, GET_FATTIME());\t/* VSN */\n\t\t\tst_dword(buf + BPB_FATSz32, sz_fat);\t\t/* FAT size [sector] */\n\t\t\tst_dword(buf + BPB_RootClus32, 2);\t\t\t/* Root directory cluster # (2) */\n\t\t\tst_word(buf + BPB_FSInfo32, 1);\t\t\t\t/* Offset of FSINFO sector (VBR + 1) */\n\t\t\tst_word(buf + BPB_BkBootSec32, 6);\t\t\t/* Offset of backup VBR (VBR + 6) */\n\t\t\tbuf[BS_DrvNum32] = 0x80;\t\t\t\t\t/* Drive number (for int13) */\n\t\t\tbuf[BS_BootSig32] = 0x29;\t\t\t\t\t/* Extended boot signature */\n\t\t\tmem_cpy(buf + BS_VolLab32, \"NO NAME    \" \"FAT32   \", 19);\t/* Volume label, FAT signature */\n\t\t} else {\n\t\t\tst_dword(buf + BS_VolID, GET_FATTIME());\t/* VSN */\n\t\t\tst_word(buf + BPB_FATSz16, (WORD)sz_fat);\t/* FAT size [sector] */\n\t\t\tbuf[BS_DrvNum] = 0x80;\t\t\t\t\t\t/* Drive number (for int13) */\n\t\t\tbuf[BS_BootSig] = 0x29;\t\t\t\t\t\t/* Extended boot signature */\n\t\t\tmem_cpy(buf + BS_VolLab, \"NO NAME    \" \"FAT     \", 19);\t/* Volume label, FAT signature */\n\t\t}\n\t\tst_word(buf + BS_55AA, 0xAA55);\t\t\t\t\t/* Signature (offset is fixed here regardless of sector size) */\n\t\tif (disk_write(pdrv, buf, b_vol, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\t/* Write it to the VBR sector */\n\n\t\t/* Create FSINFO record if needed */\n\t\tif (fmt == FS_FAT32) {\n\t\t\tdisk_write(pdrv, buf, b_vol + 6, 1);\t\t/* Write backup VBR (VBR + 6) */\n\t\t\tmem_set(buf, 0, ss);\n\t\t\tst_dword(buf + FSI_LeadSig, 0x41615252);\n\t\t\tst_dword(buf + FSI_StrucSig, 0x61417272);\n\t\t\tst_dword(buf + FSI_Free_Count, n_clst - 1);\t/* Number of free clusters */\n\t\t\tst_dword(buf + FSI_Nxt_Free, 2);\t\t\t/* Last allocated cluster# */\n\t\t\tst_word(buf + BS_55AA, 0xAA55);\n\t\t\tdisk_write(pdrv, buf, b_vol + 7, 1);\t\t/* Write backup FSINFO (VBR + 7) */\n\t\t\tdisk_write(pdrv, buf, b_vol + 1, 1);\t\t/* Write original FSINFO (VBR + 1) */\n\t\t}\n\n\t\t/* Initialize FAT area */\n\t\tmem_set(buf, 0, (UINT)szb_buf);\n\t\tsect = b_fat;\t\t/* FAT start sector */\n\t\tfor (i = 0; i < n_fats; i++) {\t\t\t/* Initialize FATs each */\n\t\t\tif (fmt == FS_FAT32) {\n\t\t\t\tst_dword(buf + 0, 0xFFFFFFF8);\t/* Entry 0 */\n\t\t\t\tst_dword(buf + 4, 0xFFFFFFFF);\t/* Entry 1 */\n\t\t\t\tst_dword(buf + 8, 0x0FFFFFFF);\t/* Entry 2 (root directory) */\n\t\t\t} else {\n\t\t\t\tst_dword(buf + 0, (fmt == FS_FAT12) ? 0xFFFFF8 : 0xFFFFFFF8);\t/* Entry 0 and 1 */\n\t\t\t}\n\t\t\tnsect = sz_fat;\t\t/* Number of FAT sectors */\n\t\t\tdo {\t/* Fill FAT sectors */\n\t\t\t\tn = (nsect > sz_buf) ? sz_buf : nsect;\n\t\t\t\tif (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\t\tmem_set(buf, 0, ss);\n\t\t\t\tsect += n; nsect -= n;\n\t\t\t} while (nsect);\n\t\t}\n\n\t\t/* Initialize root directory (fill with zero) */\n\t\tnsect = (fmt == FS_FAT32) ? pau : sz_dir;\t/* Number of root directory sectors */\n\t\tdo {\n\t\t\tn = (nsect > sz_buf) ? sz_buf : nsect;\n\t\t\tif (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\tsect += n; nsect -= n;\n\t\t} while (nsect);\n\t}\n\n\t/* Determine system ID in the partition table */\n\tif (FF_FS_EXFAT && fmt == FS_EXFAT) {\n\t\tsys = 0x07;\t\t\t/* HPFS/NTFS/exFAT */\n\t} else {\n\t\tif (fmt == FS_FAT32) {\n\t\t\tsys = 0x0C;\t\t/* FAT32X */\n\t\t} else {\n\t\t\tif (sz_vol >= 0x10000) {\n\t\t\t\tsys = 0x06;\t/* FAT12/16 (large) */\n\t\t\t} else {\n\t\t\t\tsys = (fmt == FS_FAT16) ? 0x04 : 0x01;\t/* FAT16 : FAT12 */\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Update partition information */\n\tif (FF_MULTI_PARTITION && part != 0) {\t/* Created in the existing partition */\n\t\t/* Update system ID in the partition table */\n\t\tif (disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\t/* Read the MBR */\n\t\tbuf[MBR_Table + (part - 1) * SZ_PTE + PTE_System] = sys;\t\t/* Set system ID */\n\t\tif (disk_write(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\t/* Write it back to the MBR */\n\t} else {\t\t\t\t\t\t\t\t/* Created as a new single partition */\n\t\tif (!(opt & FM_SFD)) {\t/* Create partition table if in FDISK format */\n\t\t\tmem_set(buf, 0, ss);\n\t\t\tst_word(buf + BS_55AA, 0xAA55);\t\t/* MBR signature */\n\t\t\tpte = buf + MBR_Table;\t\t\t\t/* Create partition table for single partition in the drive */\n\t\t\tpte[PTE_Boot] = 0;\t\t\t\t\t/* Boot indicator */\n\t\t\tpte[PTE_StHead] = 1;\t\t\t\t/* Start head */\n\t\t\tpte[PTE_StSec] = 1;\t\t\t\t\t/* Start sector */\n\t\t\tpte[PTE_StCyl] = 0;\t\t\t\t\t/* Start cylinder */\n\t\t\tpte[PTE_System] = sys;\t\t\t\t/* System type */\n\t\t\tn = (b_vol + sz_vol) / (63 * 255);\t/* (End CHS may be invalid) */\n\t\t\tpte[PTE_EdHead] = 254;\t\t\t\t/* End head */\n\t\t\tpte[PTE_EdSec] = (BYTE)(((n >> 2) & 0xC0) | 63);\t/* End sector */\n\t\t\tpte[PTE_EdCyl] = (BYTE)n;\t\t\t/* End cylinder */\n\t\t\tst_dword(pte + PTE_StLba, b_vol);\t/* Start offset in LBA */\n\t\t\tst_dword(pte + PTE_SizLba, sz_vol);\t/* Size in sectors */\n\t\t\tif (disk_write(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\t/* Write it to the MBR */\n\t\t}\n\t}\n\n\tif (disk_ioctl(pdrv, CTRL_SYNC, 0) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\n\tLEAVE_MKFS(FR_OK);\n}\n\n\n\n#if FF_MULTI_PARTITION\n/*-----------------------------------------------------------------------*/\n/* Create Partition Table on the Physical Drive                          */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_fdisk (\n\tBYTE pdrv,\t\t\t/* Physical drive number */\n\tconst DWORD* szt,\t/* Pointer to the size table for each partitions */\n\tvoid* work\t\t\t/* Pointer to the working buffer (null: use heap memory) */\n)\n{\n\tUINT i, n, sz_cyl, tot_cyl, b_cyl, e_cyl, p_cyl;\n\tBYTE s_hd, e_hd, *p, *buf = (BYTE*)work;\n\tDSTATUS stat;\n\tDWORD sz_disk, sz_part, s_part;\n\tFRESULT res;\n\n\n\tstat = disk_initialize(pdrv);\n\tif (stat & STA_NOINIT) return FR_NOT_READY;\n\tif (stat & STA_PROTECT) return FR_WRITE_PROTECTED;\n\tif (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_disk)) return FR_DISK_ERR;\n\n\tbuf = (BYTE*)work;\n#if FF_USE_LFN == 3\n\tif (!buf) buf = ff_memalloc(FF_MAX_SS);\t/* Use heap memory for working buffer */\n#endif\n\tif (!buf) return FR_NOT_ENOUGH_CORE;\n\n\t/* Determine the CHS without any consideration of the drive geometry */\n\tfor (n = 16; n < 256 && sz_disk / n / 63 > 1024; n *= 2) ;\n\tif (n == 256) n--;\n\te_hd = (BYTE)(n - 1);\n\tsz_cyl = 63 * n;\n\ttot_cyl = sz_disk / sz_cyl;\n\n\t/* Create partition table */\n\tmem_set(buf, 0, FF_MAX_SS);\n\tp = buf + MBR_Table; b_cyl = 0;\n\tfor (i = 0; i < 4; i++, p += SZ_PTE) {\n\t\tp_cyl = (szt[i] <= 100U) ? (DWORD)tot_cyl * szt[i] / 100 : szt[i] / sz_cyl;\t/* Number of cylinders */\n\t\tif (p_cyl == 0) continue;\n\t\ts_part = (DWORD)sz_cyl * b_cyl;\n\t\tsz_part = (DWORD)sz_cyl * p_cyl;\n\t\tif (i == 0) {\t/* Exclude first track of cylinder 0 */\n\t\t\ts_hd = 1;\n\t\t\ts_part += 63; sz_part -= 63;\n\t\t} else {\n\t\t\ts_hd = 0;\n\t\t}\n\t\te_cyl = b_cyl + p_cyl - 1;\t/* End cylinder */\n\t\tif (e_cyl >= tot_cyl) LEAVE_MKFS(FR_INVALID_PARAMETER);\n\n\t\t/* Set partition table */\n\t\tp[1] = s_hd;\t\t\t\t\t\t/* Start head */\n\t\tp[2] = (BYTE)(((b_cyl >> 2) & 0xC0) | 1);\t/* Start sector */\n\t\tp[3] = (BYTE)b_cyl;\t\t\t\t\t/* Start cylinder */\n\t\tp[4] = 0x07;\t\t\t\t\t\t/* System type (temporary setting) */\n\t\tp[5] = e_hd;\t\t\t\t\t\t/* End head */\n\t\tp[6] = (BYTE)(((e_cyl >> 2) & 0xC0) | 63);\t/* End sector */\n\t\tp[7] = (BYTE)e_cyl;\t\t\t\t\t/* End cylinder */\n\t\tst_dword(p + 8, s_part);\t\t\t/* Start sector in LBA */\n\t\tst_dword(p + 12, sz_part);\t\t\t/* Number of sectors */\n\n\t\t/* Next partition */\n\t\tb_cyl += p_cyl;\n\t}\n\tst_word(p, 0xAA55);\t\t/* MBR signature (always at offset 510) */\n\n\t/* Write it to the MBR */\n\tres = (disk_write(pdrv, buf, 0, 1) == RES_OK && disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR;\n\tLEAVE_MKFS(res);\n}\n\n#endif /* FF_MULTI_PARTITION */\n#endif /* FF_USE_MKFS && !FF_FS_READONLY */\n\n\n\n\n#if FF_USE_STRFUNC\n#if FF_USE_LFN && FF_LFN_UNICODE && (FF_STRF_ENCODE < 0 || FF_STRF_ENCODE > 3)\n#error Wrong FF_STRF_ENCODE setting\n#endif\n/*-----------------------------------------------------------------------*/\n/* Get a String from the File                                            */\n/*-----------------------------------------------------------------------*/\n\nTCHAR* f_gets (\n\tTCHAR* buff,\t/* Pointer to the string buffer to read */\n\tint len,\t\t/* Size of string buffer (items) */\n\tFIL* fp\t\t\t/* Pointer to the file object */\n)\n{\n\tint nc = 0;\n\tTCHAR *p = buff;\n\tBYTE s[4];\n\tUINT rc;\n\tDWORD dc;\n#if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE <= 2\n\tWCHAR wc;\n#endif\n#if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE == 3\n\tUINT ct;\n#endif\n\n#if FF_USE_LFN && FF_LFN_UNICODE\t\t\t/* With code conversion (Unicode API) */\n\t/* Make a room for the character and terminator  */\n\tif (FF_LFN_UNICODE == 1) len -= (FF_STRF_ENCODE == 0) ? 1 : 2;\n\tif (FF_LFN_UNICODE == 2) len -= (FF_STRF_ENCODE == 0) ? 3 : 4;\n\tif (FF_LFN_UNICODE == 3) len -= 1;\n\twhile (nc < len) {\n#if FF_STRF_ENCODE == 0\t\t/* Read a character in ANSI/OEM */\n\t\tf_read(fp, s, 1, &rc);\n\t\tif (rc != 1) break;\n\t\twc = s[0];\n\t\tif (dbc_1st((BYTE)wc)) {\n\t\t\tf_read(fp, s, 1, &rc);\n\t\t\tif (rc != 1 || !dbc_2nd(s[0])) continue;\n\t\t\twc = wc << 8 | s[0];\n\t\t}\n\t\tdc = ff_oem2uni(wc, CODEPAGE);\n\t\tif (dc == 0) continue;\n#elif FF_STRF_ENCODE == 1 || FF_STRF_ENCODE == 2 \t/* Read a character in UTF-16LE/BE */\n\t\tf_read(fp, s, 2, &rc);\n\t\tif (rc != 2) break;\n\t\tdc = (FF_STRF_ENCODE == 1) ? ld_word(s) : s[0] << 8 | s[1];\n\t\tif (IsSurrogateL(dc)) continue;\n\t\tif (IsSurrogateH(dc)) {\n\t\t\tf_read(fp, s, 2, &rc);\n\t\t\tif (rc != 2) break;\n\t\t\twc = (FF_STRF_ENCODE == 1) ? ld_word(s) : s[0] << 8 | s[1];\n\t\t\tif (!IsSurrogateL(wc)) continue;\n\t\t\tdc = ((dc & 0x3FF) + 0x40) << 10 | (wc & 0x3FF);\n\t\t}\n#else\t/* Read a character in UTF-8 */\n\t\tf_read(fp, s, 1, &rc);\n\t\tif (rc != 1) break;\n\t\tdc = s[0];\n\t\tif (dc >= 0x80) {\t/* Multi-byte character? */\n\t\t\tct = 0;\n\t\t\tif ((dc & 0xE0) == 0xC0) { dc &= 0x1F; ct = 1; }\t/* 2-byte? */\n\t\t\tif ((dc & 0xF0) == 0xE0) { dc &= 0x0F; ct = 2; }\t/* 3-byte? */\n\t\t\tif ((dc & 0xF8) == 0xF0) { dc &= 0x07; ct = 3; }\t/* 4-byte? */\n\t\t\tif (ct == 0) continue;\n\t\t\tf_read(fp, s, ct, &rc);\t\t/* Get trailing bytes */\n\t\t\tif (rc != ct) break;\n\t\t\trc = 0;\n\t\t\tdo {\t/* Merge trailing bytes */\n\t\t\t\tif ((s[rc] & 0xC0) != 0x80) break;\n\t\t\t\tdc = dc << 6 | (s[rc] & 0x3F);\n\t\t\t} while (++rc < ct);\n\t\t\tif (rc != ct || dc < 0x80 || IsSurrogate(dc) || dc >= 0x110000) continue;\t/* Wrong encoding? */\n\t\t}\n#endif\n\t\tif (FF_USE_STRFUNC == 2 && dc == '\\r') continue;\t/* Strip \\r off if needed */\n#if FF_LFN_UNICODE == 1\t|| FF_LFN_UNICODE == 3\t/* Output it in UTF-16/32 encoding */\n\t\tif (FF_LFN_UNICODE == 1 && dc >= 0x10000) {\t/* Out of BMP at UTF-16? */\n\t\t\t*p++ = (TCHAR)(0xD800 | ((dc >> 10) - 0x40)); nc++;\t/* Make and output high surrogate */\n\t\t\tdc = 0xDC00 | (dc & 0x3FF);\t\t/* Make low surrogate */\n\t\t}\n\t\t*p++ = (TCHAR)dc; nc++;\n\t\tif (dc == '\\n') break;\t/* End of line? */\n#elif FF_LFN_UNICODE == 2\t\t/* Output it in UTF-8 encoding */\n\t\tif (dc < 0x80) {\t/* 1-byte */\n\t\t\t*p++ = (TCHAR)dc;\n\t\t\tnc++;\n\t\t\tif (dc == '\\n') break;\t/* End of line? */\n\t\t} else {\n\t\t\tif (dc < 0x800) {\t\t/* 2-byte */\n\t\t\t\t*p++ = (TCHAR)(0xC0 | (dc >> 6 & 0x1F));\n\t\t\t\t*p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F));\n\t\t\t\tnc += 2;\n\t\t\t} else {\n\t\t\t\tif (dc < 0x10000) {\t/* 3-byte */\n\t\t\t\t\t*p++ = (TCHAR)(0xE0 | (dc >> 12 & 0x0F));\n\t\t\t\t\t*p++ = (TCHAR)(0x80 | (dc >> 6 & 0x3F));\n\t\t\t\t\t*p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F));\n\t\t\t\t\tnc += 3;\n\t\t\t\t} else {\t\t\t/* 4-byte */\n\t\t\t\t\t*p++ = (TCHAR)(0xF0 | (dc >> 18 & 0x07));\n\t\t\t\t\t*p++ = (TCHAR)(0x80 | (dc >> 12 & 0x3F));\n\t\t\t\t\t*p++ = (TCHAR)(0x80 | (dc >> 6 & 0x3F));\n\t\t\t\t\t*p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F));\n\t\t\t\t\tnc += 4;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n#endif\n\t}\n\n#else\t\t\t/* Byte-by-byte without any conversion (ANSI/OEM API) */\n\tlen -= 1;\t/* Make a room for the terminator */\n\twhile (nc < len) {\n\t\tf_read(fp, s, 1, &rc);\n\t\tif (rc != 1) break;\n\t\tdc = s[0];\n\t\tif (FF_USE_STRFUNC == 2 && dc == '\\r') continue;\n\t\t*p++ = (TCHAR)dc; nc++;\n\t\tif (dc == '\\n') break;\n\t}\n#endif\n\n\t*p = 0;\t\t/* Terminate the string */\n\treturn nc ? buff : 0;\t/* When no data read due to EOF or error, return with error. */\n}\n\n\n\n\n#if !FF_FS_READONLY\n#include <stdarg.h>\n/*-----------------------------------------------------------------------*/\n/* Put a Character to the File                                           */\n/*-----------------------------------------------------------------------*/\n\ntypedef struct {\t/* Putchar output buffer and work area */\n\tFIL *fp;\t\t/* Ptr to the writing file */\n\tint idx, nchr;\t/* Write index of buf[] (-1:error), number of encoding units written */\n#if FF_USE_LFN && FF_LFN_UNICODE == 1\n\tWCHAR hs;\n#elif FF_USE_LFN && FF_LFN_UNICODE == 2\n\tBYTE bs[4];\n\tUINT wi, ct;\n#endif\n\tBYTE buf[64];\t/* Write buffer */\n} putbuff;\n\n\nstatic void putc_bfd (\t\t/* Buffered write with code conversion */\n\tputbuff* pb,\n\tTCHAR c\n)\n{\n\tUINT n;\n\tint i, nc;\n#if FF_USE_LFN && FF_LFN_UNICODE\n\tWCHAR hs, wc;\n#if FF_LFN_UNICODE == 2\n\tDWORD dc;\n\tTCHAR *tp;\n#endif\n#endif\n\n\tif (FF_USE_STRFUNC == 2 && c == '\\n') {\t /* LF -> CRLF conversion */\n\t\tputc_bfd(pb, '\\r');\n\t}\n\n\ti = pb->idx;\t\t\t/* Write index of pb->buf[] */\n\tif (i < 0) return;\n\tnc = pb->nchr;\t\t\t/* Write unit counter */\n\n#if FF_USE_LFN && FF_LFN_UNICODE\n#if FF_LFN_UNICODE == 1\t\t/* UTF-16 input */\n\tif (IsSurrogateH(c)) {\n\t\tpb->hs = c; return;\n\t}\n\ths = pb->hs; pb->hs = 0;\n\tif (hs != 0) {\n\t\tif (!IsSurrogateL(c)) hs = 0;\n\t} else {\n\t\tif (IsSurrogateL(c)) return;\n\t}\n\twc = c;\n#elif FF_LFN_UNICODE == 2\t/* UTF-8 input */\n\tfor (;;) {\n\t\tif (pb->ct == 0) {\t/* Out of multi-byte sequence? */\n\t\t\tpb->bs[pb->wi = 0] = (BYTE)c;\t/* Save 1st byte */\n\t\t\tif ((BYTE)c < 0x80) break;\t\t\t\t\t/* 1-byte? */\n\t\t\tif (((BYTE)c & 0xE0) == 0xC0) pb->ct = 1;\t/* 2-byte? */\n\t\t\tif (((BYTE)c & 0xF0) == 0xE0) pb->ct = 2;\t/* 3-byte? */\n\t\t\tif (((BYTE)c & 0xF1) == 0xF0) pb->ct = 3;\t/* 4-byte? */\n\t\t\treturn;\n\t\t} else {\t\t\t\t/* In the multi-byte sequence */\n\t\t\tif (((BYTE)c & 0xC0) != 0x80) {\t/* Broken sequence? */\n\t\t\t\tpb->ct = 0; continue;\n\t\t\t}\n\t\t\tpb->bs[++pb->wi] = (BYTE)c;\t/* Save the trailing byte */\n\t\t\tif (--pb->ct == 0) break;\t/* End of multi-byte sequence? */\n\t\t\treturn;\n\t\t}\n\t}\n\ttp = (TCHAR*)pb->bs;\n\tdc = tchar2uni(&tp);\t/* UTF-8 ==> UTF-16 */\n\tif (dc == 0xFFFFFFFF) return;\n\twc = (WCHAR)dc;\n\ths = (WCHAR)(dc >> 16);\n#elif FF_LFN_UNICODE == 3\t/* UTF-32 input */\n\tif (IsSurrogate(c) || c >= 0x110000) return;\n\tif (c >= 0x10000) {\n\t\ths = (WCHAR)(0xD800 | ((c >> 10) - 0x40)); \t/* Make high surrogate */\n\t\twc = 0xDC00 | (c & 0x3FF);\t\t\t\t\t/* Make low surrogate */\n\t} else {\n\t\ths = 0;\n\t\twc = (WCHAR)c;\n\t}\n#endif\n\n#if FF_STRF_ENCODE == 1\t\t/* Write a character in UTF-16LE */\n\tif (hs != 0) {\n\t\tst_word(&pb->buf[i], hs);\n\t\ti += 2;\n\t\tnc++;\n\t}\n\tst_word(&pb->buf[i], wc);\n\ti += 2;\n#elif FF_STRF_ENCODE == 2\t/* Write a character in UTF-16BE */\n\tif (hs != 0) {\n\t\tpb->buf[i++] = (BYTE)(hs >> 8);\n\t\tpb->buf[i++] = (BYTE)hs;\n\t\tnc++;\n\t}\n\tpb->buf[i++] = (BYTE)(wc >> 8);\n\tpb->buf[i++] = (BYTE)wc;\n#elif FF_STRF_ENCODE == 3\t/* Write it in UTF-8 */\n\tif (hs != 0) {\t\t\t\t/* 4-byte */\n\t\tnc += 3;\n\t\ths = (hs & 0x3FF) + 0x40;\n\t\tpb->buf[i++] = (BYTE)(0xF0 | hs >> 8);\n\t\tpb->buf[i++] = (BYTE)(0x80 | (hs >> 2 & 0x3F));\n\t\tpb->buf[i++] = (BYTE)(0x80 | (hs & 3) << 4 | (wc >> 6 & 0x0F));\n\t\tpb->buf[i++] = (BYTE)(0x80 | (wc & 0x3F));\n\t} else {\n\t\tif (wc < 0x80) {\t\t/* 1-byte */\n\t\t\tpb->buf[i++] = (BYTE)wc;\n\t\t} else {\n\t\t\tif (wc < 0x800) {\t/* 2-byte */\n\t\t\t\tnc += 1;\n\t\t\t\tpb->buf[i++] = (BYTE)(0xC0 | wc >> 6);\n\t\t\t} else {\t\t\t/* 3-byte */\n\t\t\t\tnc += 2;\n\t\t\t\tpb->buf[i++] = (BYTE)(0xE0 | wc >> 12);\n\t\t\t\tpb->buf[i++] = (BYTE)(0x80 | (wc >> 6 & 0x3F));\n\t\t\t}\n\t\t\tpb->buf[i++] = (BYTE)(0x80 | (wc & 0x3F));\n\t\t}\n\t}\n#else\t\t\t\t\t\t/* Write it in ANSI/OEM */\n\tif (hs != 0) return;\n\twc = ff_uni2oem(wc, CODEPAGE);\t/* UTF-16 ==> ANSI/OEM */\n\tif (wc == 0) return;\n\tif (wc >= 0x100) {\n\t\tpb->buf[i++] = (BYTE)(wc >> 8); nc++;\n\t}\n\tpb->buf[i++] = (BYTE)wc;\n#endif\n\n#else\t\t\t\t\t\t\t\t\t/* ANSI/OEM input (without re-encode) */\n\tpb->buf[i++] = (BYTE)c;\n#endif\n\n\tif (i >= (int)(sizeof pb->buf) - 4) {\t/* Write buffered characters to the file */\n\t\tf_write(pb->fp, pb->buf, (UINT)i, &n);\n\t\ti = (n == (UINT)i) ? 0 : -1;\n\t}\n\tpb->idx = i;\n\tpb->nchr = nc + 1;\n}\n\n\nstatic int putc_flush (\t\t/* Flush left characters in the buffer */\n\tputbuff* pb\n)\n{\n\tUINT nw;\n\n\tif (   pb->idx >= 0\t/* Flush buffered characters to the file */\n\t\t&& f_write(pb->fp, pb->buf, (UINT)pb->idx, &nw) == FR_OK\n\t\t&& (UINT)pb->idx == nw) return pb->nchr;\n\treturn EOF;\n}\n\n\nstatic void putc_init (\t\t/* Initialize write buffer */\n\tputbuff* pb,\n\tFIL* fp\n)\n{\n\tmem_set(pb, 0, sizeof (putbuff));\n\tpb->fp = fp;\n}\n\n\n\nint f_putc (\n\tTCHAR c,\t/* A character to be output */\n\tFIL* fp\t\t/* Pointer to the file object */\n)\n{\n\tputbuff pb;\n\n\n\tputc_init(&pb, fp);\n\tputc_bfd(&pb, c);\t/* Put the character */\n\treturn putc_flush(&pb);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Put a String to the File                                              */\n/*-----------------------------------------------------------------------*/\n\nint f_puts (\n\tconst TCHAR* str,\t/* Pointer to the string to be output */\n\tFIL* fp\t\t\t\t/* Pointer to the file object */\n)\n{\n\tputbuff pb;\n\n\n\tputc_init(&pb, fp);\n\twhile (*str) putc_bfd(&pb, *str++);\t\t/* Put the string */\n\treturn putc_flush(&pb);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Put a Formatted String to the File                                    */\n/*-----------------------------------------------------------------------*/\n\nint f_printf (\n\tFIL* fp,\t\t\t/* Pointer to the file object */\n\tconst TCHAR* fmt,\t/* Pointer to the format string */\n\t...\t\t\t\t\t/* Optional arguments... */\n)\n{\n\tva_list arp;\n\tputbuff pb;\n\tBYTE f, r;\n\tUINT i, j, w;\n\tDWORD v;\n\tTCHAR c, d, str[32], *p;\n\n\n\tputc_init(&pb, fp);\n\n\tva_start(arp, fmt);\n\n\tfor (;;) {\n\t\tc = *fmt++;\n\t\tif (c == 0) break;\t\t\t/* End of string */\n\t\tif (c != '%') {\t\t\t\t/* Non escape character */\n\t\t\tputc_bfd(&pb, c);\n\t\t\tcontinue;\n\t\t}\n\t\tw = f = 0;\n\t\tc = *fmt++;\n\t\tif (c == '0') {\t\t\t\t/* Flag: '0' padding */\n\t\t\tf = 1; c = *fmt++;\n\t\t} else {\n\t\t\tif (c == '-') {\t\t\t/* Flag: left justified */\n\t\t\t\tf = 2; c = *fmt++;\n\t\t\t}\n\t\t}\n\t\tif (c == '*') {\t\t\t\t/* Minimum width by argument */\n\t\t\tw = va_arg(arp, int);\n\t\t\tc = *fmt++;\n\t\t} else {\n\t\t\twhile (IsDigit(c)) {\t/* Minimum width */\n\t\t\t\tw = w * 10 + c - '0';\n\t\t\t\tc = *fmt++;\n\t\t\t}\n\t\t}\n\t\tif (c == 'l' || c == 'L') {\t/* Type prefix: Size is long int */\n\t\t\tf |= 4; c = *fmt++;\n\t\t}\n\t\tif (c == 0) break;\n\t\td = c;\n\t\tif (IsLower(d)) d -= 0x20;\n\t\tswitch (d) {\t\t\t\t/* Atgument type is... */\n\t\tcase 'S' :\t\t\t\t\t/* String */\n\t\t\tp = va_arg(arp, TCHAR*);\n\t\t\tfor (j = 0; p[j]; j++) ;\n\t\t\tif (!(f & 2)) {\t\t\t\t\t\t/* Right padded */\n\t\t\t\twhile (j++ < w) putc_bfd(&pb, ' ') ;\n\t\t\t}\n\t\t\twhile (*p) putc_bfd(&pb, *p++) ;\t\t/* String body */\n\t\t\twhile (j++ < w) putc_bfd(&pb, ' ') ;\t/* Left padded */\n\t\t\tcontinue;\n\n\t\tcase 'C' :\t\t\t\t\t/* Character */\n\t\t\tputc_bfd(&pb, (TCHAR)va_arg(arp, int)); continue;\n\n\t\tcase 'B' :\t\t\t\t\t/* Unsigned binary */\n\t\t\tr = 2; break;\n\n\t\tcase 'O' :\t\t\t\t\t/* Unsigned octal */\n\t\t\tr = 8; break;\n\n\t\tcase 'D' :\t\t\t\t\t/* Signed decimal */\n\t\tcase 'U' :\t\t\t\t\t/* Unsigned decimal */\n\t\t\tr = 10; break;\n\n\t\tcase 'X' :\t\t\t\t\t/* Unsigned hexdecimal */\n\t\t\tr = 16; break;\n\n\t\tdefault:\t\t\t\t\t/* Unknown type (pass-through) */\n\t\t\tputc_bfd(&pb, c); continue;\n\t\t}\n\n\t\t/* Get an argument and put it in numeral */\n\t\tv = (f & 4) ? (DWORD)va_arg(arp, long) : ((d == 'D') ? (DWORD)(long)va_arg(arp, int) : (DWORD)va_arg(arp, unsigned int));\n\t\tif (d == 'D' && (v & 0x80000000)) {\n\t\t\tv = 0 - v;\n\t\t\tf |= 8;\n\t\t}\n\t\ti = 0;\n\t\tdo {\n\t\t\td = (TCHAR)(v % r); v /= r;\n\t\t\tif (d > 9) d += (c == 'x') ? 0x27 : 0x07;\n\t\t\tstr[i++] = d + '0';\n\t\t} while (v && i < sizeof str / sizeof *str);\n\t\tif (f & 8) str[i++] = '-';\n\t\tj = i; d = (f & 1) ? '0' : ' ';\n\t\tif (!(f & 2)) {\n\t\t\twhile (j++ < w) putc_bfd(&pb, d);\t/* Right pad */\n\t\t}\n\t\tdo {\n\t\t\tputc_bfd(&pb, str[--i]);\t\t\t/* Number body */\n\t\t} while (i);\n\t\twhile (j++ < w) putc_bfd(&pb, d);\t\t/* Left pad */\n\t}\n\n\tva_end(arp);\n\n\treturn putc_flush(&pb);\n}\n\n#endif /* !FF_FS_READONLY */\n#endif /* FF_USE_STRFUNC */\n\n\n\n#if FF_CODE_PAGE == 0\n/*-----------------------------------------------------------------------*/\n/* Set Active Codepage for the Path Name                                 */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_setcp (\n\tWORD cp\t\t/* Value to be set as active code page */\n)\n{\n\tstatic const WORD       validcp[] = {  437,   720,   737,   771,   775,   850,   852,   857,   860,   861,   862,   863,   864,   865,   866,   869,   932,   936,   949,   950, 0};\n\tstatic const BYTE* const tables[] = {Ct437, Ct720, Ct737, Ct771, Ct775, Ct850, Ct852, Ct857, Ct860, Ct861, Ct862, Ct863, Ct864, Ct865, Ct866, Ct869, Dc932, Dc936, Dc949, Dc950, 0};\n\tUINT i;\n\n\n\tfor (i = 0; validcp[i] != 0 && validcp[i] != cp; i++) ;\t/* Find the code page */\n\tif (validcp[i] != cp) return FR_INVALID_PARAMETER;\t/* Not found? */\n\n\tCodePage = cp;\n\tif (cp >= 900) {\t/* DBCS */\n\t\tExCvt = 0;\n\t\tDbcTbl = tables[i];\n\t} else {\t\t\t/* SBCS */\n\t\tExCvt = tables[i];\n\t\tDbcTbl = 0;\n\t}\n\treturn FR_OK;\n}\n#endif\t/* FF_CODE_PAGE == 0 */\n\n#pragma GCC pop_options\n"
  },
  {
    "path": "argon-first-stage/src/libs/fatfs/ffsystem.c",
    "content": "/*------------------------------------------------------------------------*/\n/* Sample Code of OS Dependent Functions for FatFs                        */\n/* (C) ChaN, 2018                                                          */\n/* (C) CTCaer, 2018                                                       */\n/*------------------------------------------------------------------------*/\n\n\n#include \"libs/fatfs/ff.h\"\n#include \"mem/heap.h\"\n\n\n\n#if FF_USE_LFN == 3\t/* Dynamic memory allocation */\n\n/*------------------------------------------------------------------------*/\n/* Allocate a memory block                                                */\n/*------------------------------------------------------------------------*/\n\nvoid* ff_memalloc (\t/* Returns pointer to the allocated memory block (null if not enough core) */\n\tUINT msize\t\t/* Number of bytes to allocate */\n)\n{\n\treturn malloc(msize);\t/* Allocate a new memory block with POSIX API */\n}\n\n\n/*------------------------------------------------------------------------*/\n/* Free a memory block                                                    */\n/*------------------------------------------------------------------------*/\n\nvoid ff_memfree (\n\tvoid* mblock\t/* Pointer to the memory block to free (nothing to do if null) */\n)\n{\n\tfree(mblock);\t/* Free the memory block with POSIX API */\n}\n\n#endif\n\n"
  },
  {
    "path": "argon-first-stage/src/libs/fatfs/ffunicode.c",
    "content": "/*------------------------------------------------------------------------*/\n/* Unicode handling functions for FatFs R0.13c                            */\n/*------------------------------------------------------------------------*/\n/* This module will occupy a huge memory in the .const section when the    /\n/  FatFs is configured for LFN with DBCS. If the system has any Unicode    /\n/  utilitiy for the code conversion, this module should be modified to use /\n/  that function to avoid silly memory consumption.                        /\n/-------------------------------------------------------------------------*/\n/*\n/ Copyright (C) 2018, ChaN, all right reserved.\n/\n/ FatFs module is an open source software. Redistribution and use of FatFs in\n/ source and binary forms, with or without modification, are permitted provided\n/ that the following condition is met:\n/\n/ 1. Redistributions of source code must retain the above copyright notice,\n/    this condition and the following disclaimer.\n/\n/ This software is provided by the copyright holder and contributors \"AS IS\"\n/ and any warranties related to this software are DISCLAIMED.\n/ The copyright owner or contributors be NOT LIABLE for any damages caused\n/ by use of this software.\n*/\n\n\n#include \"libs/fatfs/ff.h\"\n\n#if FF_USE_LFN\t/* This module will be blanked at non-LFN configuration */\n\n#if FF_DEFINED != 86604\t/* Revision ID */\n#error Wrong include file (ff.h).\n#endif\n\n#define MERGE2(a, b) a ## b\n#define CVTBL(tbl, cp) MERGE2(tbl, cp)\n\n#pragma GCC push_options\n#pragma GCC target (\"thumb\")\n\n\n/*------------------------------------------------------------------------*/\n/* Code Conversion Tables                                                 */\n/*------------------------------------------------------------------------*/\n\n#if FF_CODE_PAGE == 437 || FF_CODE_PAGE == 0\nstatic const WCHAR uc437[] = {\t/*  CP437(U.S.) to Unicode conversion table */\n\t0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,\n\t0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,\n\t0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,\n\t0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 720 || FF_CODE_PAGE == 0\nstatic const WCHAR uc720[] = {\t/*  CP720(Arabic) to Unicode conversion table */\n\t0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,\n\t0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,\n\t0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,\n\t0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 737 || FF_CODE_PAGE == 0\nstatic const WCHAR uc737[] = {\t/*  CP737(Greek) to Unicode conversion table */\n\t0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,\n\t0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,\n\t0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,\n\t0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 771 || FF_CODE_PAGE == 0\nstatic const WCHAR uc771[] = {\t/*  CP771(KBL) to Unicode conversion table */\n\t0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,\n\t0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,\n\t0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x0104, 0x0105, 0x010C, 0x010D,\n\t0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,\n\t0x0118, 0x0119, 0x0116, 0x0117, 0x012E, 0x012F, 0x0160, 0x0161, 0x0172, 0x0173, 0x016A, 0x016B, 0x017D, 0x017E, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 775 || FF_CODE_PAGE == 0\nstatic const WCHAR uc775[] = {\t/*  CP775(Baltic) to Unicode conversion table */\n\t0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,\n\t0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,\n\t0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,\n\t0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,\n\t0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 850 || FF_CODE_PAGE == 0\nstatic const WCHAR uc850[] = {\t/*  CP850(Latin 1) to Unicode conversion table */\n\t0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,\n\t0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,\n\t0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,\n\t0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,\n\t0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,\n\t0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 852 || FF_CODE_PAGE == 0\nstatic const WCHAR uc852[] = {\t/*  CP852(Latin 2) to Unicode conversion table */\n\t0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,\n\t0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,\n\t0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,\n\t0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,\n\t0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,\n\t0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 855 || FF_CODE_PAGE == 0\nstatic const WCHAR uc855[] = {\t/*  CP855(Cyrillic) to Unicode conversion table */\n\t0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,\n\t0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,\n\t0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,\n\t0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,\n\t0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,\n\t0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 857 || FF_CODE_PAGE == 0\nstatic const WCHAR uc857[] = {\t/*  CP857(Turkish) to Unicode conversion table */\n\t0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,\n\t0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,\n\t0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,\n\t0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,\n\t0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,\n\t0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 860 || FF_CODE_PAGE == 0\nstatic const WCHAR uc860[] = {\t/*  CP860(Portuguese) to Unicode conversion table */\n\t0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2,\n\t0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3,\n\t0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,\n\t0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 861 || FF_CODE_PAGE == 0\nstatic const WCHAR uc861[] = {\t/*  CP861(Icelandic) to Unicode conversion table */\n\t0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5,\n\t0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,\n\t0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,\n\t0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 862 || FF_CODE_PAGE == 0\nstatic const WCHAR uc862[] = {\t/*  CP862(Hebrew) to Unicode conversion table */\n\t0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,\n\t0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,\n\t0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,\n\t0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 863 || FF_CODE_PAGE == 0\nstatic const WCHAR uc863[] = {\t/*  CP863(Canadian French) to Unicode conversion table */\n\t0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0,\n\t0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192,\n\t0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2219,\n\t0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 864 || FF_CODE_PAGE == 0\nstatic const WCHAR uc864[] = {\t/*  CP864(Arabic) to Unicode conversion table */\n\t0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518,\n\t0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000,\n\t0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5,\n\t0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669, 0xFED1, 0x061B, 0xFEB1, 0xFEB5, 0xFEB9, 0x061F,\n\t0x00A2, 0xFE80, 0xFE81, 0xFE83, 0xFE85, 0xFECA, 0xFE8B, 0xFE8D, 0xFE91, 0xFE93, 0xFE97, 0xFE9B, 0xFE9F, 0xFEA3, 0xFEA7, 0xFEA9,\n\t0xFEAB, 0xFEAD, 0xFEAF, 0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, 0xFEC1, 0xFEC5, 0xFECB, 0xFECF, 0x00A6, 0x00AC, 0x00F7, 0x00D7, 0xFEC9,\n\t0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1,\n\t0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, 0x0000\n};\n#endif\n#if FF_CODE_PAGE == 865 || FF_CODE_PAGE == 0\nstatic const WCHAR uc865[] = {\t/*  CP865(Nordic) to Unicode conversion table */\n\t0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,\n\t0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,\n\t0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,\n\t0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 866 || FF_CODE_PAGE == 0\nstatic const WCHAR uc866[] = {\t/*  CP866(Russian) to Unicode conversion table */\n\t0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,\n\t0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,\n\t0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,\n\t0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 869 || FF_CODE_PAGE == 0\nstatic const WCHAR uc869[] = {\t/*  CP869(Greek 2) to Unicode conversion table */\n\t0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389,\n\t0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF,\n\t0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039A, 0x039B, 0x039C, 0x039D, 0x2563, 0x2551, 0x2557, 0x255D, 0x039E, 0x039F, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0A30, 0x03A1, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x03A3,\n\t0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x2518, 0x250C, 0x2588, 0x2584, 0x03B4, 0x03B5, 0x2580,\n\t0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384,\n\t0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0\n};\n#endif\n\n\n\n\n/*------------------------------------------------------------------------*/\n/* OEM <==> Unicode conversions for static code page configuration        */\n/* SBCS fixed code page                                                   */\n/*------------------------------------------------------------------------*/\n\n#if FF_CODE_PAGE != 0 && FF_CODE_PAGE < 900\nWCHAR ff_uni2oem (\t/* Returns OEM code character, zero on error */\n\tDWORD\tuni,\t/* UTF-16 encoded character to be converted */\n\tWORD\tcp\t\t/* Code page for the conversion */\n)\n{\n\tWCHAR c = 0;\n\tconst WCHAR *p = CVTBL(uc, FF_CODE_PAGE);\n\n\n\tif (uni < 0x80) {\t/* ASCII? */\n\t\tc = (WCHAR)uni;\n\n\t} else {\t\t\t/* Non-ASCII */\n\t\tif (uni < 0x10000 && cp == FF_CODE_PAGE) {\t/* Is it in BMP and valid code page? */\n\t\t\tfor (c = 0; c < 0x80 && uni != p[c]; c++) ;\n\t\t\tc = (c + 0x80) & 0xFF;\n\t\t}\n\t}\n\n\treturn c;\n}\n\nWCHAR ff_oem2uni (\t/* Returns Unicode character, zero on error */\n\tWCHAR\toem,\t/* OEM code to be converted */\n\tWORD\tcp\t\t/* Code page for the conversion */\n)\n{\n\tWCHAR c = 0;\n\tconst WCHAR *p = CVTBL(uc, FF_CODE_PAGE);\n\n\n\tif (oem < 0x80) {\t/* ASCII? */\n\t\tc = oem;\n\n\t} else {\t\t\t/* Extended char */\n\t\tif (cp == FF_CODE_PAGE) {\t/* Is it a valid code page? */\n\t\t\tif (oem < 0x100) c = p[oem - 0x80];\n\t\t}\n\t}\n\n\treturn c;\n}\n\n#endif\n\n\n\n/*------------------------------------------------------------------------*/\n/* OEM <==> Unicode conversions for static code page configuration        */\n/* DBCS fixed code page                                                   */\n/*------------------------------------------------------------------------*/\n\n#if FF_CODE_PAGE >= 900\nWCHAR ff_uni2oem (\t/* Returns OEM code character, zero on error */\n\tDWORD\tuni,\t/* UTF-16 encoded character to be converted */\n\tWORD\tcp\t\t/* Code page for the conversion */\n)\n{\n\tconst WCHAR *p;\n\tWCHAR c = 0, uc;\n\tUINT i = 0, n, li, hi;\n\n\n\tif (uni < 0x80) {\t/* ASCII? */\n\t\tc = (WCHAR)uni;\n\n\t} else {\t\t\t/* Non-ASCII */\n\t\tif (uni < 0x10000 && cp == FF_CODE_PAGE) {\t/* Is it in BMP and valid code page? */\n\t\t\tuc = (WCHAR)uni;\n\t\t\tp = CVTBL(uni2oem, FF_CODE_PAGE);\n\t\t\thi = sizeof CVTBL(uni2oem, FF_CODE_PAGE) / 4 - 1;\n\t\t\tli = 0;\n\t\t\tfor (n = 16; n; n--) {\n\t\t\t\ti = li + (hi - li) / 2;\n\t\t\t\tif (uc == p[i * 2]) break;\n\t\t\t\tif (uc > p[i * 2]) {\n\t\t\t\t\tli = i;\n\t\t\t\t} else {\n\t\t\t\t\thi = i;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (n != 0) c = p[i * 2 + 1];\n\t\t}\n\t}\n\n\treturn c;\n}\n\n\nWCHAR ff_oem2uni (\t/* Returns Unicode character, zero on error */\n\tWCHAR\toem,\t/* OEM code to be converted */\n\tWORD\tcp\t\t/* Code page for the conversion */\n)\n{\n\tconst WCHAR *p;\n\tWCHAR c = 0;\n\tUINT i = 0, n, li, hi;\n\n\n\tif (oem < 0x80) {\t/* ASCII? */\n\t\tc = oem;\n\n\t} else {\t\t\t/* Extended char */\n\t\tif (cp == FF_CODE_PAGE) {\t/* Is it valid code page? */\n\t\t\tp = CVTBL(oem2uni, FF_CODE_PAGE);\n\t\t\thi = sizeof CVTBL(oem2uni, FF_CODE_PAGE) / 4 - 1;\n\t\t\tli = 0;\n\t\t\tfor (n = 16; n; n--) {\n\t\t\t\ti = li + (hi - li) / 2;\n\t\t\t\tif (oem == p[i * 2]) break;\n\t\t\t\tif (oem > p[i * 2]) {\n\t\t\t\t\tli = i;\n\t\t\t\t} else {\n\t\t\t\t\thi = i;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (n != 0) c = p[i * 2 + 1];\n\t\t}\n\t}\n\n\treturn c;\n}\n#endif\n\n\n\n/*------------------------------------------------------------------------*/\n/* OEM <==> Unicode conversions for dynamic code page configuration       */\n/*------------------------------------------------------------------------*/\n\n#if FF_CODE_PAGE == 0\n\nstatic const WORD cp_code[]          = {  437,   720,   737,   771,   775,   850,   852,   855,   857,   860,   861,   862,   863,   864,   865,   866,   869, 0};\nstatic const WCHAR* const cp_table[] = {uc437, uc720, uc737, uc771, uc775, uc850, uc852, uc855, uc857, uc860, uc861, uc862, uc863, uc864, uc865, uc866, uc869, 0};\n\n\nWCHAR ff_uni2oem (\t/* Returns OEM code character, zero on error */\n\tDWORD\tuni,\t/* UTF-16 encoded character to be converted */\n\tWORD\tcp\t\t/* Code page for the conversion */\n)\n{\n\tconst WCHAR *p;\n\tWCHAR c = 0, uc;\n\tUINT i, n, li, hi;\n\n\n\tif (uni < 0x80) {\t/* ASCII? */\n\t\tc = (WCHAR)uni;\n\n\t} else {\t\t\t/* Non-ASCII */\n\t\tif (uni < 0x10000) { /* Is it in BMP? */\n\t\t\tuc = (WCHAR)uni;\n\t\t\tp = 0;\n\t\t\tif (cp < 900) {\t/* SBCS */\n\t\t\t\tfor (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ;\t\t/* Get conversion table */\n\t\t\t\tp = cp_table[i];\n\t\t\t\tif (p) {\t/* Is it valid code page ? */\n\t\t\t\t\tfor (c = 0; c < 0x80 && uc != p[c]; c++) ;\t/* Find OEM code in the table */\n\t\t\t\t\tc = (c + 0x80) & 0xFF;\n\t\t\t\t}\n\t\t\t} else {\t/* DBCS */\n\t\t\t\tswitch (cp) {\t/* Get conversion table */\n\t\t\t\tcase 932 : p = uni2oem932; hi = sizeof uni2oem932 / 4 - 1; break;\n\t\t\t\tcase 936 : p = uni2oem936; hi = sizeof uni2oem936 / 4 - 1; break;\n\t\t\t\tcase 949 : p = uni2oem949; hi = sizeof uni2oem949 / 4 - 1; break;\n\t\t\t\tcase 950 : p = uni2oem950; hi = sizeof uni2oem950 / 4 - 1; break;\n\t\t\t\t}\n\t\t\t\tif (p) {\t/* Is it valid code page? */\n\t\t\t\t\tli = 0;\n\t\t\t\t\tfor (n = 16; n; n--) {\t/* Find OEM code */\n\t\t\t\t\t\ti = li + (hi - li) / 2;\n\t\t\t\t\t\tif (uc == p[i * 2]) break;\n\t\t\t\t\t\tif (uc > p[i * 2]) {\n\t\t\t\t\t\t\tli = i;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\thi = i;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (n != 0) c = p[i * 2 + 1];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn c;\n}\n\n\nWCHAR ff_oem2uni (\t/* Returns Unicode character, zero on error */\n\tWCHAR\toem,\t/* OEM code to be converted (DBC if >=0x100) */\n\tWORD\tcp\t\t/* Code page for the conversion */\n)\n{\n\tconst WCHAR *p;\n\tWCHAR c = 0;\n\tUINT i, n, li, hi;\n\n\n\tif (oem < 0x80) {\t/* ASCII? */\n\t\tc = oem;\n\n\t} else {\t\t\t/* Extended char */\n\t\tp = 0;\n\t\tif (cp < 900) {\t/* SBCS */\n\t\t\tfor (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ;\t\t/* Get table */\n\t\t\tp = cp_table[i];\n\t\t\tif (p) {\t/* Is it a valid CP ? */\n\t\t\t\tif (oem < 0x100) c = p[oem - 0x80];\n\t\t\t}\n\t\t} else {\t/* DBCS */\n\t\t\tswitch (cp) {\n\t\t\tcase 932 : p = oem2uni932; hi = sizeof oem2uni932 / 4 - 1; break;\n\t\t\tcase 936 : p = oem2uni936; hi = sizeof oem2uni936 / 4 - 1; break;\n\t\t\tcase 949 : p = oem2uni949; hi = sizeof oem2uni949 / 4 - 1; break;\n\t\t\tcase 950 : p = oem2uni950; hi = sizeof oem2uni950 / 4 - 1; break;\n\t\t\t}\n\t\t\tif (p) {\n\t\t\t\tli = 0;\n\t\t\t\tfor (n = 16; n; n--) {\n\t\t\t\t\ti = li + (hi - li) / 2;\n\t\t\t\t\tif (oem == p[i * 2]) break;\n\t\t\t\t\tif (oem > p[i * 2]) {\n\t\t\t\t\t\tli = i;\n\t\t\t\t\t} else {\n\t\t\t\t\t\thi = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (n != 0) c = p[i * 2 + 1];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn c;\n}\n#endif\n\n\n\n/*------------------------------------------------------------------------*/\n/* Unicode up-case conversion                                             */\n/*------------------------------------------------------------------------*/\n\nDWORD ff_wtoupper (\t/* Returns up-converted code point */\n\tDWORD uni\t\t/* Unicode code point to be up-converted */\n)\n{\n\tconst WORD *p;\n\tWORD uc, bc, nc, cmd;\n\tstatic const WORD cvt1[] = {\t/* Compressed up conversion table for U+0000 - U+0FFF */\n\t\t/* Basic Latin */\n\t\t0x0061,0x031A,\n\t\t/* Latin-1 Supplement */\n\t\t0x00E0,0x0317,\n\t\t0x00F8,0x0307,\n\t\t0x00FF,0x0001,0x0178,\n\t\t/* Latin Extended-A */\n\t\t0x0100,0x0130,\n\t\t0x0132,0x0106,\n\t\t0x0139,0x0110,\n\t\t0x014A,0x012E,\n\t\t0x0179,0x0106,\n\t\t/* Latin Extended-B */\n\t\t0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA,\n\t\t0x01CD,0x0110,\n\t\t0x01DD,0x0001,0x018E,\n\t\t0x01DE,0x0112,\n\t\t0x01F3,0x0003,0x01F1,0x01F4,0x01F4,\n\t\t0x01F8,0x0128,\n\t\t0x0222,0x0112,\n\t\t0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241,\n\t\t0x0246,0x010A,\n\t\t/* IPA Extensions */\n\t\t0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7,\n\t\t/* Greek, Coptic */\n\t\t0x037B,0x0003,0x03FD,0x03FE,0x03FF,\n\t\t0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A,\n\t\t0x03B1,0x0311,\n\t\t0x03C2,0x0002,0x03A3,0x03A3,\n\t\t0x03C4,0x0308,\n\t\t0x03CC,0x0003,0x038C,0x038E,0x038F,\n\t\t0x03D8,0x0118,\n\t\t0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA,\n\t\t/* Cyrillic */\n\t\t0x0430,0x0320,\n\t\t0x0450,0x0710,\n\t\t0x0460,0x0122,\n\t\t0x048A,0x0136,\n\t\t0x04C1,0x010E,\n\t\t0x04CF,0x0001,0x04C0,\n\t\t0x04D0,0x0144,\n\t\t/* Armenian */\n\t\t0x0561,0x0426,\n\n\t\t0x0000\t/* EOT */\n\t};\n\tstatic const WORD cvt2[] = {\t/* Compressed up conversion table for U+1000 - U+FFFF */\n\t\t/* Phonetic Extensions */\n\t\t0x1D7D,0x0001,0x2C63,\n\t\t/* Latin Extended Additional */\n\t\t0x1E00,0x0196,\n\t\t0x1EA0,0x015A,\n\t\t/* Greek Extended */\n\t\t0x1F00,0x0608,\n\t\t0x1F10,0x0606,\n\t\t0x1F20,0x0608,\n\t\t0x1F30,0x0608,\n\t\t0x1F40,0x0606,\n\t\t0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F,\n\t\t0x1F60,0x0608,\n\t\t0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB,\n\t\t0x1F80,0x0608,\n\t\t0x1F90,0x0608,\n\t\t0x1FA0,0x0608,\n\t\t0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,\n\t\t0x1FCC,0x0001,0x1FC3,\n\t\t0x1FD0,0x0602,\n\t\t0x1FE0,0x0602,\n\t\t0x1FE5,0x0001,0x1FEC,\n\t\t0x1FF3,0x0001,0x1FFC,\n\t\t/* Letterlike Symbols */\n\t\t0x214E,0x0001,0x2132,\n\t\t/* Number forms */\n\t\t0x2170,0x0210,\n\t\t0x2184,0x0001,0x2183,\n\t\t/* Enclosed Alphanumerics */\n\t\t0x24D0,0x051A,\n\t\t0x2C30,0x042F,\n\t\t/* Latin Extended-C */\n\t\t0x2C60,0x0102,\n\t\t0x2C67,0x0106, 0x2C75,0x0102,\n\t\t/* Coptic */\n\t\t0x2C80,0x0164,\n\t\t/* Georgian Supplement */\n\t\t0x2D00,0x0826,\n\t\t/* Full-width */\n\t\t0xFF41,0x031A,\n\n\t\t0x0000\t/* EOT */\n\t};\n\n\n\tif (uni < 0x10000) {\t/* Is it in BMP? */\n\t\tuc = (WORD)uni;\n\t\tp = uc < 0x1000 ? cvt1 : cvt2;\n\t\tfor (;;) {\n\t\t\tbc = *p++;\t\t\t\t\t\t\t\t/* Get the block base */\n\t\t\tif (bc == 0 || uc < bc) break;\t\t\t/* Not matched? */\n\t\t\tnc = *p++; cmd = nc >> 8; nc &= 0xFF;\t/* Get processing command and block size */\n\t\t\tif (uc < bc + nc) {\t/* In the block? */\n\t\t\t\tswitch (cmd) {\n\t\t\t\tcase 0:\tuc = p[uc - bc]; break;\t\t/* Table conversion */\n\t\t\t\tcase 1:\tuc -= (uc - bc) & 1; break;\t/* Case pairs */\n\t\t\t\tcase 2: uc -= 16; break;\t\t\t/* Shift -16 */\n\t\t\t\tcase 3:\tuc -= 32; break;\t\t\t/* Shift -32 */\n\t\t\t\tcase 4:\tuc -= 48; break;\t\t\t/* Shift -48 */\n\t\t\t\tcase 5:\tuc -= 26; break;\t\t\t/* Shift -26 */\n\t\t\t\tcase 6:\tuc += 8; break;\t\t\t\t/* Shift +8 */\n\t\t\t\tcase 7: uc -= 80; break;\t\t\t/* Shift -80 */\n\t\t\t\tcase 8:\tuc -= 0x1C60; break;\t\t/* Shift -0x1C60 */\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (cmd == 0) p += nc;\t/* Skip table if needed */\n\t\t}\n\t\tuni = uc;\n\t}\n\n\treturn uni;\n}\n\n#pragma GCC pop_options\n\n\n#endif /* #if FF_USE_LFN */\n"
  },
  {
    "path": "argon-first-stage/src/link.ld",
    "content": "ENTRY(_start)\n\nSECTIONS {\n\tPROVIDE(__ipl_start = 0x40008000);\n\t. = __ipl_start;\n\t.text : {\n\t\t*(.text._start);\n\t\t*(._boot_cfg);\n\t\t*(._ipl_version);\n\t\t*(.text*);\n\t}\n\t.data : {\n\t\t*(.data*);\n\t\t*(.rodata*);\n\t}\n\t. = ALIGN(0x10);\n\t__ipl_end = .;\n\t.bss : {\n\t\t__bss_start = .;\n\t\t*(COMMON)\n\t\t*(.bss*)\n\t\t__bss_end = .;\n\t}\n}\n"
  },
  {
    "path": "argon-first-stage/src/main.c",
    "content": "/*\n * Copyright (c) 2018 Guillem96\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"gfx/di.h\"\n#include \"gfx/gfx.h\"\n\n#include \"mem/heap.h\"\n\n#include \"soc/hw_init.h\"\n#include \"soc/bpmp.h\"\n\n#include \"core/launcher.h\"\n\n#include \"utils/util.h\"\n#include \"utils/fs_utils.h\"\n#include \"utils/btn.h\"\n\n#include \"power/max17050.h\"\n\n\nextern void pivot_stack(u32 stack_top);\n\nstatic inline void setup_gfx()\n{\n    gfx_init_ctxt((u32 *)FB_ADDRESS, 720, 1280, 720);\n    memset((u32 *)FB_ADDRESS, 0, 0x3C0000);\n\tgfx_con_init();\n}\n\nstatic void error_end(const char* error_msg)\n{\n    display_init_framebuffer();\n    gfx_clear_grey(0x0);\n    gfx_printf(\"%s\\n\", error_msg);\n    \n    gfx_printf(\"Press power button to reboot into RCM...\\n\\n\");\n    wait_for_button_and_reboot();\n}\n\n\nvoid ipl_main()\n{\n    /* Configure Switch Hardware (thanks to hekate project) */\n    config_hw();\n    bpmp_mmu_enable();\n\n    /* Init the stack and the heap */\n    pivot_stack(0x90010000);\n    heap_init(0x90020000);\n\n    /* Init display and gfx module */\n    display_init();\n    setup_gfx();\n    display_backlight_pwm_init();\n    display_backlight_brightness(100, 1000);\n\n    \n    bpmp_clk_rate_set(BPMP_CLK_SUPER_BOOST);\n    \n    /* Mount Sd card and launch payload */\n    if (sd_mount())\n    {  \n\n        u8* splash = sd_file_read(\"argon/splash.bmp\");\n        if (splash)\n        {\n            gfx_render_splash(splash);\n            display_init_framebuffer();\n            msleep(1000);\n        } \n        else \n        {\n            error_end(\"No splash found\\n\");\n        }\n\n        launch_payload(\"argon/sys/argon-nx-gui.bin\");\n        error_end(\"Fail chainloading GUI\\n\");\n    } else {\n        error_end(\"No sd card found...\\n\");\n    }\n    error_end(\"\");\n}"
  },
  {
    "path": "argon-first-stage/src/mem/heap.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 M4xw\n * Copyright (c) 2018 Guillem96\n * \n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n#include \"mem/heap.h\"\n\nstatic void _heap_create(heap_t *heap, u32 start)\n{\n\theap->start = start;\n\theap->first = NULL;\n}\n\nstatic u32 _heap_alloc(heap_t *heap, u32 size, u32 alignment)\n{\n\thnode_t *node, *new;\n\tint search = 1;\n\n\tsize = ALIGN(size, alignment);\n\n\tif (!heap->first)\n\t{\n\t\tnode = (hnode_t *)heap->start;\n\t\tnode->used = 1;\n\t\tnode->size = size;\n\t\tnode->prev = NULL;\n\t\tnode->next = NULL;\n\t\theap->first = node;\n\n\t\treturn (u32)node + sizeof(hnode_t);\n\t}\n\n\tnode = heap->first;\n\twhile (search)\n\t{\n\t\tif (!node->used && size + sizeof(hnode_t) < node->size)\n\t\t{\n\t\t\tnew = (hnode_t *)((u32)node + sizeof(hnode_t) + size);\n\n\t\t\tnew->size = node->size - sizeof(hnode_t) - size;\n\t\t\tnode->size = size;\n\t\t\tnode->used = 1;\n\t\t\tnew->used = 0;\n\t\t\tnew->next = node->next;\n\t\t\tnew->prev = node;\n\t\t\tnode->next = new;\n\n\t\t\treturn (u32)node + sizeof(hnode_t);\n\t\t}\n\t\tif (node->next)\n\t\t\tnode = node->next;\n\t\telse\n\t\t\tsearch = 0;\n\t}\n\n\tnew = (hnode_t *)((u32)node + sizeof(hnode_t) + node->size);\n\tnew->used = 1;\n\tnew->size = size;\n\tnew->prev = node;\n\tnew->next = NULL;\n\tnode->next = new;\n\n\treturn (u32)new + sizeof(hnode_t);\n}\n\nstatic void _heap_free(heap_t *heap, u32 addr)\n{\n\thnode_t *node = (hnode_t *)(addr - sizeof(hnode_t));\n\tnode->used = 0;\n\tnode = heap->first;\n\twhile (node)\n\t{\n\t\tif (!node->used)\n\t\t{\n\t\t\tif (node->prev && !node->prev->used)\n\t\t\t{\n\t\t\t\tnode->prev->size += node->size + sizeof(hnode_t);\n\t\t\t\tnode->prev->next = node->next;\n\t\t\t\tif (node->next)\n\t\t\t\t\tnode->next->prev = node->prev;\n\t\t\t}\n\t\t}\n\t\tnode = node->next;\n\t}\n}\n\nheap_t _heap;\n\nvoid heap_init(u32 base)\n{\n\t_heap_create(&_heap, base);\n}\n\nvoid *malloc(u32 size)\n{\n\treturn (void *)_heap_alloc(&_heap, size, 0x10);\n}\n\nvoid *memalign(u32 align, u32 size)\n{\n\treturn (void *)_heap_alloc(&_heap, size, align);\n}\n\nvoid *calloc(u32 num, u32 size)\n{\n\tvoid *res = (void *)_heap_alloc(&_heap, num * size, 0x10);\n\tmemset(res, 0, num * size);\n\treturn res;\n}\n\nvoid free(void *buf)\n{\n\tif ((buf != NULL) || ((u32)buf > (_heap.start - 1)))\n\t\t_heap_free(&_heap, (u32)buf);\n}\n\nvoid *m_realloc(void* ptr, u32 current_size, u32 new_size)\n{\n    if (new_size == 0)\n    {\n      free(ptr);\n      return NULL;\n    }\n    else if (!ptr)\n    {\n        return malloc(new_size);\n    }\n    else if (new_size <= current_size)\n    {\n        return ptr;\n    }\n    else\n    {\n        if ((ptr) && (new_size > current_size))\n        {\n            void *ptrNew = malloc(new_size);\n            if (ptrNew)\n            {\n                memcpy(ptrNew, ptr, current_size);\n                free(ptr);\n            }\n            return ptrNew;\n        }\n        return NULL;\n    }\n}\n"
  },
  {
    "path": "argon-first-stage/src/mem/mc.c",
    "content": "#include \"mem/mc.h\"\n#include \"soc/t210.h\"\n#include \"soc/clock.h\"\n#include \"utils/util.h\"\n\nvoid mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock)\n{\n\tMC(MC_SEC_CARVEOUT_BOM) = bom;\n\tMC(MC_SEC_CARVEOUT_SIZE_MB) = size1mb;\n\tif (lock)\n\t\tMC(MC_SEC_CARVEOUT_REG_CTRL) = 1;\n}\n\nvoid mc_config_carveout()\n{\n\t*(vu32 *)0x8005FFFC = 0xC0EDBBCC;\n\tMC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1;\n\tMC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;\n\tMC(MC_VIDEO_PROTECT_BOM) = 0;\n\tMC(MC_VIDEO_PROTECT_SIZE_MB) = 0;\n\tMC(MC_VIDEO_PROTECT_REG_CTRL) = 1;\n\n\t// Configure TSEC carveout @ 0x90000000, 1MB.\n\t//mc_config_tsec_carveout(0x90000000, 1, false);\n\tmc_config_tsec_carveout(0, 0, true);\n\n\tMC(MC_MTS_CARVEOUT_BOM) = 0;\n\tMC(MC_MTS_CARVEOUT_SIZE_MB) = 0;\n\tMC(MC_MTS_CARVEOUT_ADR_HI) = 0;\n\tMC(MC_MTS_CARVEOUT_REG_CTRL) = 1;\n\n\tMC(MC_SECURITY_CARVEOUT1_BOM) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_BOM_HI) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_SIZE_128KB) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CFG0) = 0x4000006;\n\n\tMC(MC_SECURITY_CARVEOUT2_BOM) = 0x80020000;\n\tMC(MC_SECURITY_CARVEOUT2_BOM_HI) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_SIZE_128KB) = 2;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = 0x3100000;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4) = 0x300;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_CFG0) = 0x440167E;\n\n\tMC(MC_SECURITY_CARVEOUT3_BOM) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_BOM_HI) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_SIZE_128KB) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2) = 0x3000000;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4) = 0x300;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CFG0) = 0x4401E7E;\n\n\tMC(MC_SECURITY_CARVEOUT4_BOM) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_BOM_HI) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_SIZE_128KB) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CFG0) = 0x8F;\n\n\tMC(MC_SECURITY_CARVEOUT5_BOM) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_BOM_HI) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_SIZE_128KB) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CFG0) = 0x8F;\n}\n\nvoid mc_enable_ahb_redirect()\n{\n\t// Enable ARC_CLK_OVR_ON.\n\tCLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) = (CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) & 0xFFF7FFFF) | 0x80000;\n\t//MC(MC_IRAM_REG_CTRL) &= 0xFFFFFFFE;\n\tMC(MC_IRAM_BOM) = 0x40000000;\n\tMC(MC_IRAM_TOM) = 0x4003F000;\n}\n\nvoid mc_disable_ahb_redirect()\n{\n\tMC(MC_IRAM_BOM) = 0xFFFFF000;\n\tMC(MC_IRAM_TOM) = 0;\n\t// Disable IRAM_CFG_WRITE_ACCESS (sticky).\n\t//MC(MC_IRAM_REG_CTRL) = MC(MC_IRAM_REG_CTRL) & 0xFFFFFFFE | 1;\n\t// Disable ARC_CLK_OVR_ON.\n\tCLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) &= 0xFFF7FFFF;\n}\n\nvoid mc_enable()\n{\n\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | 0x40000000;\n\t// Enable MIPI CAL clock.\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFDFFFFFF) | 0x2000000;\n\t// Enable MC clock.\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFFFFFFFE) | 1;\n\t// Enable EMC DLL clock.\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) & 0xFFFFBFFF) | 0x4000;\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x2000001; //Clear EMC and MC reset.\n\tusleep(5);\n\n\t//#ifdef CONFIG_ENABLE_AHB_REDIRECT\n\tmc_disable_ahb_redirect();\n\t//mc_enable_ahb_redirect();\n\t//#endif\n}\n"
  },
  {
    "path": "argon-first-stage/src/mem/sdram.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"soc/i2c.h\"\n#include \"soc/t210.h\"\n#include \"mem/mc.h\"\n#include \"mem/emc.h\"\n#include \"soc/pmc.h\"\n#include \"utils/util.h\"\n#include \"soc/fuse.h\"\n#include \"power/max77620.h\"\n#include \"mem/sdram_param_t210.h\"\n#include \"soc/clock.h\"\n\n#define CONFIG_SDRAM_COMPRESS_CFG\n\n#ifdef CONFIG_SDRAM_COMPRESS_CFG\n#include \"libs/compr/lz.h\"\n#include \"mem/sdram_config_lz.inl\"\n#else\n#include \"mem/sdram_config.inl\"\n#endif\n\nu32 get_sdram_id()\n{\n\treturn (fuse_read_odm(4) & 0x1F) >> 3;\n}\n\nstatic void _sdram_config(const sdram_params_t *params)\n{\n\tPMC(APBDEV_PMC_IO_DPD3_REQ) = (((4 * params->emc_pmc_scratch1 >> 2) + 0x80000000) ^ 0xFFFF) & 0xC000FFFF;\n\tusleep(params->pmc_io_dpd3_req_wait);\n\n\tu32 req = (4 * params->emc_pmc_scratch2 >> 2) + 0x80000000;\n\tPMC(APBDEV_PMC_IO_DPD4_REQ) = (req >> 16 << 16) ^ 0x3FFF0000;\n\tusleep(params->pmc_io_dpd4_req_wait);\n\tPMC(APBDEV_PMC_IO_DPD4_REQ) = (req ^ 0xFFFF) & 0xC000FFFF;\n\tusleep(params->pmc_io_dpd4_req_wait);\n\tPMC(APBDEV_PMC_WEAK_BIAS) = 0;\n\tusleep(1);\n\n\tCLOCK(CLK_RST_CONTROLLER_PLLM_MISC1) = params->pllm_setup_control;\n\tCLOCK(CLK_RST_CONTROLLER_PLLM_MISC2) = 0;\n\tCLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = (params->pllm_feedback_divider << 8) | params->pllm_input_divider | 0x40000000 | ((params->pllm_post_divider & 0xFFFF) << 20);\n\n\tu32 wait_end = get_tmr_us() + 300;\n\twhile (!(CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) & 0x8000000))\n\t{\n\t\tif (get_tmr_us() >= wait_end)\n\t\t\tgoto break_nosleep;\n\t}\n\tusleep(10);\nbreak_nosleep:\n\n\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = ((params->mc_emem_arb_misc0 >> 11) & 0x10000) | (params->emc_clock_source & 0xFFFEFFFF);\n\tif (params->emc_clock_source_dll)\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll;\n\tif (params->clear_clock2_mc1)\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = 0x40000000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x2000001;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x4000;\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x2000001;\n\tEMC(EMC_PMACRO_VTTGEN_CTRL_0) = params->emc_pmacro_vttgen_ctrl0;\n\tEMC(EMC_PMACRO_VTTGEN_CTRL_1) = params->emc_pmacro_vttgen_ctrl1;\n\tEMC(EMC_PMACRO_VTTGEN_CTRL_2) = params->emc_pmacro_vttgen_ctrl2;\n\tEMC(EMC_TIMING_CONTROL) = 1;\n\tusleep(1);\n\tEMC(EMC_DBG) = (params->emc_dbg_write_mux << 1) | params->emc_dbg;\n\tif (params->emc_bct_spare2)\n\t\t*(vu32 *)params->emc_bct_spare2 = params->emc_bct_spare3;\n\tEMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;\n\tEMC(EMC_CMD_MAPPING_CMD0_0) = params->emc_cmd_mapping_cmd0_0;\n\tEMC(EMC_CMD_MAPPING_CMD0_1) = params->emc_cmd_mapping_cmd0_1;\n\tEMC(EMC_CMD_MAPPING_CMD0_2) = params->emc_cmd_mapping_cmd0_2;\n\tEMC(EMC_CMD_MAPPING_CMD1_0) = params->emc_cmd_mapping_cmd1_0;\n\tEMC(EMC_CMD_MAPPING_CMD1_1) = params->emc_cmd_mapping_cmd1_1;\n\tEMC(EMC_CMD_MAPPING_CMD1_2) = params->emc_cmd_mapping_cmd1_2;\n\tEMC(EMC_CMD_MAPPING_CMD2_0) = params->emc_cmd_mapping_cmd2_0;\n\tEMC(EMC_CMD_MAPPING_CMD2_1) = params->emc_cmd_mapping_cmd2_1;\n\tEMC(EMC_CMD_MAPPING_CMD2_2) = params->emc_cmd_mapping_cmd2_2;\n\tEMC(EMC_CMD_MAPPING_CMD3_0) = params->emc_cmd_mapping_cmd3_0;\n\tEMC(EMC_CMD_MAPPING_CMD3_1) = params->emc_cmd_mapping_cmd3_1;\n\tEMC(EMC_CMD_MAPPING_CMD3_2) = params->emc_cmd_mapping_cmd3_2;\n\tEMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;\n\tEMC(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0;\n\tEMC(EMC_PMACRO_BRICK_MAPPING_1) = params->emc_pmacro_brick_mapping1;\n\tEMC(EMC_PMACRO_BRICK_MAPPING_2) = params->emc_pmacro_brick_mapping2;\n\tEMC(EMC_PMACRO_BRICK_CTRL_RFU1) = (params->emc_pmacro_brick_ctrl_rfu1 & 0x1120112) | 0x1EED1EED;\n\tEMC(EMC_CONFIG_SAMPLE_DELAY) = params->emc_config_sample_delay;\n\tEMC(EMC_FBIO_CFG8) = params->emc_fbio_cfg8;\n\tEMC(EMC_SWIZZLE_RANK0_BYTE0) = params->emc_swizzle_rank0_byte0;\n\tEMC(EMC_SWIZZLE_RANK0_BYTE1) = params->emc_swizzle_rank0_byte1;\n\tEMC(EMC_SWIZZLE_RANK0_BYTE2) = params->emc_swizzle_rank0_byte2;\n\tEMC(EMC_SWIZZLE_RANK0_BYTE3) = params->emc_swizzle_rank0_byte3;\n\tEMC(EMC_SWIZZLE_RANK1_BYTE0) = params->emc_swizzle_rank1_byte0;\n\tEMC(EMC_SWIZZLE_RANK1_BYTE1) = params->emc_swizzle_rank1_byte1;\n\tEMC(EMC_SWIZZLE_RANK1_BYTE2) = params->emc_swizzle_rank1_byte2;\n\tEMC(EMC_SWIZZLE_RANK1_BYTE3) = params->emc_swizzle_rank1_byte3;\n\tif (params->emc_bct_spare6)\n\t\t*(vu32 *)params->emc_bct_spare6 = params->emc_bct_spare7;\n\tEMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl;\n\tEMC(EMC_XM2COMPPADCTRL2) = params->emc_xm2_comp_pad_ctrl2;\n\tEMC(EMC_XM2COMPPADCTRL3) = params->emc_xm2_comp_pad_ctrl3;\n\tEMC(EMC_AUTO_CAL_CONFIG2) = params->emc_auto_cal_config2;\n\tEMC(EMC_AUTO_CAL_CONFIG3) = params->emc_auto_cal_config3;\n\tEMC(EMC_AUTO_CAL_CONFIG4) = params->emc_auto_cal_config4;\n\tEMC(EMC_AUTO_CAL_CONFIG5) = params->emc_auto_cal_config5;\n\tEMC(EMC_AUTO_CAL_CONFIG6) = params->emc_auto_cal_config6;\n\tEMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7;\n\tEMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8;\n\tEMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;\n\tEMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;\n\tEMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;\n\tEMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive;\n\tEMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = params->emc_pmacro_auto_cal_common;\n\tEMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;\n\tEMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;\n\tEMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0;\n\tEMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1;\n\tEMC(EMC_CFG_DIG_DLL_1) = params->emc_cfg_dig_dll_1;\n\tEMC(EMC_DATA_BRLSHFT_0) = params->emc_data_brlshft0;\n\tEMC(EMC_DATA_BRLSHFT_1) = params->emc_data_brlshft1;\n\tEMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0;\n\tEMC(EMC_DQS_BRLSHFT_1) = params->emc_dqs_brlshft1;\n\tEMC(EMC_CMD_BRLSHFT_0) = params->emc_cmd_brlshft0;\n\tEMC(EMC_CMD_BRLSHFT_1) = params->emc_cmd_brlshft1;\n\tEMC(EMC_CMD_BRLSHFT_2) = params->emc_cmd_brlshft2;\n\tEMC(EMC_CMD_BRLSHFT_3) = params->emc_cmd_brlshft3;\n\tEMC(EMC_QUSE_BRLSHFT_0) = params->emc_quse_brlshft0;\n\tEMC(EMC_QUSE_BRLSHFT_1) = params->emc_quse_brlshft1;\n\tEMC(EMC_QUSE_BRLSHFT_2) = params->emc_quse_brlshft2;\n\tEMC(EMC_QUSE_BRLSHFT_3) = params->emc_quse_brlshft3;\n\tEMC(EMC_PMACRO_BRICK_CTRL_RFU1) = (params->emc_pmacro_brick_ctrl_rfu1 & 0x1BF01BF) | 0x1E401E40;\n\tEMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl;\n\tEMC(EMC_PMACRO_CMD_BRICK_CTRL_FDPD) = params->emc_pmacro_cmd_brick_ctrl_fdpd;\n\tEMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2 & 0xFF7FFF7F;\n\tEMC(EMC_PMACRO_DATA_BRICK_CTRL_FDPD) = params->emc_pmacro_data_brick_ctrl_fdpd;\n\tEMC(EMC_PMACRO_BG_BIAS_CTRL_0) = params->emc_pmacro_bg_bias_ctrl0;\n\tEMC(EMC_PMACRO_DATA_PAD_RX_CTRL) = params->emc_pmacro_data_pad_rx_ctrl;\n\tEMC(EMC_PMACRO_CMD_PAD_RX_CTRL) = params->emc_pmacro_cmd_pad_rx_ctrl;\n\tEMC(EMC_PMACRO_DATA_PAD_TX_CTRL) = params->emc_pmacro_data_pad_tx_ctrl;\n\tEMC(EMC_PMACRO_DATA_RX_TERM_MODE) = params->emc_pmacro_data_rx_term_mode;\n\tEMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;\n\tEMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl;\n\tEMC(EMC_CFG_3) = params->emc_cfg3;\n\tEMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;\n\tEMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;\n\tEMC(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2;\n\tEMC(EMC_PMACRO_TX_PWRD_3) = params->emc_pmacro_tx_pwrd3;\n\tEMC(EMC_PMACRO_TX_PWRD_4) = params->emc_pmacro_tx_pwrd4;\n\tEMC(EMC_PMACRO_TX_PWRD_5) = params->emc_pmacro_tx_pwrd5;\n\tEMC(EMC_PMACRO_TX_SEL_CLK_SRC_0) = params->emc_pmacro_tx_sel_clk_src0;\n\tEMC(EMC_PMACRO_TX_SEL_CLK_SRC_1) = params->emc_pmacro_tx_sel_clk_src1;\n\tEMC(EMC_PMACRO_TX_SEL_CLK_SRC_2) = params->emc_pmacro_tx_sel_clk_src2;\n\tEMC(EMC_PMACRO_TX_SEL_CLK_SRC_3) = params->emc_pmacro_tx_sel_clk_src3;\n\tEMC(EMC_PMACRO_TX_SEL_CLK_SRC_4) = params->emc_pmacro_tx_sel_clk_src4;\n\tEMC(EMC_PMACRO_TX_SEL_CLK_SRC_5) = params->emc_pmacro_tx_sel_clk_src5;\n\tEMC(EMC_PMACRO_DDLL_BYPASS) = params->emc_pmacro_ddll_bypass;\n\tEMC(EMC_PMACRO_DDLL_PWRD_0) = params->emc_pmacro_ddll_pwrd0;\n\tEMC(EMC_PMACRO_DDLL_PWRD_1) = params->emc_pmacro_ddll_pwrd1;\n\tEMC(EMC_PMACRO_DDLL_PWRD_2) = params->emc_pmacro_ddll_pwrd2;\n\tEMC(EMC_PMACRO_CMD_CTRL_0) = params->emc_pmacro_cmd_ctrl0;\n\tEMC(EMC_PMACRO_CMD_CTRL_1) = params->emc_pmacro_cmd_ctrl1;\n\tEMC(EMC_PMACRO_CMD_CTRL_2) = params->emc_pmacro_cmd_ctrl2;\n\tEMC(EMC_PMACRO_IB_VREF_DQ_0) = params->emc_pmacro_ib_vref_dq_0;\n\tEMC(EMC_PMACRO_IB_VREF_DQ_1) = params->emc_pmacro_ib_vref_dq_1;\n\tEMC(EMC_PMACRO_IB_VREF_DQS_0) = params->emc_pmacro_ib_vref_dqs_0;\n\tEMC(EMC_PMACRO_IB_VREF_DQS_1) = params->emc_pmacro_ib_vref_dqs_1;\n\tEMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK0_0) = params->emc_pmacro_quse_ddll_rank0_0;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK0_1) = params->emc_pmacro_quse_ddll_rank0_1;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK0_2) = params->emc_pmacro_quse_ddll_rank0_2;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK0_3) = params->emc_pmacro_quse_ddll_rank0_3;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK0_4) = params->emc_pmacro_quse_ddll_rank0_4;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK0_5) = params->emc_pmacro_quse_ddll_rank0_5;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK1_0) = params->emc_pmacro_quse_ddll_rank1_0;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK1_1) = params->emc_pmacro_quse_ddll_rank1_1;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK1_2) = params->emc_pmacro_quse_ddll_rank1_2;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK1_3) = params->emc_pmacro_quse_ddll_rank1_3;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK1_4) = params->emc_pmacro_quse_ddll_rank1_4;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK1_5) = params->emc_pmacro_quse_ddll_rank1_5;\n\tEMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0) = params->emc_pmacro_ob_ddll_long_dq_rank0_0;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1) = params->emc_pmacro_ob_ddll_long_dq_rank0_1;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2) = params->emc_pmacro_ob_ddll_long_dq_rank0_2;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3) = params->emc_pmacro_ob_ddll_long_dq_rank0_3;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4) = params->emc_pmacro_ob_ddll_long_dq_rank0_4;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5) = params->emc_pmacro_ob_ddll_long_dq_rank0_5;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0) = params->emc_pmacro_ob_ddll_long_dq_rank1_0;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1) = params->emc_pmacro_ob_ddll_long_dq_rank1_1;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2) = params->emc_pmacro_ob_ddll_long_dq_rank1_2;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3) = params->emc_pmacro_ob_ddll_long_dq_rank1_3;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4) = params->emc_pmacro_ob_ddll_long_dq_rank1_4;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5) = params->emc_pmacro_ob_ddll_long_dq_rank1_5;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0) = params->emc_pmacro_ob_ddll_long_dqs_rank0_0;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1) = params->emc_pmacro_ob_ddll_long_dqs_rank0_1;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2) = params->emc_pmacro_ob_ddll_long_dqs_rank0_2;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3) = params->emc_pmacro_ob_ddll_long_dqs_rank0_3;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4) = params->emc_pmacro_ob_ddll_long_dqs_rank0_4;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5) = params->emc_pmacro_ob_ddll_long_dqs_rank0_5;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0) = params->emc_pmacro_ob_ddll_long_dqs_rank1_0;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1) = params->emc_pmacro_ob_ddll_long_dqs_rank1_1;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ob_ddll_long_dqs_rank1_2;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ob_ddll_long_dqs_rank1_3;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4) = params->emc_pmacro_ob_ddll_long_dqs_rank1_4;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5) = params->emc_pmacro_ob_ddll_long_dqs_rank1_5;\n\tEMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0) = params->emc_pmacro_ib_ddll_long_dqs_rank0_0;\n\tEMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1) = params->emc_pmacro_ib_ddll_long_dqs_rank0_1;\n\tEMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2) = params->emc_pmacro_ib_ddll_long_dqs_rank0_2;\n\tEMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3) = params->emc_pmacro_ib_ddll_long_dqs_rank0_3;\n\tEMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0) = params->emc_pmacro_ib_ddll_long_dqs_rank1_0;\n\tEMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1) = params->emc_pmacro_ib_ddll_long_dqs_rank1_1;\n\tEMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ib_ddll_long_dqs_rank1_2;\n\tEMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ib_ddll_long_dqs_rank1_3;\n\tEMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0;\n\tEMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1;\n\tEMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2;\n\tEMC(EMC_PMACRO_DDLL_LONG_CMD_3) = params->emc_pmacro_ddll_long_cmd_3;\n\tEMC(EMC_PMACRO_DDLL_LONG_CMD_4) = params->emc_pmacro_ddll_long_cmd_4;\n\tEMC(EMC_PMACRO_DDLL_SHORT_CMD_0) = params->emc_pmacro_ddll_short_cmd_0;\n\tEMC(EMC_PMACRO_DDLL_SHORT_CMD_1) = params->emc_pmacro_ddll_short_cmd_1;\n\tEMC(EMC_PMACRO_DDLL_SHORT_CMD_2) = params->emc_pmacro_ddll_short_cmd_2;\n\tEMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = (params->emc_pmacro_common_pad_tx_ctrl & 1) | 0xE;\n\tif (params->emc_bct_spare4)\n\t\t*(vu32 *)params->emc_bct_spare4 = params->emc_bct_spare5;\n\tEMC(EMC_TIMING_CONTROL) = 1;\n\tMC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom;\n\tMC(MC_VIDEO_PROTECT_BOM_ADR_HI) = params->mc_video_protect_bom_adr_hi;\n\tMC(MC_VIDEO_PROTECT_SIZE_MB) = params->mc_video_protect_size_mb;\n\tMC(MC_VIDEO_PROTECT_VPR_OVERRIDE) = params->mc_video_protect_vpr_override;\n\tMC(MC_VIDEO_PROTECT_VPR_OVERRIDE1) = params->mc_video_protect_vpr_override1;\n\tMC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = params->mc_video_protect_gpu_override0;\n\tMC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = params->mc_video_protect_gpu_override1;\n\tMC(MC_EMEM_ADR_CFG) = params->mc_emem_adr_cfg;\n\tMC(MC_EMEM_ADR_CFG_DEV0) = params->mc_emem_adr_cfg_dev0;\n\tMC(MC_EMEM_ADR_CFG_DEV1) = params->mc_emem_adr_cfg_dev1;\n\tMC(MC_EMEM_ADR_CFG_CHANNEL_MASK) = params->mc_emem_adr_cfg_channel_mask;\n\tMC(MC_EMEM_ADR_CFG_BANK_MASK_0) = params->mc_emem_adr_cfg_bank_mask0;\n\tMC(MC_EMEM_ADR_CFG_BANK_MASK_1) = params->mc_emem_adr_cfg_bank_mask1;\n\tMC(MC_EMEM_ADR_CFG_BANK_MASK_2) = params->mc_emem_adr_cfg_bank_mask2;\n\tMC(MC_EMEM_CFG) = params->mc_emem_cfg;\n\tMC(MC_SEC_CARVEOUT_BOM) = params->mc_sec_carveout_bom;\n\tMC(MC_SEC_CARVEOUT_ADR_HI) = params->mc_sec_carveout_adr_hi;\n\tMC(MC_SEC_CARVEOUT_SIZE_MB) = params->mc_sec_carveout_size_mb;\n\tMC(MC_MTS_CARVEOUT_BOM) = params->mc_mts_carveout_bom;\n\tMC(MC_MTS_CARVEOUT_ADR_HI) = params->mc_mts_carveout_adr_hi;\n\tMC(MC_MTS_CARVEOUT_SIZE_MB) = params->mc_mts_carveout_size_mb;\n\tMC(MC_EMEM_ARB_CFG) = params->mc_emem_arb_cfg;\n\tMC(MC_EMEM_ARB_OUTSTANDING_REQ) = params->mc_emem_arb_outstanding_req;\n\tMC(MC_EMEM_ARB_REFPB_HP_CTRL) = params->emc_emem_arb_refpb_hp_ctrl;\n\tMC(MC_EMEM_ARB_REFPB_BANK_CTRL) = params->emc_emem_arb_refpb_bank_ctrl;\n\tMC(MC_EMEM_ARB_TIMING_RCD) = params->mc_emem_arb_timing_rcd;\n\tMC(MC_EMEM_ARB_TIMING_RP) = params->mc_emem_arb_timing_rp;\n\tMC(MC_EMEM_ARB_TIMING_RC) = params->mc_emem_arb_timing_rc;\n\tMC(MC_EMEM_ARB_TIMING_RAS) = params->mc_emem_arb_timing_ras;\n\tMC(MC_EMEM_ARB_TIMING_FAW) = params->mc_emem_arb_timing_faw;\n\tMC(MC_EMEM_ARB_TIMING_RRD) = params->mc_emem_arb_timing_rrd;\n\tMC(MC_EMEM_ARB_TIMING_RAP2PRE) = params->mc_emem_arb_timing_rap2pre;\n\tMC(MC_EMEM_ARB_TIMING_WAP2PRE) = params->mc_emem_arb_timing_wap2pre;\n\tMC(MC_EMEM_ARB_TIMING_R2R) = params->mc_emem_arb_timing_r2r;\n\tMC(MC_EMEM_ARB_TIMING_W2W) = params->mc_emem_arb_timing_w2w;\n\tMC(MC_EMEM_ARB_TIMING_CCDMW) = params->mc_emem_arb_timing_ccdmw;\n\tMC(MC_EMEM_ARB_TIMING_R2W) = params->mc_emem_arb_timing_r2w;\n\tMC(MC_EMEM_ARB_TIMING_W2R) = params->mc_emem_arb_timing_w2r;\n\tMC(MC_EMEM_ARB_TIMING_RFCPB) = params->mc_emem_arb_timing_rfcpb;\n\tMC(MC_EMEM_ARB_DA_TURNS) = params->mc_emem_arb_da_turns;\n\tMC(MC_EMEM_ARB_DA_COVERS) = params->mc_emem_arb_da_covers;\n\tMC(MC_EMEM_ARB_MISC0) = params->mc_emem_arb_misc0;\n\tMC(MC_EMEM_ARB_MISC1) = params->mc_emem_arb_misc1;\n\tMC(MC_EMEM_ARB_MISC2) = params->mc_emem_arb_misc2;\n\tMC(MC_EMEM_ARB_RING1_THROTTLE) = params->mc_emem_arb_ring1_throttle;\n\tMC(MC_EMEM_ARB_OVERRIDE) = params->mc_emem_arb_override;\n\tMC(MC_EMEM_ARB_OVERRIDE_1) = params->mc_emem_arb_override1;\n\tMC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv;\n\tMC(MC_DA_CONFIG0) = params->mc_da_cfg0;\n\tMC(MC_TIMING_CONTROL) = 1;\n\tMC(MC_CLKEN_OVERRIDE) = params->mc_clken_override;\n\tMC(MC_STAT_CONTROL) = params->mc_stat_control;\n\tEMC(EMC_ADR_CFG) = params->emc_adr_cfg;\n\tEMC(EMC_CLKEN_OVERRIDE) = params->emc_clken_override;\n\tEMC(EMC_PMACRO_AUTOCAL_CFG_0) = params->emc_pmacro_auto_cal_cfg0;\n\tEMC(EMC_PMACRO_AUTOCAL_CFG_1) = params->emc_pmacro_auto_cal_cfg1;\n\tEMC(EMC_PMACRO_AUTOCAL_CFG_2) = params->emc_pmacro_auto_cal_cfg2;\n\tEMC(EMC_AUTO_CAL_VREF_SEL_0) = params->emc_auto_cal_vref_sel0;\n\tEMC(EMC_AUTO_CAL_VREF_SEL_1) = params->emc_auto_cal_vref_sel1;\n\tEMC(EMC_AUTO_CAL_INTERVAL) = params->emc_auto_cal_interval;\n\tEMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config;\n\tusleep(params->emc_auto_cal_wait);\n\tif (params->emc_bct_spare8)\n\t\t*(vu32 *)params->emc_bct_spare8 = params->emc_bct_spare9;\n\tEMC(EMC_CFG_2) = params->emc_cfg2;\n\tEMC(EMC_CFG_PIPE) = params->emc_cfg_pipe;\n\tEMC(EMC_CFG_PIPE_1) = params->emc_cfg_pipe1;\n\tEMC(EMC_CFG_PIPE_2) = params->emc_cfg_pipe2;\n\tEMC(EMC_CMDQ) = params->emc_cmd_q;\n\tEMC(EMC_MC2EMCQ) = params->emc_mc2emc_q;\n\tEMC(EMC_MRS_WAIT_CNT) = params->emc_mrs_wait_cnt;\n\tEMC(EMC_MRS_WAIT_CNT2) = params->emc_mrs_wait_cnt2;\n\tEMC(EMC_FBIO_CFG5) = params->emc_fbio_cfg5;\n\tEMC(EMC_RC) = params->emc_rc;\n\tEMC(EMC_RFC) = params->emc_rfc;\n\tEMC(EMC_RFCPB) = params->emc_rfc_pb;\n\tEMC(EMC_REFCTRL2) = params->emc_ref_ctrl2;\n\tEMC(EMC_RFC_SLR) = params->emc_rfc_slr;\n\tEMC(EMC_RAS) = params->emc_ras;\n\tEMC(EMC_RP) = params->emc_rp;\n\tEMC(EMC_TPPD) = params->emc_tppd;\n\tEMC(EMC_R2R) = params->emc_r2r;\n\tEMC(EMC_W2W) = params->emc_w2w;\n\tEMC(EMC_R2W) = params->emc_r2w;\n\tEMC(EMC_W2R) = params->emc_w2r;\n\tEMC(EMC_R2P) = params->emc_r2p;\n\tEMC(EMC_W2P) = params->emc_w2p;\n\tEMC(EMC_CCDMW) = params->emc_ccdmw;\n\tEMC(EMC_RD_RCD) = params->emc_rd_rcd;\n\tEMC(EMC_WR_RCD) = params->emc_wr_rcd;\n\tEMC(EMC_RRD) = params->emc_rrd;\n\tEMC(EMC_REXT) = params->emc_rext;\n\tEMC(EMC_WEXT) = params->emc_wext;\n\tEMC(EMC_WDV) = params->emc_wdv;\n\tEMC(EMC_WDV_CHK) = params->emc_wdv_chk;\n\tEMC(EMC_WSV) = params->emc_wsv;\n\tEMC(EMC_WEV) = params->emc_wev;\n\tEMC(EMC_WDV_MASK) = params->emc_wdv_mask;\n\tEMC(EMC_WS_DURATION) = params->emc_ws_duration;\n\tEMC(EMC_WE_DURATION) = params->emc_we_duration;\n\tEMC(EMC_QUSE) = params->emc_quse;\n\tEMC(EMC_QUSE_WIDTH) = params->emc_quse_width;\n\tEMC(EMC_IBDLY) = params->emc_ibdly;\n\tEMC(EMC_OBDLY) = params->emc_obdly;\n\tEMC(EMC_EINPUT) = params->emc_einput;\n\tEMC(EMC_EINPUT_DURATION) = params->emc_einput_duration;\n\tEMC(EMC_PUTERM_EXTRA) = params->emc_puterm_extra;\n\tEMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width;\n\tEMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = params->emc_pmacro_common_pad_tx_ctrl;\n\tEMC(EMC_DBG) = params->emc_dbg;\n\tEMC(EMC_QRST) = params->emc_qrst;\n\tEMC(EMC_ISSUE_QRST) = 0;\n\tEMC(EMC_QSAFE) = params->emc_qsafe;\n\tEMC(EMC_RDV) = params->emc_rdv;\n\tEMC(EMC_RDV_MASK) = params->emc_rdv_mask;\n\tEMC(EMC_RDV_EARLY) = params->emc_rdv_early;\n\tEMC(EMC_RDV_EARLY_MASK) = params->emc_rdv_early_mask;\n\tEMC(EMC_QPOP) = params->emc_qpop;\n\tEMC(EMC_REFRESH) = params->emc_refresh;\n\tEMC(EMC_BURST_REFRESH_NUM) = params->emc_burst_refresh_num;\n\tEMC(EMC_PRE_REFRESH_REQ_CNT) = params->emc_prerefresh_req_cnt;\n\tEMC(EMC_PDEX2WR) = params->emc_pdex2wr;\n\tEMC(EMC_PDEX2RD) = params->emc_pdex2rd;\n\tEMC(EMC_PCHG2PDEN) = params->emc_pchg2pden;\n\tEMC(EMC_ACT2PDEN) = params->emc_act2pden;\n\tEMC(EMC_AR2PDEN) = params->emc_ar2pden;\n\tEMC(EMC_RW2PDEN) = params->emc_rw2pden;\n\tEMC(EMC_CKE2PDEN) = params->emc_cke2pden;\n\tEMC(EMC_PDEX2CKE) = params->emc_pdex2che;\n\tEMC(EMC_PDEX2MRR) = params->emc_pdex2mrr;\n\tEMC(EMC_TXSR) = params->emc_txsr;\n\tEMC(EMC_TXSRDLL) = params->emc_txsr_dll;\n\tEMC(EMC_TCKE) = params->emc_tcke;\n\tEMC(EMC_TCKESR) = params->emc_tckesr;\n\tEMC(EMC_TPD) = params->emc_tpd;\n\tEMC(EMC_TFAW) = params->emc_tfaw;\n\tEMC(EMC_TRPAB) = params->emc_trpab;\n\tEMC(EMC_TCLKSTABLE) = params->emc_tclkstable;\n\tEMC(EMC_TCLKSTOP) = params->emc_tclkstop;\n\tEMC(EMC_TREFBW) = params->emc_trefbw;\n\tEMC(EMC_ODT_WRITE) = params->emc_odt_write;\n\tEMC(EMC_CFG_DIG_DLL) = params->emc_cfg_dig_dll;\n\tEMC(EMC_CFG_DIG_DLL_PERIOD) = params->emc_cfg_dig_dll_period;\n\tEMC(EMC_FBIO_SPARE) = params->emc_fbio_spare & 0xFFFFFFFD;\n\tEMC(EMC_CFG_RSV) = params->emc_cfg_rsv;\n\tEMC(EMC_PMC_SCRATCH1) = params->emc_pmc_scratch1;\n\tEMC(EMC_PMC_SCRATCH2) = params->emc_pmc_scratch2;\n\tEMC(EMC_PMC_SCRATCH3) = params->emc_pmc_scratch3;\n\tEMC(EMC_ACPD_CONTROL) = params->emc_acpd_control;\n\tEMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen;\n\tEMC(EMC_CFG) = (params->emc_cfg & 0xE) | 0x3C00000;\n\tif (params->boot_rom_patch_control & 0x80000000)\n\t{\n\t\t*(vu32 *)(4 * (params->boot_rom_patch_control + 0x1C000000)) = params->boot_rom_patch_data;\n\t\tMC(MC_TIMING_CONTROL) = 1;\n\t}\n\tPMC(APBDEV_PMC_IO_DPD3_REQ) = ((4 * params->emc_pmc_scratch1 >> 2) + 0x40000000) & 0xCFFF0000;\n\tusleep(params->pmc_io_dpd3_req_wait);\n\tif (!params->emc_auto_cal_interval)\n\t\tEMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config | 0x200;\n\tEMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2;\n\tif (params->emc_zcal_warm_cold_boot_enables & 1)\n\t{\n\t\tif (params->memory_type == 2)\n\t\t\tEMC(EMC_ZCAL_WAIT_CNT) = 8 * params->emc_zcal_wait_cnt;\n\t\tif (params->memory_type == 3)\n\t\t{\n\t\t\tEMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;\n\t\t\tEMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;\n\t\t}\n\t}\n\tEMC(EMC_TIMING_CONTROL) = 1;\n\tusleep(params->emc_timing_control_wait);\n\tPMC(APBDEV_PMC_DDR_CNTRL) &= 0xFFF8007F;\n\tusleep(params->pmc_ddr_ctrl_wait);\n\tif (params->memory_type == 2)\n\t{\n\t\tEMC(EMC_PIN) = (params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12);\n\t\tusleep(params->emc_pin_extra_wait + 200);\n\t\tEMC(EMC_PIN) = ((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 256;\n\t\tusleep(params->emc_pin_extra_wait + 500);\n\t}\n\tif (params->memory_type == 3)\n\t{\n\t\tEMC(EMC_PIN) = (params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12);\n\t\tusleep(params->emc_pin_extra_wait + 200);\n\t\tEMC(EMC_PIN) = ((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 256;\n\t\tusleep(params->emc_pin_extra_wait + 2000);\n\t}\n\tEMC(EMC_PIN) = ((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 0x101;\n\tusleep(params->emc_pin_program_wait);\n\tif (params->memory_type != 3)\n\t\tEMC(EMC_NOP) = (params->emc_dev_select << 30) + 1;\n\tif (params->memory_type == 1)\n\t\tusleep(params->emc_pin_extra_wait + 200);\n\tif (params->memory_type == 3)\n\t{\n\t\tif (params->emc_bct_spare10)\n\t\t\t*(vu32 *)params->emc_bct_spare10 = params->emc_bct_spare11;\n\t\tEMC(EMC_MRW2) = params->emc_mrw2;\n\t\tEMC(EMC_MRW) = params->emc_mrw1;\n\t\tEMC(EMC_MRW3) = params->emc_mrw3;\n\t\tEMC(EMC_MRW4) = params->emc_mrw4;\n\t\tEMC(EMC_MRW6) = params->emc_mrw6;\n\t\tEMC(EMC_MRW14) = params->emc_mrw14;\n\t\tEMC(EMC_MRW8) = params->emc_mrw8;\n\t\tEMC(EMC_MRW12) = params->emc_mrw12;\n\t\tEMC(EMC_MRW9) = params->emc_mrw9;\n\t\tEMC(EMC_MRW13) = params->emc_mrw13;\n\t\tif (params->emc_zcal_warm_cold_boot_enables & 1)\n\t\t{\n\t\t\tEMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0;\n\t\t\tusleep(params->emc_zcal_init_wait);\n\t\t\tEMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0 ^ 3;\n\t\t\tif (!(params->emc_dev_select & 2))\n\t\t\t{\n\t\t\t\tEMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1;\n\t\t\t\tusleep(params->emc_zcal_init_wait);\n\t\t\t\tEMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1 ^ 3;\n\t\t\t}\n\t\t}\n\t}\n\tPMC(APBDEV_PMC_DDR_CFG) = params->pmc_ddr_cfg;\n\tif (params->memory_type - 1 <= 2)\n\t{\n\t\tEMC(EMC_ZCAL_INTERVAL) = params->emc_zcal_interval;\n\t\tEMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;\n\t\tEMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;\n\t}\n\tif (params->emc_bct_spare12)\n\t\t*(vu32 *)params->emc_bct_spare12 = params->emc_bct_spare13;\n\tEMC(EMC_TIMING_CONTROL) = 1;\n\tif (params->emc_extra_refresh_num)\n\t\tEMC(EMC_REF) = ((1 << params->emc_extra_refresh_num << 8) - 0xFD) | (params->emc_pin_gpio << 30);\n\tEMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000;\n\tEMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;\n\tEMC(EMC_CFG_UPDATE) = params->emc_cfg_update;\n\tEMC(EMC_CFG) = params->emc_cfg;\n\tEMC(EMC_FDPD_CTRL_DQ) = params->emc_fdpd_ctrl_dq;\n\tEMC(EMC_FDPD_CTRL_CMD) = params->emc_fdpd_ctrl_cmd;\n\tEMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;\n\tEMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2;\n\tEMC(EMC_TIMING_CONTROL) = 1;\n\tEMC(EMC_CFG_PIPE_CLK) = params->emc_cfg_pipe_clk;\n\tEMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = params->emc_fdpd_ctrl_cmd_no_ramp;\n\tSYSREG(AHB_ARBITRATION_XBAR_CTRL) = (SYSREG(AHB_ARBITRATION_XBAR_CTRL) & 0xFFFEFFFF) | ((params->ahb_arbitration_xbar_ctrl_meminit_done & 0xFFFF) << 16);\n\tMC(MC_VIDEO_PROTECT_REG_CTRL) = params->mc_video_protect_write_access;\n\tMC(MC_SEC_CARVEOUT_REG_CTRL) = params->mc_sec_carveout_protect_write_access;\n\tMC(MC_MTS_CARVEOUT_REG_CTRL) = params->mc_mts_carveout_reg_ctrl;\n\tMC(MC_EMEM_CFG_ACCESS_CTRL) = 1; //Disable write access to a bunch of EMC registers.\n}\n\nconst void *sdram_get_params()\n{\n\t//TODO: sdram_id should be in [0, 7].\n\n#ifdef CONFIG_SDRAM_COMPRESS_CFG\n\tu8 *buf = (u8 *)0x40030000;\n\tLZ_Uncompress(_dram_cfg_lz, buf, sizeof(_dram_cfg_lz));\n\treturn (const void *)&buf[sizeof(sdram_params_t) * get_sdram_id()];\n#else\n\treturn _dram_cfgs[get_sdram_id()];\n#endif\n}\n\nvoid sdram_init()\n{\n\t//TODO: sdram_id should be in [0,4].\n\tconst sdram_params_t *params = (const sdram_params_t *)sdram_get_params();\n\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, 0x05);\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD1, 40); //40 = (1000 * 1100 - 600000) / 12500 -> 1.1V\n\n\tPMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel;\n\tusleep(params->pmc_vddp_sel_wait);\n\tPMC(APBDEV_PMC_DDR_PWR) = PMC(APBDEV_PMC_DDR_PWR);\n\tPMC(APBDEV_PMC_NO_IOPOWER) = params->pmc_no_io_power;\n\tPMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short;\n\tPMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl;\n\n\tif (params->emc_bct_spare0)\n\t\t*(vu32 *)params->emc_bct_spare0 = params->emc_bct_spare1;\n\n\t_sdram_config(params);\n}\n"
  },
  {
    "path": "argon-first-stage/src/power/bq24193.c",
    "content": "/*\n * Battery charger driver for Nintendo Switch's TI BQ24193\n *\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"power/bq24193.h\"\n#include \"soc/i2c.h\"\n#include \"utils/util.h\"\n\nint bq24193_get_property(enum BQ24193_reg_prop prop, int *value)\n{\n\tu8 data;\n\n\tswitch (prop) {\n\t\tcase BQ24193_InputVoltageLimit: // Input voltage limit (mV).\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_InputSource);\n\t\t\tdata = (data & BQ24193_INCONFIG_VINDPM_MASK) >> 3;\n\t\t\t*value += ((data >> 0) & 1) ? 80 : 0;\n\t\t\t*value += ((data >> 1) & 1) ? 160 : 0;\n\t\t\t*value += ((data >> 2) & 1) ? 320 : 0;\n\t\t\t*value += ((data >> 3) & 1) ? 640 : 0;\n\t\t\t*value += 3880;\n\t\t\tbreak;\n\t\tcase BQ24193_InputCurrentLimit: // Input current limit (mA).\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_InputSource);\n\t\t\tdata &= BQ24193_INCONFIG_INLIMIT_MASK;\n\t\t\tswitch (data)\n\t\t\t{\n\t\t\tcase 0:\n\t\t\t\t*value = 100;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\t*value = 150;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\t*value = 500;\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\t*value = 900;\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\t*value = 1200;\n\t\t\t\tbreak;\n\t\t\tcase 5:\n\t\t\t\t*value = 1500;\n\t\t\t\tbreak;\n\t\t\tcase 6:\n\t\t\t\t*value = 2000;\n\t\t\t\tbreak;\n\t\t\tcase 7:\n\t\t\t\t*value = 3000;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase BQ24193_SystemMinimumVoltage: // Minimum system voltage limit (mV).\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_PORConfig);\n\t\t\t*value = (data & BQ24193_PORCONFIG_SYSMIN_MASK) >> 1;\n\t\t\t*value *= 100;\n\t\t\t*value += 3000;\n\t\t\tbreak;\n\t\tcase BQ24193_FastChargeCurrentLimit: // Fast charge current limit (mA).\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgCurr);\n\t\t\tdata = (data & BQ24193_CHRGCURR_ICHG_MASK) >> 2;\n\t\t\t*value += ((data >> 0) & 1) ? 64 : 0;\n\t\t\t*value += ((data >> 1) & 1) ? 128 : 0;\n\t\t\t*value += ((data >> 2) & 1) ? 256 : 0;\n\t\t\t*value += ((data >> 3) & 1) ? 512 : 0;\n\t\t\t*value += ((data >> 4) & 1) ? 1024 : 0;\n\t\t\t*value += ((data >> 5) & 1) ? 2048 : 0;\n\t\t\t*value += 512;\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgCurr);\n\t\t\tdata &= BQ24193_CHRGCURR_20PCT_MASK;\n\t\t\tif (data)\n\t\t\t\t*value = *value * 20 / 100; // Fast charge current limit is 20%.\n\t\t\tbreak;\n\t\tcase BQ24193_ChargeVoltageLimit: // Charge voltage limit (mV).\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgVolt);\n\t\t\tdata = (data & BQ24193_CHRGVOLT_VREG) >> 2; \n\t\t\t*value += ((data >> 0) & 1) ? 16 : 0;\n\t\t\t*value += ((data >> 1) & 1) ? 32 : 0;\n\t\t\t*value += ((data >> 2) & 1) ? 64 : 0;\n\t\t\t*value += ((data >> 3) & 1) ? 128 : 0;\n\t\t\t*value += ((data >> 4) & 1) ? 256 : 0;\n\t\t\t*value += ((data >> 5) & 1) ? 512 : 0;\n\t\t\t*value += 3504;\n\t\t\tbreak;\n\t\tcase BQ24193_RechargeThreshold: // Recharge voltage threshold less than voltage limit (mV).\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgVolt);\n\t\t\tdata &= BQ24193_IRTHERMAL_THERM_MASK;\n\t\t\tif (data)\n\t\t\t\t*value = 300;\n\t\t\telse\n\t\t\t\t*value = 100;\n\t\t\tbreak;\n\t\tcase BQ24193_ThermalRegulation: // Thermal regulation threshold (oC).\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_IRCompThermal);\n\t\t\tdata &= BQ24193_IRTHERMAL_THERM_MASK;\n\t\t\tswitch (data)\n\t\t\t{\n\t\t\tcase 0:\n\t\t\t\t*value = 60;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\t*value = 80;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\t*value = 100;\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\t*value = 120;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase BQ24193_ChargeStatus: // 0: Not charging, 1: Pre-charge, 2: Fast charging, 3: Charge termination done\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_Status);\n\t\t\t*value = (data & BQ24193_STATUS_CHRG_MASK) >> 4;\n\t\t\tbreak;\n\t\tcase BQ24193_TempStatus: // 0: Normal, 2: Warm, 3: Cool, 5: Cold, 6: Hot.\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_FaultReg);\n\t\t\t*value = data & BQ24193_FAULT_THERM_MASK;\n\t\t\tbreak;\n\t\tcase BQ24193_DevID: // Dev ID.\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_VendorPart);\n\t\t\t*value = data & BQ24193_VENDORPART_DEV_MASK;\n\t\t\tbreak;\n\t\tcase BQ24193_ProductNumber: // Product number.\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_VendorPart);\n\t\t\t*value = (data & BQ24193_VENDORPART_PN_MASK) >> 3;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nvoid bq24193_fake_battery_removal()\n{\n\tu8  value;\n\n\t// Disable watchdog to keep BATFET disabled.\n\tvalue = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgTermTimer);\n\tvalue &= ~BQ24193_CHRGTERM_WATCHDOG_MASK;\n\ti2c_send_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgTermTimer, value);\n\n\t// Force BATFET to disabled state. This disconnects the battery from the system.\n\tvalue = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_Misc);\n\tvalue |= BQ24193_MISC_BATFET_DI_MASK;\n\ti2c_send_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_Misc, value);\n}"
  },
  {
    "path": "argon-first-stage/src/power/max17050.c",
    "content": "/*\n * Fuel gauge driver for Nintendo Switch's Maxim 17050\n *\n * Copyright (C) 2011 Samsung Electronics\n * MyungJoo Ham <myungjoo.ham@samsung.com>\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n *\n * This driver is based on max17040_battery.c\n */\n\n#include \"power/max17050.h\"\n#include \"soc/i2c.h\"\n#include \"utils/util.h\"\n\n/* Status register bits */\n#define STATUS_POR_BIT (1 << 1)\n#define STATUS_BST_BIT (1 << 3)\n#define STATUS_VMN_BIT (1 << 8)\n#define STATUS_TMN_BIT (1 << 9)\n#define STATUS_SMN_BIT (1 << 10)\n#define STATUS_BI_BIT  (1 << 11)\n#define STATUS_VMX_BIT (1 << 12)\n#define STATUS_TMX_BIT (1 << 13)\n#define STATUS_SMX_BIT (1 << 14)\n#define STATUS_BR_BIT  (1 << 15)\n\n#define VFSOC0_LOCK   0x0000\n#define VFSOC0_UNLOCK 0x0080\n\n#define MAX17050_VMAX_TOLERANCE 50 /* 50 mV */\n\nint max17050_get_property(enum MAX17050_reg reg, int *value)\n{\n\tu16 data;\n\n\tswitch (reg)\n\t{\n\tcase MAX17050_Age: // Age (percent). Based on 100% x (FullCAP Register/DesignCap).\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_Age);\n\t\t*value = data >> 8; /* Show MSB. 1% increments */\n\t\tbreak;\n\tcase MAX17050_Cycles: // Cycle count.\n\t\ti2c_recv_buf_small((u8 *)value, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_Cycles);\n\t\tbreak;\n\tcase MAX17050_MinVolt: // Voltage max/min\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MinMaxVolt);\n\t\t*value = (data & 0xff) * 20; /* Voltage MIN. Units of 20mV */\n\t\tbreak;\n\tcase MAX17050_MaxVolt: // Voltage max/min\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MinMaxVolt);\n\t\t*value = (data >> 8) * 20; /* Voltage MAX. Units of LSB = 20mV */\n\t\tbreak;\n\tcase MAX17050_V_empty: // Voltage min design.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_V_empty);\n\t\t*value = (data >> 7) * 10; /* Units of LSB = 10mV */\n\t\tbreak;\n\tcase MAX17050_VCELL: // Voltage now.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_VCELL);\n\t\t*value = data * 625 / 8 / 1000;\n\t\tbreak;\n\tcase MAX17050_AvgVCELL: // Voltage avg.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_AvgVCELL);\n\t\t*value = data * 625 / 8 / 1000;\n\t\tbreak;\n\tcase MAX17050_OCVInternal: // Voltage ocv.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_OCVInternal);\n\t\t*value = data * 625 / 8 / 1000;\n\t\tbreak;\n\tcase MAX17050_RepSOC: // Capacity %.\n\t\ti2c_recv_buf_small((u8 *)value, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_RepSOC);\n\t\tbreak;\n\tcase MAX17050_DesignCap: // Charge full design.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_DesignCap);\n\t\tdata = data * 5 / 10;\n\t\t*value = data;\n\t\tbreak;\n\tcase MAX17050_FullCAP: // Charge full.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_FullCAP);\n\t\tdata = data * 5 / 10;\n\t\t*value = data;\n\t\tbreak;\n\tcase MAX17050_RepCap: // Charge now.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_RepCap);\n\t\tdata = data * 5 / 10;\n\t\t*value = data;\n\t\tbreak;\n\tcase MAX17050_TEMP: // Temp.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_TEMP);\n\t\t*value = (s16)data;\n\t\t*value = *value * 10 / 256;\n\t\tbreak;\n\tcase MAX17050_Current: // Current now.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_Current);\n\t\t*value = (s16)data;\n\t\t*value *= 1562500 / MAX17050_DEFAULT_SNS_RESISTOR;\n\t\tbreak;\n\tcase MAX17050_AvgCurrent: // Current avg.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_AvgCurrent);\n\t\t*value = (s16)data;\n\t\t*value *= 1562500 / MAX17050_DEFAULT_SNS_RESISTOR;\n\t\tbreak;\n\tdefault:\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nstatic int _max17050_write_verify_reg(u8 reg, u16 value)\n{\n\tint retries = 8;\n\tint ret;\n\tu16 read_value;\n\n\tdo\n\t{\n\t\tret = i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, reg, (u8 *)&value, 2);\n\t\ti2c_recv_buf_small((u8 *)&read_value, 2, I2C_1, MAXIM17050_I2C_ADDR, reg);\n\t\tif (read_value != value)\n\t\t{\n\t\t\tret = -1;\n\t\t\tretries--;\n\t\t}\n\t} while (retries && read_value != value);\n\n\treturn ret;\n}\n\nstatic void _max17050_override_por(u8 reg, u16 value)\n{\n\tif (value)\n\t\ti2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, reg, (u8 *)&value, 2);\n}\n\nstatic void _max17050_load_new_capacity_params()\n{\n\tu16 fullcap, repSoc, dq_acc, dp_acc;\n\n\tfullcap = 0x2476; // 4667mAh design capacity.\n\tdq_acc = 0x10bc;  // From a healthy fuel gauge.\n\tdp_acc = 0x5e09;  //          =||=\n\trepSoc = 0x6400;  // 100%.\n\n\t_max17050_write_verify_reg(MAX17050_RemCap, fullcap);\n\t_max17050_write_verify_reg(MAX17050_RepCap, fullcap);\n\n\t_max17050_write_verify_reg(MAX17050_dQacc, dq_acc);\n\t_max17050_write_verify_reg(MAX17050_dPacc, dp_acc);\n\n\t_max17050_write_verify_reg(MAX17050_FullCAP, fullcap);\n\t//i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_DesignCap, (u8 *)&fullcap, 2);\n\t_max17050_write_verify_reg(MAX17050_FullCAPNom, fullcap);\n\t/* Update SOC register with new SOC */\n\ti2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_RepSOC, (u8 *)&repSoc, 2);\n}\n\nstatic void _max17050_reset_vfsoc0_reg()\n{\n\tu16 lockVal = 0;\n\tu16 vfSoc = 0x6440; // >100% for fully charged battery\n\n\tlockVal = VFSOC0_UNLOCK;\n\ti2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_VFSOC0Enable, (u8 *)&lockVal, 2);\n\n\t_max17050_write_verify_reg(MAX17050_VFSOC0, vfSoc);\n\n\tlockVal = VFSOC0_LOCK;\n\ti2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_VFSOC0Enable, (u8 *)&lockVal, 2);\n}\n\nstatic void _max17050_update_capacity_regs()\n{\n\tu16 value = 0x2476; // Set to 4667mAh design capacity.\n\t_max17050_write_verify_reg(MAX17050_FullCAP, value);\n\t_max17050_write_verify_reg(MAX17050_FullCAPNom, value);\n\t//i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_DesignCap, config->design_cap, 2);\n}\n\nstatic void _max17050_write_config_regs()\n{\n\tu16 value = 0;\n\n\tvalue = 0x7254;\n\ti2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_CONFIG, (u8 *)&value, 2);\n\tvalue = 0x2473;\n\ti2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_LearnCFG, (u8 *)&value, 2);\n\t//i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_FilterCFG, (u8 *)&value, 2)\n\t//i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_RelaxCFG, (u8 *)&value, 2)\n\t//i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_FullSOCThr, (u8 *)&value, 2)\n}\n\n/*\n * Block write all the override values coming from platform data.\n * This function MUST be called before the POR initialization proceedure\n * specified by maxim.\n */\nstatic void _max17050_override_por_values()\n{\n\tu16 dq_acc = 0x10bc; // From a healthy fuel gauge.\n\tu16 dp_acc = 0x5e09; //           =||=\n\n\t_max17050_override_por(MAX17050_dQacc, dq_acc);\n\t_max17050_override_por(MAX17050_dPacc, dp_acc);\n\n\t//_max17050_override_por(MAX17050_RCOMP0, config->rcomp0);  //0x58\n\t//_max17050_override_por(MAX17050_TempCo, config->tcompc0); //0x1b22\n\n\t//u16 k_empty0 = 0x439;\n\t//_max17050_override_por(map, MAX17050_K_empty0, k_empty0); // Unknown cell data\n}\n\nstatic void _max17050_set_por_bit(u16 value)\n{\n\t_max17050_write_verify_reg(MAX17050_STATUS, value);\n}\n\nint max17050_fix_configuration()\n{\n\t/* Init phase, set the POR bit */\n\t_max17050_set_por_bit(STATUS_POR_BIT);\n\n\t/* Override POR values */\n\t_max17050_override_por_values();\n\t/* After Power up, the MAX17050 requires 500ms in order\n\t * to perform signal debouncing and initial SOC reporting\n\t */\n\tmsleep(500);\n\n\t/* Initialize configaration */\n\t_max17050_write_config_regs();\n\n\t/* update capacity params */\n\t_max17050_update_capacity_regs();\n\n\t/* delay must be atleast 350mS to allow VFSOC\n\t * to be calculated from the new configuration\n\t */\n\tmsleep(350);\n\n\t/* reset vfsoc0 reg */\n\t_max17050_reset_vfsoc0_reg();\n\n\t/* load new capacity params */\n\t_max17050_load_new_capacity_params();\n\n\t/* Init complete, Clear the POR bit */\n\t//_max17050_set_por_bit(0); // Should we? Or let the switch to reconfigure POR?\n\n\t// Sets POR, BI, BR. \n\t_max17050_set_por_bit(0x8801);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "argon-first-stage/src/power/max7762x.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2019 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"power/max7762x.h\"\n#include \"power/max77620.h\"\n#include \"soc/i2c.h\"\n#include \"utils/util.h\"\n\n#define REGULATOR_SD 0\n#define REGULATOR_LDO 1\n\ntypedef struct _max77620_regulator_t\n{\n\tu8 type;\n\tconst char *name;\n\tu8 reg_sd;\n\n\tu32 mv_step;\n\tu32 mv_min;\n\tu32 mv_default;\n\tu32 mv_max;\n\n\tu8 volt_addr;\n\tu8 cfg_addr;\n\n\tu8 volt_mask;\n\tu8 enable_mask;\n\tu8 enable_shift;\n\tu8 status_mask;\n\n\tu8 fps_addr;\n\tu8 fps_src;\n\tu8 pd_period;\n\tu8 pu_period;\n} max77620_regulator_t;\n\nstatic const max77620_regulator_t _pmic_regulators[] = {\n\t{  REGULATOR_SD,  \"sd0\", 0x16,  12500, 600000,  625000, 1400000,      MAX77620_REG_SD0,   MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK,  MAX77620_SD_POWER_MODE_SHIFT,  0x80,  MAX77620_REG_FPS_SD0,  1, 7, 1 },\n\t{  REGULATOR_SD,  \"sd1\", 0x17,  12500, 600000, 1125000, 1125000,      MAX77620_REG_SD1,   MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK,  MAX77620_SD_POWER_MODE_SHIFT,  0x40,  MAX77620_REG_FPS_SD1,  0, 1, 5 },\n\t{  REGULATOR_SD,  \"sd2\", 0x18,  12500, 600000, 1325000, 1350000,      MAX77620_REG_SD2,   MAX77620_REG_SD2_CFG, MAX77620_SDX_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK,  MAX77620_SD_POWER_MODE_SHIFT,  0x20,  MAX77620_REG_FPS_SD2,  1, 5, 2 },\n\t{  REGULATOR_SD,  \"sd3\", 0x19,  12500, 600000, 1800000, 1800000,      MAX77620_REG_SD3,   MAX77620_REG_SD3_CFG, MAX77620_SDX_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK,  MAX77620_SD_POWER_MODE_SHIFT,  0x10,  MAX77620_REG_FPS_SD3,  0, 3, 3 },\n\t{ REGULATOR_LDO, \"ldo0\", 0x00,  25000, 800000, 1200000, 1200000, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO0, 3, 7, 0 },\n\t{ REGULATOR_LDO, \"ldo1\", 0x00,  25000, 800000, 1050000, 1050000, MAX77620_REG_LDO1_CFG, MAX77620_REG_LDO1_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO1, 3, 7, 0 },\n\t{ REGULATOR_LDO, \"ldo2\", 0x00,  50000, 800000, 1800000, 3300000, MAX77620_REG_LDO2_CFG, MAX77620_REG_LDO2_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO2, 3, 7, 0 },\n\t{ REGULATOR_LDO, \"ldo3\", 0x00,  50000, 800000, 3100000, 3100000, MAX77620_REG_LDO3_CFG, MAX77620_REG_LDO3_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO3, 3, 7, 0 },\n\t{ REGULATOR_LDO, \"ldo4\", 0x00,  12500, 800000,  850000,  850000, MAX77620_REG_LDO4_CFG, MAX77620_REG_LDO4_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO4, 0, 7, 1 },\n\t{ REGULATOR_LDO, \"ldo5\", 0x00,  50000, 800000, 1800000, 1800000, MAX77620_REG_LDO5_CFG, MAX77620_REG_LDO5_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO5, 3, 7, 0 },\n\t{ REGULATOR_LDO, \"ldo6\", 0x00,  50000, 800000, 2900000, 2900000, MAX77620_REG_LDO6_CFG, MAX77620_REG_LDO6_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO6, 3, 7, 0 },\n\t{ REGULATOR_LDO, \"ldo7\", 0x00,  50000, 800000, 1050000, 1050000, MAX77620_REG_LDO7_CFG, MAX77620_REG_LDO7_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO7, 1, 4, 3 },\n\t{ REGULATOR_LDO, \"ldo8\", 0x00,  50000, 800000, 1050000, 1050000, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO8, 3, 7, 0 }\n};\n\nint max77620_regulator_get_status(u32 id)\n{\n\tif (id > REGULATOR_MAX)\n\t\treturn 0;\n\n\tconst max77620_regulator_t *reg = &_pmic_regulators[id];\n\n\tif (reg->type == REGULATOR_SD)\n\t\treturn (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_STATSD) & reg->status_mask) ? 0 : 1;\n\treturn (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg->cfg_addr) & 8) ? 1 : 0;\n}\n\nint max77620_regulator_config_fps(u32 id)\n{\n\tif (id > REGULATOR_MAX)\n\t\treturn 0;\n\n\tconst max77620_regulator_t *reg = &_pmic_regulators[id];\n\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->fps_addr,\n\t\t(reg->fps_src << MAX77620_FPS_SRC_SHIFT) | (reg->pu_period << MAX77620_FPS_PU_PERIOD_SHIFT) | (reg->pd_period));\n\n\treturn 1;\n}\n\nint max77620_regulator_set_voltage(u32 id, u32 mv)\n{\n\tif (id > REGULATOR_MAX)\n\t\treturn 0;\n\n\tconst max77620_regulator_t *reg = &_pmic_regulators[id];\n\n\tif (mv < reg->mv_min || mv > reg->mv_max)\n\t\treturn 0;\n\n\tu32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;\n\tu8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr);\n\tval = (val & ~reg->volt_mask) | (mult & reg->volt_mask);\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr, val);\n\tusleep(1000);\n\n\treturn 1;\n}\n\nint max77620_regulator_enable(u32 id, int enable)\n{\n\tif (id > REGULATOR_MAX)\n\t\treturn 0;\n\n\tconst max77620_regulator_t *reg = &_pmic_regulators[id];\n\n\tu32 addr = reg->type == REGULATOR_SD ? reg->cfg_addr : reg->volt_addr;\n\tu8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, addr);\n\tif (enable)\n\t\tval = (val & ~reg->enable_mask) | ((MAX77620_POWER_MODE_NORMAL << reg->enable_shift) & reg->enable_mask);\n\telse\n\t\tval &= ~reg->enable_mask;\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, addr, val);\n\tusleep(1000);\n\n\treturn 1;\n}\n\nint max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags)\n{\n\tif (id > REGULATOR_MAX)\n\t\treturn 0;\n\n\tconst max77620_regulator_t *reg = &_pmic_regulators[id];\n\n\tif (mv < reg->mv_min || mv > reg->mv_max)\n\t\treturn 0;\n\n\tu32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;\n\tu8 val = ((flags << reg->enable_shift) & ~reg->volt_mask) | (mult & reg->volt_mask);\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr, val);\n\tusleep(1000);\n\n\treturn 1;\n}\n\nvoid max77620_config_default()\n{\n\tfor (u32 i = 1; i <= REGULATOR_MAX; i++)\n\t{\n\t\ti2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CID4);\n\t\tmax77620_regulator_config_fps(i);\n\t\tmax77620_regulator_set_voltage(i, _pmic_regulators[i].mv_default);\n\t\tif (_pmic_regulators[i].fps_src != MAX77620_FPS_SRC_NONE)\n\t\t\tmax77620_regulator_enable(i, 1);\n\t}\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, 4);\n}\n\nvoid max77620_low_battery_monitor_config()\n{\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGGLBL1,\n\t\tMAX77620_CNFGGLBL1_LBDAC_EN | MAX77620_CNFGGLBL1_LBHYST_N | MAX77620_CNFGGLBL1_LBDAC_N);\n}\n"
  },
  {
    "path": "argon-first-stage/src/sec/se.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 CTCaer\n * Copyright (c) 2018 Atmosphère-NX\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"sec/se.h\"\n#include \"mem/heap.h\"\n#include \"soc/t210.h\"\n#include \"sec/se_t210.h\"\n#include \"utils/util.h\"\n\ntypedef struct _se_ll_t\n{\n\tvu32 num;\n\tvu32 addr;\n\tvu32 size;\n} se_ll_t;\n\nstatic void _gf256_mul_x(void *block)\n{\n\tu8 *pdata = (u8 *)block;\n\tu32 carry = 0;\n\n\tfor (u32 i = 0xF; i >= 0; i--)\n\t{\n\t\tu8 b = pdata[i];\n\t\tpdata[i] = (b << 1) | carry;\n\t\tcarry = b >> 7;\n\t}\n\n\tif (carry)\n\t\tpdata[0xF] ^= 0x87;\n}\n\nstatic void _se_ll_init(se_ll_t *ll, u32 addr, u32 size)\n{\n\tll->num = 0;\n\tll->addr = addr;\n\tll->size = size;\n}\n\nstatic void _se_ll_set(se_ll_t *dst, se_ll_t *src)\n{\n\tSE(SE_IN_LL_ADDR_REG_OFFSET) = (u32)src;\n\tSE(SE_OUT_LL_ADDR_REG_OFFSET) = (u32)dst;\n}\n\nstatic int _se_wait()\n{\n\twhile (!(SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_OP_DONE(INT_SET)))\n\t\t;\n\tif (SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_ERROR(INT_SET) ||\n\t\tSE(SE_STATUS_0) & 3 ||\n\t\tSE(SE_ERR_STATUS_0) != 0)\n\t\treturn 0;\n\treturn 1;\n}\n\nstatic int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size)\n{\n\tse_ll_t *ll_dst = NULL, *ll_src = NULL;\n\n\tif (dst)\n\t{\n\t\tll_dst = (se_ll_t *)malloc(sizeof(se_ll_t));\n\t\t_se_ll_init(ll_dst, (u32)dst, dst_size);\n\t}\n\n\tif (src)\n\t{\n\t\tll_src = (se_ll_t *)malloc(sizeof(se_ll_t));\n\t\t_se_ll_init(ll_src, (u32)src, src_size);\n\t}\n\n\t_se_ll_set(ll_dst, ll_src);\n\n\tSE(SE_ERR_STATUS_0) = SE(SE_ERR_STATUS_0);\n\tSE(SE_INT_STATUS_REG_OFFSET) = SE(SE_INT_STATUS_REG_OFFSET);\n\tSE(SE_OPERATION_REG_OFFSET) = SE_OPERATION(op);\n\n\tint res = _se_wait();\n\n\tif (src)\n\t\tfree(ll_src);\n\tif (dst)\n\t\tfree(ll_dst);\n\n\treturn res;\n}\n\nstatic int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size)\n{\n\tif (!src || !dst)\n\t\treturn 0;\n\n\tu8 *block = (u8 *)malloc(0x10);\n\tmemset(block, 0, 0x10);\n\n\tSE(SE_BLOCK_COUNT_REG_OFFSET) = 0;\n\n\tmemcpy(block, src, src_size);\n\tint res = _se_execute(op, block, 0x10, block, 0x10);\n\tmemcpy(dst, block, dst_size);\n\t\n\tfree(block);\n\treturn res;\n}\n\nstatic void _se_aes_ctr_set(void *ctr)\n{\n\tu32 *data = (u32 *)ctr;\n\tfor (u32 i = 0; i < 4; i++)\n\t\tSE(SE_CRYPTO_CTR_REG_OFFSET + 4 * i) = data[i];\n}\n\nvoid se_rsa_acc_ctrl(u32 rs, u32 flags)\n{\n\tif (flags & 0x7F)\n\t\tSE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + 4 * rs) = (((flags >> 4) & 4) | (flags & 3)) ^ 7;\n\tif (flags & 0x80)\n\t\tSE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~(1 << rs);\n}\n\nvoid se_key_acc_ctrl(u32 ks, u32 flags)\n{\n\tif (flags & 0x7F)\n\t\tSE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks) = ~flags;\n\tif (flags & 0x80)\n\t\tSE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~(1 << ks);\n}\n\nvoid se_aes_key_set(u32 ks, void *key, u32 size)\n{\n\tu32 *data = (u32 *)key;\n\tfor (u32 i = 0; i < size / 4; i++)\n\t{\n\t\tSE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;\n\t\tSE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i];\n\t}\n}\n\nvoid se_aes_key_clear(u32 ks)\n{\n\tfor (u32 i = 0; i < TEGRA_SE_AES_MAX_KEY_SIZE / 4; i++)\n\t{\n\t\tSE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;\n\t\tSE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0;\n\t}\n}\n\nint se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)\n{\n\tSE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTAB);\n\tSE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);\n\tSE(SE_BLOCK_COUNT_REG_OFFSET) = 0;\n\tSE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst);\n\n\treturn _se_execute(OP_START, NULL, 0, input, 0x10);\n}\n\nint se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src)\n{\n\tif (enc)\n\t{\n\t\tSE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);\n\t\tSE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);\n\t}\n\telse\n\t{\n\t\tSE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);\n\t\tSE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);\n\t}\n\tSE(SE_BLOCK_COUNT_REG_OFFSET) = 0;\n\treturn _se_execute(OP_START, dst, 0x10, src, 0x10);\n}\n\nint se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr)\n{\n\tSE(SE_SPARE_0_REG_OFFSET) = 1;\n\tSE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);\n\tSE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) |\n\t\tSE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) | SE_CRYPTO_CTR_VAL(1);\n\t_se_aes_ctr_set(ctr);\n\n\tu32 src_size_aligned = src_size & 0xFFFFFFF0;\n\tu32 src_size_delta = src_size & 0xF;\n\n\tif (src_size_aligned)\n\t{\n\t\tSE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;\n\t\tif (!_se_execute(OP_START, dst, dst_size, src, src_size_aligned))\n\t\t\treturn 0;\n\t}\n\n\tif (src_size - src_size_aligned && src_size_aligned < dst_size)\n\t\treturn _se_execute_one_block(OP_START, dst + src_size_aligned,\n\t\t\tMIN(src_size_delta, dst_size - src_size_aligned),\n\t\t\tsrc + src_size_aligned, src_size_delta);\n\n\treturn 1;\n}\n\nint se_aes_xts_crypt_sec(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *src, u32 secsize)\n{\n\tint res = 0;\n\tu8 *tweak = (u8 *)malloc(0x10);\n\tu8 *pdst = (u8 *)dst;\n\tu8 *psrc = (u8 *)src;\n\n\t//Generate tweak.\n\tfor (int i = 0xF; i >= 0; i--)\n\t{\n\t\ttweak[i] = sec & 0xFF;\n\t\tsec >>= 8;\n\t}\n\tif (!se_aes_crypt_block_ecb(ks1, 1, tweak, tweak))\n\t\tgoto out;\n\n\t//We are assuming a 0x10-aligned sector size in this implementation.\n\tfor (u32 i = 0; i < secsize / 0x10; i++)\n\t{\n\t\tfor (u32 j = 0; j < 0x10; j++)\n\t\t\tpdst[j] = psrc[j] ^ tweak[j];\n\t\tif (!se_aes_crypt_block_ecb(ks2, enc, pdst, pdst))\n\t\t\tgoto out;\n\t\tfor (u32 j = 0; j < 0x10; j++)\n\t\t\tpdst[j] = pdst[j] ^ tweak[j];\n\t\t_gf256_mul_x(tweak);\n\t\tpsrc += 0x10;\n\t\tpdst += 0x10;\n\t}\n\n\tres = 1;\n\nout:;\n\tfree(tweak);\n\treturn res;\n}\n\nint se_aes_xts_crypt(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs)\n{\n\tu8 *pdst = (u8 *)dst;\n\tu8 *psrc = (u8 *)src;\n\n\tfor (u32 i = 0; i < num_secs; i++)\n\t\tif (!se_aes_xts_crypt_sec(ks1, ks2, enc, sec + i, pdst + secsize * i, psrc + secsize * i, secsize))\n\t\t\treturn 0;\n\n\treturn 1;\n}\n\n// se_calc_sha256() was derived from Atmosphère's se_calculate_sha256.\nint se_calc_sha256(void *dst, const void *src, u32 src_size)\n{\n\tint res;\n\t// Setup config for SHA256, size = BITS(src_size).\n\tSE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);\n\tSE(SE_SHA_CONFIG_REG_OFFSET) = 1;\n\tSE(SE_SHA_MSG_LENGTH_REG_OFFSET) = (u32)(src_size << 3);\n\tSE(0x208) = 0;\n\tSE(0x20C) = 0;\n\tSE(0x210) = 0;\n\tSE(SE_SHA_MSG_LEFT_REG_OFFSET) = (u32)(src_size << 3);\n\tSE(0x218) = 0;\n   \tSE(0x21C) = 0;\n\tSE(0x220) = 0;\n\n\t// Trigger the operation.\n\tres = _se_execute(OP_START, NULL, 0, src, src_size);\n\n\t// Copy output hash.\n\tu32 *dst32 = (u32 *)dst;\n\tfor (u32 i = 0; i < 8; i++)\n\t\tdst32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)));\n\n\treturn res;\n}\n\n"
  },
  {
    "path": "argon-first-stage/src/soc/bpmp.c",
    "content": "/*\n * BPMP-Lite Cache/MMU and Frequency driver for Tegra X1\n *\n * Copyright (c) 2019 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"soc/bpmp.h\"\n#include \"soc/clock.h\"\n#include \"soc/t210.h\"\n#include \"utils/util.h\"\n\n#define BPMP_CACHE_CONFIG               0x0\n#define  CFG_ENABLE                     (1 << 0)\n#define  CFG_FORCE_WRITE_THROUGH        (1 << 3)\n#define  CFG_DISABLE_WRITE_BUFFER       (1 << 10)\n#define  CFG_DISABLE_READ_BUFFER        (1 << 11)\n#define  CFG_FULL_LINE_DIRTY            (1 << 13)\n#define  CFG_TAG_CHK_ABRT_ON_ERR        (1 << 14)\n#define BPMP_CACHE_LOCK                 0x4\n#define BPMP_CACHE_SIZE                 0xC\n#define BPMP_CACHE_LFSR                 0x10\n#define BPMP_CACHE_TAG_STATUS           0x14\n#define BPMP_CACHE_CLKEN_OVERRIDE       0x18\n#define BPMP_CACHE_MAINT_ADDR           0x20\n#define BPMP_CACHE_MAINT_DATA           0x24\n#define BPMP_CACHE_MAINT_REQ            0x28\n#define  MAINT_REQ_WAY_BITMAP(x)        ((x) << 8)\n\n#define BPMP_CACHE_INT_MASK             0x40\n#define BPMP_CACHE_INT_CLEAR            0x44\n#define  INT_CLR_MAINT_DONE             (1 << 0)\n\n#define BPMP_CACHE_INT_RAW_EVENT        0x48\n#define  INT_RAW_EVENT_MAINT_DONE      (1 << 0)\n#define BPMP_CACHE_INT_STATUS           0x4C\n\n#define BPMP_CACHE_RB_CFG               0x80\n#define BPMP_CACHE_WB_CFG               0x84\n\n#define BPMP_CACHE_MMU_FALLBACK_ENTRY   0xA0\n#define BPMP_CACHE_MMU_SHADOW_COPY_MASK 0xA4\n#define BPMP_CACHE_MMU_CFG              0xAC\n#define  MMU_CFG_SEQ_EN                 (1 << 1)\n#define  MMU_CFG_TLB_EN                 (1 << 2)\n#define  MMU_CFG_ABORT_STORE_LAST       (1 << 4)\n#define BPMP_CACHE_MMU_CMD              0xB0\n#define  MMU_CMD_NOP                    0\n#define  MMU_CMD_INIT                   1\n#define  MMU_CMD_COPY_SHADOW            2\n#define BPMP_CACHE_MMU_ABORT_STAT       0xB4\n#define BPMP_CACHE_MMU_ABORT_ADDR       0xB8\n#define BPMP_CACHE_MMU_ACTIVE_ENTRIES   0xBC\n\n#define BPMP_MMU_SHADOW_ENTRY_BASE     (BPMP_CACHE_BASE + 0x400)\n#define BPMP_MMU_MAIN_ENTRY_BASE       (BPMP_CACHE_BASE + 0x800)\n#define  MMU_ENTRY_ADDR_MASK           0xFFFFFFE0\n\n#define  MMU_EN_CACHED                (1 << 0)\n#define  MMU_EN_EXEC                  (1 << 1)\n#define  MMU_EN_READ                  (1 << 2)\n#define  MMU_EN_WRITE                 (1 << 3)\n\n#pragma GCC push_options\n#pragma GCC target (\"thumb\")\n\nbpmp_mmu_entry_t mmu_entries[] =\n{\n\t{ 0x80000000,    0xFFFFFFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true },\n\t{ 0x40008000, 0x40040000, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true }\n};\n\nvoid bpmp_mmu_maintenance(u32 op)\n{\n\tif (!(BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) & CFG_ENABLE))\n\t\treturn;\n\n\tBPMP_CACHE_CTRL(BPMP_CACHE_INT_CLEAR) = INT_CLR_MAINT_DONE;\n\n\t// This is a blocking operation.\n\tBPMP_CACHE_CTRL(BPMP_CACHE_MAINT_REQ) = MAINT_REQ_WAY_BITMAP(0xF) | op;\n\n\twhile(!(BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT) & INT_RAW_EVENT_MAINT_DONE))\n\t\t;\n\n\tBPMP_CACHE_CTRL(BPMP_CACHE_INT_CLEAR) = BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT);\n}\n\nvoid bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply)\n{\n\tif (idx > 31)\n\t\treturn;\n\n\tvolatile bpmp_mmu_entry_t *mmu_entry = (bpmp_mmu_entry_t *)(BPMP_MMU_SHADOW_ENTRY_BASE + sizeof(bpmp_mmu_entry_t) * idx);\n\n\tif (entry->enable)\n\t{\n\t\tmmu_entry->min_addr = entry->min_addr & MMU_ENTRY_ADDR_MASK;\n\t\tmmu_entry->max_addr = entry->max_addr & MMU_ENTRY_ADDR_MASK;\n\t\tmmu_entry->attr = entry->attr;\n\n\t\tBPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) |= (1 << idx);\n\n\t\tif (apply)\n\t\t\tBPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_COPY_SHADOW;\n\t}\n}\n\nvoid bpmp_mmu_enable()\n{\n\tif (BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) & CFG_ENABLE)\n\t\treturn;\n\n\t// Init BPMP MMU.\n\tBPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_INIT;\n\tBPMP_CACHE_CTRL(BPMP_CACHE_MMU_FALLBACK_ENTRY) = MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC; // RWX for non-defined regions.\n\tBPMP_CACHE_CTRL(BPMP_CACHE_MMU_CFG) = MMU_CFG_SEQ_EN | MMU_CFG_TLB_EN | MMU_CFG_ABORT_STORE_LAST;\n\n\t// Init BPMP MMU entries.\n\tBPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) = 0;\n\tfor (u32 idx = 0; idx < (sizeof(mmu_entries) / sizeof(bpmp_mmu_entry_t)); idx++)\n\t\tbpmp_mmu_set_entry(idx, &mmu_entries[idx], false);\n\n\tBPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_COPY_SHADOW;\n\n\t// Invalidate cache.\n\tbpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY);\n\n\t// Enable cache.\n\tBPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = CFG_ENABLE | CFG_FORCE_WRITE_THROUGH | CFG_TAG_CHK_ABRT_ON_ERR;\n\n\t// HW bug. Invalidate cache again.\n\tbpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY);\n}\n\nvoid bpmp_mmu_disable()\n{\n\tif (!(BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) & CFG_ENABLE))\n\t\treturn;\n\n\t// Clean and invalidate cache.\n\tbpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY);\n\n\t// Enable cache.\n\tBPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = 0;\n\n\t// HW bug. Invalidate cache again.\n\tbpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY);\n}\n\nconst u8 pllc4_divn[] = {\n\t0,   // BPMP_CLK_NORMAL:      408MHz  0% - 136MHz APB.\n\t85,  // BPMP_CLK_LOW_BOOST:   544MHz 33% - 136MHz APB.\n\t90,  // BPMP_CLK_MID_BOOST:   576MHz 41% - 144MHz APB.\n\t94   // BPMP_CLK_SUPER_BOOST: 602MHz 48% - 150MHz APB.\n\t//95   // BPMP_CLK_SUPER_BOOST: 608MHz 49% - 152MHz APB.\n};\n\nbpmp_freq_t bpmp_clock_set = BPMP_CLK_NORMAL;\n\nvoid bpmp_clk_rate_set(bpmp_freq_t fid)\n{\n\tif (fid > (BPMP_CLK_MAX - 1))\n\t\tfid = BPMP_CLK_MAX - 1;\n\n\tif (bpmp_clock_set == fid)\n\t\treturn;\n\n\tif (fid)\n\t{\n\t\tif (bpmp_clock_set)\n\t\t{\n\t\t\t// Restore to PLLP source during PLLC4 configuration.\n\t\t\tCLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) =\n\t\t\t\t(CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & 0xFFFF8888) | 0x3333; // PLLP_OUT.\n\t\t\t// Wait a bit for clock source change.\n\t\t\tmsleep(10);\n\t\t}\n\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLC4_MISC) = (1 << 30);\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) = 4 | (pllc4_divn[fid] << 8) | (1 << 30); // DIVM: 4, DIVP: 1.\n\n\t\twhile (!(CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) & (1 << 27)))\n\t\t\t;\n\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLC4_OUT) = (1 << 8) | (1 << 1); // 1.5 div.\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLC4_OUT) |= 1; // Get divider out of reset.\n\n\t\t// Wait a bit for PLLC4 to stabilize.\n\t\tmsleep(10);\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 3; // PCLK = HCLK / 4.\n\t\tCLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) =\n\t\t\t(CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & 0xFFFF8888) | 0x3323; // PLLC4_OUT3.\n\n\t\tbpmp_clock_set = fid;\n\t}\n\telse\n\t{\n\t\tCLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) =\n\t\t\t(CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & 0xFFFF8888) | 0x3333; // PLLP_OUT.\n\n\t\t// Wait a bit for clock source change.\n\t\tmsleep(10);\n\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // PCLK = HCLK / 3.\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~(1<<30);\n\t\tbpmp_clock_set = BPMP_CLK_NORMAL;\n\t}\n}\n\n#pragma GCC pop_options\n"
  },
  {
    "path": "argon-first-stage/src/soc/clock.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"soc/clock.h\"\n#include \"soc/t210.h\"\n#include \"utils/util.h\"\n#include \"storage/sdmmc.h\"\n\n#pragma GCC push_options\n#pragma GCC target (\"thumb\")\n\n/* clock_t: reset, enable, source, index, clk_src, clk_div */\n\nstatic const clock_t _clock_uart[] = {\n/* UART A */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, 6,    0, 0 },\n/* UART B */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, 7,    0, 0 },\n/* UART C */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, 0x17, 0, 0 },\n/* UART D */ { 0 },\n/* UART E */ { 0 }\n};\n\nstatic const clock_t _clock_i2c[] = {\n/* I2C1 */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, 0xC,  0, 19 }, //20.4MHz -> 100KHz\n/* I2C2 */ { 0 },\n/* I2C3 */ { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, 3,    0, 4 },  //81.6MHz -> 400KHz\n/* I2C4 */ { 0 },\n/* I2C5 */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, 0xF,  0, 4 },  //81.6MHz -> 400KHz\n/* I2C6 */ { 0 }\n};\n\nstatic clock_t _clock_se = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE,     0x1F, 0, 0\n};\n\nstatic clock_t _clock_tzram = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE,                        0x1E, 0, 0\n};\n\nstatic clock_t _clock_host1x = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, 0x1C, 4, 3\n};\nstatic clock_t _clock_tsec = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC,   0x13, 0, 2\n};\nstatic clock_t _clock_sor_safe = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE,                        0x1E, 0, 0\n};\nstatic clock_t _clock_sor0 = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NO_SOURCE,                        0x16, 0, 0\n};\nstatic clock_t _clock_sor1 = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1,   0x17, 0, 2\n};\nstatic clock_t _clock_kfuse = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE,                        8,    0, 0\n};\n\nstatic clock_t _clock_cl_dvfs =\t{\n\tCLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE,                        0x1B, 0, 0\n};\nstatic clock_t _clock_coresight = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE,     9, 0, 4\n};\n\nstatic clock_t _clock_pwm = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM,    0x11, 6, 4\n};\n\nvoid clock_enable(const clock_t *clk)\n{\n\t// Put clock into reset.\n\tCLOCK(clk->reset) = (CLOCK(clk->reset) & ~(1 << clk->index)) | (1 << clk->index);\n\t// Disable.\n\tCLOCK(clk->enable) &= ~(1 << clk->index);\n\t// Configure clock source if required.\n\tif (clk->source)\n\t\tCLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29);\n\t// Enable.\n\tCLOCK(clk->enable) = (CLOCK(clk->enable) & ~(1 << clk->index)) | (1 << clk->index);\n\t// Take clock off reset.\n\tCLOCK(clk->reset) &= ~(1 << clk->index);\n}\n\nvoid clock_disable(const clock_t *clk)\n{\n\t// Put clock into reset.\n\tCLOCK(clk->reset) = (CLOCK(clk->reset) & ~(1 << clk->index)) | (1 << clk->index);\n\t// Disable.\n\tCLOCK(clk->enable) &= ~(1 << clk->index);\n}\n\nvoid clock_enable_fuse(bool enable)\n{\n\tCLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) = (CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) & 0xEFFFFFFF) | ((enable & 1) << 28);\n}\n\nvoid clock_enable_uart(u32 idx)\n{\n\tclock_enable(&_clock_uart[idx]);\n}\n\nvoid clock_enable_i2c(u32 idx)\n{\n\tclock_enable(&_clock_i2c[idx]);\n}\n\nvoid clock_disable_i2c(u32 idx)\n{\n\tclock_disable(&_clock_i2c[idx]);\n}\n\nvoid clock_enable_se()\n{\n\tclock_enable(&_clock_se);\n}\n\nvoid clock_enable_tzram()\n{\n\tclock_enable(&_clock_tzram);\n}\n\nvoid clock_enable_host1x()\n{\n\tclock_enable(&_clock_host1x);\n}\n\nvoid clock_disable_host1x()\n{\n\tclock_disable(&_clock_host1x);\n}\n\nvoid clock_enable_tsec()\n{\n\tclock_enable(&_clock_tsec);\n}\n\nvoid clock_disable_tsec()\n{\n\tclock_disable(&_clock_tsec);\n}\n\nvoid clock_enable_sor_safe()\n{\n\tclock_enable(&_clock_sor_safe);\n}\n\nvoid clock_disable_sor_safe()\n{\n\tclock_disable(&_clock_sor_safe);\n}\n\nvoid clock_enable_sor0()\n{\n\tclock_enable(&_clock_sor0);\n}\n\nvoid clock_disable_sor0()\n{\n\tclock_disable(&_clock_sor0);\n}\n\nvoid clock_enable_sor1()\n{\n\tclock_enable(&_clock_sor1);\n}\n\nvoid clock_disable_sor1()\n{\n\tclock_disable(&_clock_sor1);\n}\n\nvoid clock_enable_kfuse()\n{\n\t//clock_enable(&_clock_kfuse);\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) = (CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) & 0xFFFFFEFF) | 0x100;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) &= 0xFFFFFEFF;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) & 0xFFFFFEFF) | 0x100;\n\tusleep(10);\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) &= 0xFFFFFEFF;\n\tusleep(20);\n}\n\nvoid clock_disable_kfuse()\n{\n\tclock_disable(&_clock_kfuse);\n}\n\nvoid clock_enable_cl_dvfs()\n{\n\tclock_enable(&_clock_cl_dvfs);\n}\n\nvoid clock_disable_cl_dvfs()\n{\n\tclock_disable(&_clock_cl_dvfs);\n}\n\nvoid clock_enable_coresight()\n{\n\tclock_enable(&_clock_coresight);\n}\n\nvoid clock_disable_coresight()\n{\n\tclock_disable(&_clock_coresight);\n}\n\nvoid clock_enable_pwm()\n{\n\tclock_enable(&_clock_pwm);\n}\n\nvoid clock_disable_pwm()\n{\n\tclock_disable(&_clock_pwm);\n}\n\n#define L_SWR_SDMMC1_RST (1 << 14)\n#define L_SWR_SDMMC2_RST (1 << 9)\n#define L_SWR_SDMMC4_RST (1 << 15)\n#define U_SWR_SDMMC3_RST (1 << 5)\n\n#define L_CLK_ENB_SDMMC1 (1 << 14)\n#define L_CLK_ENB_SDMMC2 (1 << 9)\n#define L_CLK_ENB_SDMMC4 (1 << 15)\n#define U_CLK_ENB_SDMMC3 (1 << 5)\n\n#define L_SET_SDMMC1_RST (1 << 14)\n#define L_SET_SDMMC2_RST (1 << 9)\n#define L_SET_SDMMC4_RST (1 << 15)\n#define U_SET_SDMMC3_RST (1 << 5)\n\n#define L_CLR_SDMMC1_RST (1 << 14)\n#define L_CLR_SDMMC2_RST (1 << 9)\n#define L_CLR_SDMMC4_RST (1 << 15)\n#define U_CLR_SDMMC3_RST (1 << 5)\n\n#define L_SET_CLK_ENB_SDMMC1 (1 << 14)\n#define L_SET_CLK_ENB_SDMMC2 (1 << 9)\n#define L_SET_CLK_ENB_SDMMC4 (1 << 15)\n#define U_SET_CLK_ENB_SDMMC3 (1 << 5)\n\n#define L_CLR_CLK_ENB_SDMMC1 (1 << 14)\n#define L_CLR_CLK_ENB_SDMMC2 (1 << 9)\n#define L_CLR_CLK_ENB_SDMMC4 (1 << 15)\n#define U_CLR_CLK_ENB_SDMMC3 (1 << 5)\n\nstatic int _clock_sdmmc_is_reset(u32 id)\n{\n\tswitch (id)\n\t{\n\tcase SDMMC_1:\n\t\treturn CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & L_SWR_SDMMC1_RST;\n\tcase SDMMC_2:\n\t\treturn CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & L_SWR_SDMMC2_RST;\n\tcase SDMMC_3:\n\t\treturn CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_U) & U_SWR_SDMMC3_RST;\n\tcase SDMMC_4:\n\t\treturn CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & L_SWR_SDMMC4_RST;\n\t}\n\treturn 0;\n}\n\nstatic void _clock_sdmmc_set_reset(u32 id)\n{\n\tswitch (id)\n\t{\n\tcase SDMMC_1:\n\t\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = L_SET_SDMMC1_RST;\n\t\tbreak;\n\tcase SDMMC_2:\n\t\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = L_SET_SDMMC2_RST;\n\t\tbreak;\n\tcase SDMMC_3:\n\t\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_U_SET) = U_SET_SDMMC3_RST;\n\t\tbreak;\n\tcase SDMMC_4:\n\t\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = L_SET_SDMMC4_RST;\n\t\tbreak;\n\t}\n}\n\nstatic void _clock_sdmmc_clear_reset(u32 id)\n{\n\tswitch (id)\n\t{\n\tcase SDMMC_1:\n\t\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = L_CLR_SDMMC1_RST;\n\t\tbreak;\n\tcase SDMMC_2:\n\t\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = L_CLR_SDMMC2_RST;\n\t\tbreak;\n\tcase SDMMC_3:\n\t\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_U_CLR) = U_CLR_SDMMC3_RST;\n\t\tbreak;\n\tcase SDMMC_4:\n\t\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = L_CLR_SDMMC4_RST;\n\t\tbreak;\n\t}\n}\n\nstatic int _clock_sdmmc_is_enabled(u32 id)\n{\n\tswitch (id)\n\t{\n\tcase SDMMC_1:\n\t\treturn CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & L_CLK_ENB_SDMMC1;\n\tcase SDMMC_2:\n\t\treturn CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & L_CLK_ENB_SDMMC2;\n\tcase SDMMC_3:\n\t\treturn CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) & U_CLK_ENB_SDMMC3;\n\tcase SDMMC_4:\n\t\treturn CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & L_CLK_ENB_SDMMC4;\n\t}\n\treturn 0;\n}\n\nstatic void _clock_sdmmc_set_enable(u32 id)\n{\n\tswitch (id)\n\t{\n\tcase SDMMC_1:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC1;\n\t\tbreak;\n\tcase SDMMC_2:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC2;\n\t\tbreak;\n\tcase SDMMC_3:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_SET) = U_SET_CLK_ENB_SDMMC3;\n\t\tbreak;\n\tcase SDMMC_4:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC4;\n\t\tbreak;\n\t}\n}\n\nstatic void _clock_sdmmc_clear_enable(u32 id)\n{\n\tswitch (id)\n\t{\n\tcase SDMMC_1:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC1;\n\t\tbreak;\n\tcase SDMMC_2:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC2;\n\t\tbreak;\n\tcase SDMMC_3:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_CLR) = U_CLR_CLK_ENB_SDMMC3;\n\t\tbreak;\n\tcase SDMMC_4:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC4;\n\t\tbreak;\n\t}\n}\n\nstatic u32 _clock_sdmmc_table[8] = { 0 };\n\n#define PLLP_OUT0      0x0\n\nstatic int _clock_sdmmc_config_clock_source_inner(u32 *pout, u32 id, u32 val)\n{\n\tu32 divisor = 0;\n\tu32 source = PLLP_OUT0;\n\n\tswitch (val)\n\t{\n\tcase 25000:\n\t\t*pout = 24728;\n\t\tdivisor = 31;\n\t\tbreak;\n\tcase 26000:\n\t\t*pout = 25500;\n\t\tdivisor = 30;\n\t\tbreak;\n\tcase 40800:\n\t\t*pout = 40800;\n\t\tdivisor = 18;\n\t\tbreak;\n\tcase 50000:\n\t\t*pout = 48000;\n\t\tdivisor = 15;\n\t\tbreak;\n\tcase 52000:\n\t\t*pout = 51000;\n\t\tdivisor = 14;\n\t\tbreak;\n\tcase 100000:\n\t\t*pout = 90667;\n\t\tdivisor = 7;\n\t\tbreak;\n\tcase 200000:\n\t\t*pout = 163200;\n\t\tdivisor = 3;\n\t\tbreak;\n\tcase 208000:\n\t\t*pout = 204000;\n\t\tdivisor = 2;\n\t\tbreak;\n\tdefault:\n\t\t*pout = 24728;\n\t\tdivisor = 31;\n\t}\n\n\t_clock_sdmmc_table[2 * id] = val;\n\t_clock_sdmmc_table[2 * id + 1] = *pout;\n\n\tswitch (id)\n\t{\n\tcase SDMMC_1:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = (source << 29) | divisor;\n\t\tbreak;\n\tcase SDMMC_2:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = (source << 29) | divisor;\n\t\tbreak;\n\tcase SDMMC_3:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = (source << 29) | divisor;\n\t\tbreak;\n\tcase SDMMC_4:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = (source << 29) | divisor;\n\t\tbreak;\n\t}\n\n\treturn 1;\n}\n\nvoid clock_sdmmc_config_clock_source(u32 *pout, u32 id, u32 val)\n{\n\tif (_clock_sdmmc_table[2 * id] == val)\n\t{\n\t\t*pout = _clock_sdmmc_table[2 * id + 1];\n\t}\n\telse\n\t{\n\t\tint is_enabled = _clock_sdmmc_is_enabled(id);\n\t\tif (is_enabled)\n\t\t\t_clock_sdmmc_clear_enable(id);\n\t\t_clock_sdmmc_config_clock_source_inner(pout, id, val);\n\t\tif (is_enabled)\n\t\t\t_clock_sdmmc_set_enable(id);\n\t\t_clock_sdmmc_is_reset(id);\n\t}\n}\n\nvoid clock_sdmmc_get_params(u32 *pout, u16 *pdivisor, u32 type)\n{\n\tswitch (type)\n\t{\n\tcase 0:\n\t\t*pout = 26000;\n\t\t*pdivisor = 66;\n\t\tbreak;\n\tcase 1:\n\t\t*pout = 26000;\n\t\t*pdivisor = 1;\n\t\tbreak;\n\tcase 2:\n\t\t*pout = 52000;\n\t\t*pdivisor = 1;\n\t\tbreak;\n\tcase 3:\n\tcase 4:\n\tcase 11:\n\t\t*pout = 200000;\n\t\t*pdivisor = 1;\n\t\tbreak;\n\tcase 5:\n\t\t*pout = 25000;\n\t\t*pdivisor = 64;\n\t\tbreak;\n\tcase 6:\n\tcase 8:\n\t\t*pout = 25000;\n\t\t*pdivisor = 1;\n\t\tbreak;\n\tcase 7:\n\t\t*pout = 50000;\n\t\t*pdivisor = 1;\n\t\tbreak;\n\tcase 10:\n\t\t*pout = 100000;\n\t\t*pdivisor = 1;\n\t\tbreak;\n\tcase 13:\n\t\t*pout = 40800;\n\t\t*pdivisor = 1;\n\t\tbreak;\n\tcase 14:\n\t\t*pout = 200000;\n\t\t*pdivisor = 2;\n\t\tbreak;\n\t}\n}\n\nint clock_sdmmc_is_not_reset_and_enabled(u32 id)\n{\n\treturn !_clock_sdmmc_is_reset(id) && _clock_sdmmc_is_enabled(id);\n}\n\nvoid clock_sdmmc_enable(u32 id, u32 val)\n{\n\tu32 div = 0;\n\n\tif (_clock_sdmmc_is_enabled(id))\n\t\t_clock_sdmmc_clear_enable(id);\n\t_clock_sdmmc_set_reset(id);\n\t_clock_sdmmc_config_clock_source_inner(&div, id, val);\n\t_clock_sdmmc_set_enable(id);\n\t_clock_sdmmc_is_reset(id);\n\tusleep((100000 + div - 1) / div);\n\t_clock_sdmmc_clear_reset(id);\n\t_clock_sdmmc_is_reset(id);\n}\n\nvoid clock_sdmmc_disable(u32 id)\n{\n\t_clock_sdmmc_set_reset(id);\n\t_clock_sdmmc_clear_enable(id);\n\t_clock_sdmmc_is_reset(id);\n}\n\n#pragma GCC pop_options\n"
  },
  {
    "path": "argon-first-stage/src/soc/cluster.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"soc/cluster.h\"\n#include \"soc/i2c.h\"\n#include \"soc/clock.h\"\n#include \"utils/util.h\"\n#include \"soc/pmc.h\"\n#include \"soc/t210.h\"\n#include \"power/max77620.h\"\n#include \"power/max7762x.h\"\n\nvoid _cluster_enable_power()\n{\n\tu8 tmp = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO);\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO, tmp & 0xDF);\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, MAX77620_CNFG_GPIO_DRV_PUSHPULL | MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH);\n\n\t// Enable cores power.\n\t// 1-3.x: MAX77621_NFSR_ENABLE.\n\ti2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL1_REG,\n\t\tMAX77621_AD_ENABLE | MAX77621_NFSR_ENABLE | MAX77621_SNS_ENABLE);\n\t// 1.0.0-3.x: MAX77621_T_JUNCTION_120 | MAX77621_CKKADV_TRIP_DISABLE | MAX77621_INDUCTOR_NOMINAL.\n\ti2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL2_REG,\n\t\tMAX77621_T_JUNCTION_120 | MAX77621_WDTMR_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US| MAX77621_INDUCTOR_NOMINAL);\n\ti2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_REG, MAX77621_VOUT_ENABLE | 0x37);\n\ti2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_DVC_REG, MAX77621_VOUT_ENABLE | 0x37);\n}\n\nint _cluster_pmc_enable_partition(u32 part, u32 toggle, bool enable)\n{\n\t// Check if the partition has already been turned on.\n\tif (enable && PMC(APBDEV_PMC_PWRGATE_STATUS) & part)\n\t\treturn 1;\n\n\tu32 i = 5001;\n\twhile (PMC(APBDEV_PMC_PWRGATE_TOGGLE) & 0x100)\n\t{\n\t\tusleep(1);\n\t\ti--;\n\t\tif (i < 1)\n\t\t\treturn 0;\n\t}\n\n\tPMC(APBDEV_PMC_PWRGATE_TOGGLE) = toggle | (enable ? 0x100 : 0);\n\n\ti = 5001;\n\twhile (i > 0)\n\t{\n\t\tif (PMC(APBDEV_PMC_PWRGATE_STATUS) & part)\n\t\t\tbreak;\n\t\tusleep(1);\n\t\ti--;\n\t}\n\n\treturn 1;\n}\n\nvoid cluster_boot_cpu0(u32 entry)\n{\n\t// Set ACTIVE_CLUSER to FAST.\n\tFLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= 0xFFFFFFFE;\n\n\t_cluster_enable_power();\n\n\tif (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x40000000))\n\t{\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= 0xFFFFFFF7;\n\t\tusleep(2);\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x80404E02;\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x404E02;\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLX_MISC) = (CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) & 0xFFFBFFFF) | 0x40000;\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x40404E02;\n\t}\n\twhile (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x8000000))\n\t\t;\n\n\t// Configure MSELECT source and enable clock.\n\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) & 0x1FFFFF00) | 6;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) & 0xFFFFFFF7) | 8;\n\n\t// Configure initial CPU clock frequency and enable clock.\n\tCLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888;\n\tCLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = 1;\n\n\tclock_enable_coresight();\n\n\t// CAR2PMC_CPU_ACK_WIDTH should be set to 0.\n\tCLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) &= 0xFFFFF000;\n\n\t// Enable CPU rail.\n\t_cluster_pmc_enable_partition(1, 0, true);\n\t// Enable cluster 0 non-CPU.\n\t_cluster_pmc_enable_partition(0x8000, 15, true);\n\t// Enable CE0.\n\t_cluster_pmc_enable_partition(0x4000, 14, true);\n\n\t// Request and wait for RAM repair.\n\tFLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = 1;\n\twhile (!(FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) & 2))\n\t\t;\n\n\tEXCP_VEC(EVP_CPU_RESET_VECTOR) = 0;\n\n\t// Set reset vector.\n\tSB(SB_AA64_RESET_LOW) = entry | 1;\n\tSB(SB_AA64_RESET_HIGH) = 0;\n\t// Non-secure reset vector write disable.\n\tSB(SB_CSR) = 2;\n\t(void)SB(SB_CSR);\n\n\t// Clear MSELECT reset.\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEVICES_V) &= 0xFFFFFFF7;\n\t// Clear NONCPU reset.\n\tCLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000;\n\t// Clear CPU0 reset.\n\t// < 5.x: 0x411F000F, Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.\n\tCLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x41010001;\n}\n"
  },
  {
    "path": "argon-first-stage/src/soc/fuse.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 shuffle2\n * Copyright (c) 2018 balika011\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"soc/fuse.h\"\n#include \"soc/t210.h\"\n\n#define ARRAYSIZE(x) (sizeof(x) / sizeof(*x))\n\nstatic const u32 evp_thunk_template[] = {\n\t0xe92d0007, //   STMFD   SP!, {R0-R2}\n\t0xe1a0200e, //   MOV     R2, LR\n\t0xe2422002, //   SUB     R2, R2, #2\n\t0xe5922000, //   LDR     R2, [R2]\n\t0xe20220ff, //   AND     R2, R2, #0xFF\n\t0xe1a02082, //   MOV     R2, R2,LSL#1\n\t0xe59f001c, //   LDR     R0, =evp_thunk_template\n\t0xe59f101c, //   LDR     R1, =thunk_end\n\t0xe0411000, //   SUB     R1, R1, R0\n\t0xe59f0018, //   LDR     R0, =iram_evp_thunks\n\t0xe0800001, //   ADD     R0, R0, R1\n\t0xe0822000, //   ADD     R2, R2, R0\n\t0xe3822001, //   ORR     R2, R2, #1\n\t0xe8bd0003, //   LDMFD   SP!, {R0,R1}\n\t0xe12fff12, //   BX      R2\n\t0x001007b0, // off_1007EC DCD evp_thunk_template\n\t0x001007f8, // off_1007F0 DCD thunk_end\n\t0x40004c30, // off_1007F4 DCD iram_evp_thunks\n\t// thunk_end is here\n};\nstatic const u32 evp_thunk_template_len = sizeof(evp_thunk_template);\n\n// treated as 12bit values\nstatic const u32 hash_vals[] = {1, 2, 4, 8, 0, 3, 5, 6, 7, 9, 10, 11};\n\nvoid fuse_disable_program()\n{\n\tFUSE(FUSE_DISABLEREGPROGRAM) = 1;\n}\n\nu32 fuse_read_odm(u32 idx)\n{\n\treturn FUSE(FUSE_RESERVED_ODMX(idx));\n}\n\nvoid fuse_wait_idle()\n{\n    u32 ctrl;\n    do\n    {\n        ctrl = FUSE(FUSE_CTRL);\n    } while (((ctrl >> 16) & 0x1f) != 4);\n}\n\nu32 parity32_even(u32 *words, u32 count)\n{\n\tu32 acc = words[0];\n\tfor (u32 i = 1; i < count; i++)\n\t{\n\t\tacc ^= words[i];\n\t}\n\tu32 lo = ((acc & 0xffff) ^ (acc >> 16)) & 0xff;\n\tu32 hi = ((acc & 0xffff) ^ (acc >> 16)) >> 8;\n\tu32 x = hi ^ lo;\n\tlo = ((x & 0xf) ^ (x >> 4)) & 3;\n\thi = ((x & 0xf) ^ (x >> 4)) >> 2;\n\tx = hi ^ lo;\n \n\treturn (x & 1) ^ (x >> 1);\n}\n\nint patch_hash_one(u32 *word)\n{\n\tu32 bits20_31 = *word & 0xfff00000;\n\tu32 parity_bit = parity32_even(&bits20_31, 1);\n\tu32 hash = 0;\n\tfor (u32 i = 0; i < 12; i++)\n\t{\n\t\tif (*word & (1 << (20 + i)))\n\t\t{\n\t\t\thash ^= hash_vals[i];\n\t\t}\n\t}\n\tif (hash == 0)\n\t{\n\t\tif (parity_bit == 0)\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\t\t*word ^= 1 << 24;\n\t\treturn 1;\n\t}\n\tif (parity_bit == 0)\n\t{\n\t\treturn 3;\n\t}\n\tfor (u32 i = 0; i < ARRAYSIZE(hash_vals); i++)\n\t{\n\t\tif (hash_vals[i] == hash)\n\t\t{\n\t\t\t*word ^= 1 << (20 + i);\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 2;\n}\n\nint patch_hash_multi(u32 *words, u32 count)\n{\n\tu32 parity_bit = parity32_even(words, count);\n\tu32 bits0_14 = words[0] & 0x7fff;\n\tu32 bit15 = words[0] & 0x8000;\n\tu32 bits16_19 = words[0] & 0xf0000;\n\n\tu32 hash = 0;\n\twords[0] = bits16_19;\n\tfor (u32 i = 0; i < count; i++)\n\t{\n\t\tu32 w = words[i];\n\t\tif (w)\n\t\t{\n\t\t\tfor (u32 bitpos = 0; bitpos < 32; bitpos++)\n\t\t\t{\n\t\t\t\tif ((w >> bitpos) & 1)\n\t\t\t\t{\n\t\t\t\t\thash ^= 0x4000 + i * 32 + bitpos;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\thash ^= bits0_14;\n\t// stupid but this is what original code does.\n\t// equivalent to original words[0] &= 0xfff00000\n\twords[0] = bits16_19 ^ bit15 ^ bits0_14;\n\n\tif (hash == 0)\n\t{\n\t\tif (parity_bit == 0)\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\t\twords[0] ^= 0x8000;\n\t\treturn 1;\n\t}\n\tif (parity_bit == 0)\n\t{\n\t\treturn 3;\n\t}\n\tu32 bitcount = hash - 0x4000;\n\tif (bitcount < 16 || bitcount >= count * 32)\n\t{\n\t\tu32 num_set = 0;\n\t\tfor (u32 bitpos = 0; bitpos < 15; bitpos++)\n\t\t{\n\t\t\tif ((hash >> bitpos) & 1)\n\t\t\t{\n\t\t\t\tnum_set++;\n\t\t\t}\n\t\t}\n\t\tif (num_set != 1)\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\t\twords[0] ^= hash;\n\t\treturn 1;\n\t}\n\twords[bitcount / 32] ^= 1 << (hash & 0x1f);\n\treturn 1;\n}\n\nint fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value))\n{\n\tu32 words[80];\n\tu32 word_count;\n\tu32 word_addr;\n\tu32 word0 = 0;\n\tu32 total_read = 0;\n\n\tword_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);\n\tword_count &= 0x7f;\n\tword_addr = 191;\n\n\twhile (word_count)\n\t{\n\t\ttotal_read += word_count;\n\t\tif (total_read >= ARRAYSIZE(words))\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t\t\n\t\tfor (u32 i = 0; i < word_count; i++)\n\t\t{\n\t\t\tFUSE(FUSE_ADDR) = word_addr--;\n\t\t\tFUSE(FUSE_CTRL) = (FUSE(FUSE_ADDR) & ~FUSE_CMD_MASK) | FUSE_READ;\n\t\t\tfuse_wait_idle();\n\t\t\twords[i] = FUSE(FUSE_RDATA);\n\t\t}\n\t\t\n\t\tword0 = words[0];\n\t\tif (patch_hash_multi(words, word_count) >= 2)\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tu32 ipatch_count = (words[0] >> 16) & 0xf;\n\t\tif (ipatch_count)\n\t\t{\n\t\t\tfor (u32 i = 0; i < ipatch_count; i++)\n\t\t\t{\n\t\t\t\tu32 word = words[i + 1];\n\t\t\t\tu32 addr = (word >> 16) * 2;\n\t\t\t\tu32 data = word & 0xffff;\n\t\t\n\t\t\t\tipatch(addr, data);\n\t\t\t}\n\t\t}\n\t\twords[0] = word0;\n\t\tif ((word0 >> 25) == 0)\n\t\t\tbreak;\n\t\tif (patch_hash_one(&word0) >= 2)\n\t\t{\n\t\t\treturn 3;\n\t\t}\n\t\tword_count = word0 >> 25;\n\t}\n\t\n\treturn 0;\n}\n\nint fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)\n{\n\tu32 words[80];\n\tu32 word_count;\n\tu32 word_addr;\n\tu32 word0 = 0;\n\tu32 total_read = 0;\n\tint evp_thunk_written = 0;\n\tvoid *evp_thunk_dst_addr = 0;\n\n\tmemset(iram_evp_thunks, 0, *iram_evp_thunks_len);\n\n\tword_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);\n\tword_count &= 0x7f;\n\tword_addr = 191;\n\n\twhile (word_count)\n\t{\n\t\ttotal_read += word_count;\n\t\tif (total_read >= ARRAYSIZE(words))\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t\t\n\t\tfor (u32 i = 0; i < word_count; i++)\n\t\t{\n\t\t\tFUSE(FUSE_ADDR) = word_addr--;\n\t\t\tFUSE(FUSE_CTRL) = (FUSE(FUSE_ADDR) & ~FUSE_CMD_MASK) | FUSE_READ;\n\t\t\tfuse_wait_idle();\n\t\t\twords[i] = FUSE(FUSE_RDATA);\n\t\t}\n\t\t\n\t\tword0 = words[0];\n\t\tif (patch_hash_multi(words, word_count) >= 2)\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tu32 ipatch_count = (words[0] >> 16) & 0xf;\n\t\tu32 insn_count = word_count - ipatch_count - 1;\n\t\tif (insn_count)\n\t\t{\n\t\t\tif (!evp_thunk_written)\n\t\t\t{\n\t\t\t\tevp_thunk_dst_addr = (void *)iram_evp_thunks;\n\n\t\t\t\tmemcpy(evp_thunk_dst_addr, (void *)evp_thunk_template, evp_thunk_template_len);\n\t\t\t\tevp_thunk_dst_addr += evp_thunk_template_len;\n\t\t\t\tevp_thunk_written = 1;\n\t\t\t\t*iram_evp_thunks_len = evp_thunk_template_len;\n\n\t\t\t\t//write32(TEGRA_EXCEPTION_VECTORS_BASE + 0x208, iram_evp_thunks);\n\t\t\t}\n\n\t\t\tu32 thunk_patch_len = insn_count * sizeof(u32);\n\t\t\tmemcpy(evp_thunk_dst_addr, &words[ipatch_count + 1], thunk_patch_len);\n\t\t\tevp_thunk_dst_addr += thunk_patch_len;\n\t\t\t*iram_evp_thunks_len += thunk_patch_len;\n\t\t}\n\t\twords[0] = word0;\n\t\tif ((word0 >> 25) == 0)\n\t\t\tbreak;\n\t\tif (patch_hash_one(&word0) >= 2)\n\t\t{\n\t\t\treturn 3;\n\t\t}\n\t\tword_count = word0 >> 25;\n\t}\n\t\n\treturn 0;\n}\n\nvoid read_raw_ipatch_fuses(u32 *words)\n{\n\tfor (u32 i = 0; i < 0x100; i++)\n\t{\n\t\tFUSE(FUSE_ADDR) = i;\n\t\tFUSE(FUSE_CTRL) = (FUSE(FUSE_ADDR) & ~FUSE_CMD_MASK) | FUSE_READ;\n\t\tfuse_wait_idle();\n\t\twords[i] = FUSE(FUSE_RDATA);\n\t}\n}"
  },
  {
    "path": "argon-first-stage/src/soc/gpio.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"soc/gpio.h\"\n#include \"soc/t210.h\"\n\nstatic const u16 _gpio_cnf[31] = {\n\t0x000, 0x004, 0x008, 0x00C,\n\t0x100, 0x104, 0x108, 0x10C,\n\t0x200, 0x204, 0x208, 0x20C,\n\t0x300, 0x304, 0x308, 0x30C,\n\t0x400, 0x404, 0x408, 0x40C,\n\t0x500, 0x504, 0x508, 0x50C,\n\t0x600, 0x604, 0x608, 0x60C,\n\t0x700, 0x704, 0x708\n};\n\nstatic const u16 _gpio_oe[31] = {\n\t0x010, 0x014, 0x018, 0x01C,\n\t0x110, 0x114, 0x118, 0x11C,\n\t0x210, 0x214, 0x218, 0x21C,\n\t0x310, 0x314, 0x318, 0x31C,\n\t0x410, 0x414, 0x418, 0x41C,\n\t0x510, 0x514, 0x518, 0x51C,\n\t0x610, 0x614, 0x618, 0x61C,\n\t0x710, 0x714, 0x718\n};\n\nstatic const u16 _gpio_out[31] = {\n\t0x020, 0x024, 0x028, 0x02C,\n\t0x120, 0x124, 0x128, 0x12C,\n\t0x220, 0x224, 0x228, 0x22C,\n\t0x320, 0x324, 0x328, 0x32C,\n\t0x420, 0x424, 0x428, 0x42C,\n\t0x520, 0x524, 0x528, 0x52C,\n\t0x620, 0x624, 0x628, 0x62C,\n\t0x720, 0x724, 0x728\n};\n\nstatic const u16 _gpio_in[31] = {\n\t0x030, 0x034, 0x038, 0x03C,\n\t0x130, 0x134, 0x138, 0x13C,\n\t0x230, 0x234, 0x238, 0x23C,\n\t0x330, 0x334, 0x338, 0x33C,\n\t0x430, 0x434, 0x438, 0x43C,\n\t0x530, 0x534, 0x538, 0x53C,\n\t0x630, 0x634, 0x638, 0x63C,\n\t0x730, 0x734, 0x738\n};\n\nvoid gpio_config(u32 port, u32 pins, int mode)\n{\n\tif (mode)\n\t\tGPIO(_gpio_cnf[port]) |= pins;\n\telse\n\t\tGPIO(_gpio_cnf[port]) &= ~pins;\n\t(void)GPIO(_gpio_cnf[port]);\n}\n\nvoid gpio_output_enable(u32 port, u32 pins, int enable)\n{\n\tif (enable)\n\t\tGPIO(_gpio_oe[port]) |= pins;\n\telse\n\t\tGPIO(_gpio_oe[port]) &= ~pins;\n\t(void)GPIO(_gpio_oe[port]);\n}\n\nvoid gpio_write(u32 port, u32 pins, int high)\n{\n\tif (high)\n\t\tGPIO(_gpio_out[port]) |= pins;\n\telse\n\t\tGPIO(_gpio_out[port]) &= ~pins;\n\t(void)GPIO(_gpio_out[port]);\n}\n\nint gpio_read(u32 port, u32 pins)\n{\n\treturn (GPIO(_gpio_in[port]) & pins) ? 1 : 0;\n}\n"
  },
  {
    "path": "argon-first-stage/src/soc/hw_init.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"soc/hw_init.h\"\n\n#include \"gfx/di.h\"\n\n#include \"mem/mc.h\"\n#include \"mem/sdram.h\"\n\n#include \"power/max77620.h\"\n#include \"power/max7762x.h\"\n\n#include \"sec/se.h\"\n#include \"sec/se_t210.h\"\n\n#include \"soc/clock.h\"\n#include \"soc/fuse.h\"\n#include \"soc/gpio.h\"\n#include \"soc/i2c.h\"\n#include \"soc/pinmux.h\"\n#include \"soc/pmc.h\"\n#include \"soc/t210.h\"\n#include \"soc/uart.h\"\n#include \"soc/bpmp.h\"\n\n#include \"storage/sdmmc.h\"\n\n#include \"utils/util.h\"\n#include \"utils/fs_utils.h\"\n\nvoid _config_oscillators()\n{\n    CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = (CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3) | 4;\n    SYSCTR0(SYSCTR0_CNTFID0) = 19200000;\n    TMR(TIMERUS_USEC_CFG) = 0x45F; // For 19.2MHz clk_m.\n    CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071;\n    PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81) | 0xE;\n    PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF) | 0x400000;\n    PMC(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | 0x1000;\n    PMC(APBDEV_PMC_SCRATCH188) = (PMC(APBDEV_PMC_SCRATCH188) & 0xFCFFFFFF) | 0x2000000;\n    CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10;\n    CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF;\n    PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz)\n    CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444;\n    CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000;\n    CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2;\n}\n\nvoid _config_gpios()\n{\n    PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0;\n    PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;\n\n    PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE;\n    PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE;\n\n#if !defined(DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_B\n    gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);\n#endif\n#if !defined(DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_C\n    gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);\n#endif\n    gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_GPIO);\n    gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_GPIO);\n    gpio_output_enable(GPIO_PORT_G, GPIO_PIN_0, GPIO_OUTPUT_DISABLE);\n    gpio_output_enable(GPIO_PORT_D, GPIO_PIN_1, GPIO_OUTPUT_DISABLE);\n    gpio_output_enable(GPIO_PORT_E, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);\n    gpio_output_enable(GPIO_PORT_H, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);\n\n    pinmux_config_i2c(I2C_1);\n    pinmux_config_i2c(I2C_5);\n    pinmux_config_uart(UART_A);\n\n    // Configure volume up/down as inputs.\n    gpio_config(GPIO_PORT_X, GPIO_PIN_6, GPIO_MODE_GPIO);\n    gpio_config(GPIO_PORT_X, GPIO_PIN_7, GPIO_MODE_GPIO);\n    gpio_output_enable(GPIO_PORT_X, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);\n    gpio_output_enable(GPIO_PORT_X, GPIO_PIN_7, GPIO_OUTPUT_DISABLE);\n}\n\nvoid _config_pmc_scratch()\n{\n    PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF;\n    PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE;\n    PMC(APBDEV_PMC_SECURE_SCRATCH21) |= 0x10;\n}\n\nvoid _mbist_workaround()\n{\n    CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= (1 << 10); // Enable AHUB clock.\n    CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= (1 << 6);  // Enable APE clock.\n\n    CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) | 0x8000) & 0xFFFFBFFF;\n    CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) |= 0x40800000u;\n    CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_CLR) = 0x40;\n    CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_CLR) = 0x40000;\n    CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = 0x18000000;\n    usleep(2);\n\n    I2S(I2S1_CTRL) |= I2S_CTRL_MASTER_EN;\n    I2S(I2S1_CG) &= ~I2S_CG_SLCG_ENABLE;\n    I2S(I2S2_CTRL) |= I2S_CTRL_MASTER_EN;\n    I2S(I2S2_CG) &= ~I2S_CG_SLCG_ENABLE;\n    I2S(I2S3_CTRL) |= I2S_CTRL_MASTER_EN;\n    I2S(I2S3_CG) &= ~I2S_CG_SLCG_ENABLE;\n    I2S(I2S4_CTRL) |= I2S_CTRL_MASTER_EN;\n    I2S(I2S4_CG) &= ~I2S_CG_SLCG_ENABLE;\n    I2S(I2S5_CTRL) |= I2S_CTRL_MASTER_EN;\n    I2S(I2S5_CG) &= ~I2S_CG_SLCG_ENABLE;\n    DISPLAY_A(_DIREG(DC_COM_DSC_TOP_CTL)) |= 4;\n    VIC(0x8C) = 0xFFFFFFFF;\n    usleep(2);\n\n    CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_SET) = 0x40;\n    CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = 0x18000000;\n    CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_SET) = 0x40000;\n    CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = 0xC0;\n    CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = 0x80000130;\n    CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) = 0x1F00200;\n    CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = 0x80400808;\n    CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) = 0x402000FC;\n    CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) = 0x23000780;\n    CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) = 0x300;\n    CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA) = 0;\n    CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB) = 0;\n    CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC) = 0;\n    CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) = 0;\n    CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE) = 0;\n    CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) &= 0x1F7FFFFF;\n    CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) &= 0xFFFF3FFF;\n    CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000;\n    CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) & 0x1FFFFFFF) | 0x80000000;\n    CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000;\n}\n\nvoid _config_se_brom()\n{\n    // Bootrom part we skipped.\n    u32 sbk[4] = {\n        FUSE(FUSE_PRIVATE_KEY0),\n        FUSE(FUSE_PRIVATE_KEY1),\n        FUSE(FUSE_PRIVATE_KEY2),\n        FUSE(FUSE_PRIVATE_KEY3)};\n    // Set SBK to slot 14.\n    se_aes_key_set(14, sbk, 0x10);\n\n    // Lock SBK from being read.\n    SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 14 * 4) = 0x7E;\n\n    // This memset needs to happen here, else TZRAM will behave weirdly later on.\n    memset((void *)TZRAM_BASE, 0, 0x10000);\n    PMC(APBDEV_PMC_CRYPTO_OP) = 0;\n    SE(SE_INT_STATUS_REG_OFFSET) = 0x1F;\n\n    // Lock SSK (although it's not set and unused anyways).\n    SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 15 * 4) = 0x7E;\n\n    // Clear the boot reason to avoid problems later\n    PMC(APBDEV_PMC_SCRATCH200) = 0x0;\n    PMC(APBDEV_PMC_RST_STATUS) = 0x0;\n    APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) = (APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) & 0xF0) | (7 << 10);\n}\n\nvoid config_hw()\n{\n    // Bootrom stuff we skipped by going through rcm.\n    _config_se_brom();\n    //FUSE(FUSE_PRIVATEKEYDISABLE) = 0x11;\n    SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F;\n    PMC(APBDEV_PMC_SCRATCH49) = ((PMC(APBDEV_PMC_SCRATCH49) >> 1) << 1) & 0xFFFFFFFD;\n\n    _mbist_workaround();\n    clock_enable_se();\n\n    // Enable fuse clock.\n    clock_enable_fuse(true);\n    // Disable fuse programming.\n    fuse_disable_program();\n\n    mc_enable();\n\n    _config_oscillators();\n    APB_MISC(APB_MISC_PP_PINMUX_GLOBAL) = 0;\n    _config_gpios();\n\n    clock_enable_cl_dvfs();\n\n    clock_enable_i2c(I2C_1);\n    clock_enable_i2c(I2C_5);\n\n    clock_enable_tzram();\n\n    i2c_init(I2C_1);\n    i2c_init(I2C_5);\n\n    i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);\n    i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1,\n                  (1 << 6) | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off.\n\n    i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0,\n                  (7 << MAX77620_FPS_TIME_PERIOD_SHIFT));\n    i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG1,\n                  (7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (1 << MAX77620_FPS_EN_SRC_SHIFT));\n    i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG2,\n                  (7 << MAX77620_FPS_TIME_PERIOD_SHIFT));\n    max77620_regulator_config_fps(REGULATOR_LDO4);\n    max77620_regulator_config_fps(REGULATOR_LDO8);\n    max77620_regulator_config_fps(REGULATOR_SD0);\n    max77620_regulator_config_fps(REGULATOR_SD1);\n    max77620_regulator_config_fps(REGULATOR_SD3);\n\n    i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_GPIO3,\n                  (4 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (2 << MAX77620_FPS_PD_PERIOD_SHIFT)); // 3.x+\n\n    max77620_regulator_set_voltage(REGULATOR_SD0, 1125000);\n\n    // Fix GPU after warmboot for Linux.\n    i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, 2);\n    i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO6, 2);\n\n    // Disable low battery shutdown monitor.\n    max77620_low_battery_monitor_config();\n\n    _config_pmc_scratch(); // Missing from 4.x+\n\n    CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = (CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & 0xFFFF8888) | 0x3333;\n\n    sdram_init();\n\n    // bpmp_mmu_enable();\n}\n"
  },
  {
    "path": "argon-first-stage/src/soc/i2c.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"soc/i2c.h\"\n#include \"utils/util.h\"\n\nstatic u32 i2c_addrs[] = {\n\t0x7000C000, 0x7000C400, 0x7000C500,\n\t0x7000C700, 0x7000D000, 0x7000D100\n};\n\nstatic void _i2c_wait(vu32 *base)\n{\n\tbase[I2C_CONFIG_LOAD] = 0x25;\n\tfor (u32 i = 0; i < 20; i++)\n\t{\n\t\tusleep(1);\n\t\tif (!(base[I2C_CONFIG_LOAD] & 1))\n\t\t\tbreak;\n\t}\n}\n\nstatic int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)\n{\n\tif (size > 4)\n\t\treturn 0;\n\n\tu32 tmp = 0;\n\tmemcpy(&tmp, buf, size);\n\n\tvu32 *base = (vu32 *)i2c_addrs[idx];\n\tbase[I2C_CMD_ADDR0] = x << 1; //Set x (send mode).\n\tbase[I2C_CMD_DATA1] = tmp;    //Set value.\n\tbase[I2C_CNFG] = (2 * size - 2) | 0x2800; //Set size and send mode.\n\t_i2c_wait(base);  //Kick transaction.\n\n\tbase[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200;\n\twhile (base[I2C_STATUS] & 0x100)\n\t\t;\n\n\tif (base[I2C_STATUS] << 28)\n\t\treturn 0;\n\n\treturn 1;\n}\n\nstatic int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)\n{\n\tif (size > 8)\n\t\treturn 0;\n\n\tvu32 *base = (vu32 *)i2c_addrs[idx];\n\tbase[I2C_CMD_ADDR0] = (x << 1) | 1; // Set x (recv mode).\n\tbase[I2C_CNFG] = (size - 1) << 1 | 0x2840; // Set size and recv mode.\n\t_i2c_wait(base);        // Kick transaction.\n\n\tbase[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200;\n\twhile (base[I2C_STATUS] & 0x100)\n\t\t;\n\n\tif (base[I2C_STATUS] << 28)\n\t\treturn 0;\n\n\tu32 tmp = base[I2C_CMD_DATA1]; // Get LS value.\n\tif (size > 4)\n\t{\n\t\tmemcpy(buf, &tmp, 4);\n\t\ttmp = base[I2C_CMD_DATA2]; // Get MS value.\n\t\tmemcpy(buf + 4, &tmp, size - 4);\n\t}\n\telse\n\t\tmemcpy(buf, &tmp, size);\n\n\treturn 1;\n}\n\nvoid i2c_init(u32 idx)\n{\n\tvu32 *base = (vu32 *)i2c_addrs[idx];\n\n\tbase[I2C_CLK_DIVISOR_REGISTER] = 0x50001;\n\tbase[I2C_BUS_CLEAR_CONFIG] = 0x90003;\n\t_i2c_wait(base);\n\n\tfor (u32 i = 0; i < 10; i++)\n\t{\n\t\tusleep(20000);\n\t\tif (base[INTERRUPT_STATUS_REGISTER] & 0x800)\n\t\t\tbreak;\n\t}\n\n\t(vu32)base[I2C_BUS_CLEAR_STATUS];\n\tbase[INTERRUPT_STATUS_REGISTER] = base[INTERRUPT_STATUS_REGISTER];\n}\n\nint i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size)\n{\n\tu8 tmp[4];\n\n\tif (size > 3)\n\t\treturn 0;\n\n\ttmp[0] = y;\n\tmemcpy(tmp + 1, buf, size);\n\n\treturn _i2c_send_pkt(idx, x, tmp, size + 1);\n}\n\nint i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y)\n{\n\tint res = _i2c_send_pkt(idx, x, (u8 *)&y, 1);\n\tif (res)\n\t\tres = _i2c_recv_pkt(idx, buf, size, x);\n\treturn res;\n}\n\nint i2c_send_byte(u32 idx, u32 x, u32 y, u8 b)\n{\n\treturn i2c_send_buf_small(idx, x, y, &b, 1);\n}\n\nu8 i2c_recv_byte(u32 idx, u32 x, u32 y)\n{\n\tu8 tmp = 0;\n\ti2c_recv_buf_small(&tmp, 1, idx, x, y);\n\treturn tmp;\n}\n\n"
  },
  {
    "path": "argon-first-stage/src/soc/pinmux.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"soc/pinmux.h\"\n#include \"soc/t210.h\"\n\nvoid pinmux_config_uart(u32 idx)\n{\n\tPINMUX_AUX(PINMUX_AUX_UARTX_TX(idx)) = 0;\n\tPINMUX_AUX(PINMUX_AUX_UARTX_RX(idx)) = PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;\n\tPINMUX_AUX(PINMUX_AUX_UARTX_RTS(idx)) = 0;\n\tPINMUX_AUX(PINMUX_AUX_UARTX_CTS(idx)) = PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN;\n}\n\nvoid pinmux_config_i2c(u32 idx)\n{\n\tPINMUX_AUX(PINMUX_AUX_X_I2C_SCL(idx)) = PINMUX_INPUT_ENABLE;\n\tPINMUX_AUX(PINMUX_AUX_X_I2C_SDA(idx)) = PINMUX_INPUT_ENABLE;\n}\n"
  },
  {
    "path": "argon-first-stage/src/soc/smmu.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 balika011\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"soc/smmu.h\"\n#include \"soc/cluster.h\"\n#include \"soc/t210.h\"\n#include \"mem/mc_t210.h\"\n#include \"utils/util.h\"\n#include \"utils/aarch64_util.h\"\n\nbool smmu_used = false;\nu8 *_pageheap = (u8 *)SMMU_HEAP_ADDR;\n\n//Enabling SMMU requires a TZ secure write: MC(MC_SMMU_CONFIG) = 1;\nu8 smmu_payload[] __attribute__((aligned(16))) = {\n\t0x41, 0x01, 0x00, 0x58, // 0x00: LDR  X1, =0x70019010\n\t0x20, 0x00, 0x80, 0xD2, // 0x04: MOV  X0, #0x1\n\t0x20, 0x00, 0x00, 0xB9, // 0x08: STR  W0, [X1]\n\t0x1F, 0x71, 0x08, 0xD5, // 0x0C: IC   IALLUIS\n\t0x9F, 0x3B, 0x03, 0xD5, // 0x10: DSB  ISH\n\t0xFE, 0xFF, 0xFF, 0x17, // 0x14: B    loop\n\t0x00, 0x00, 0x80, 0xD2, // 0x18: MOV  X0, #0x0\n\t0x20, 0x00, 0x00, 0xB9, // 0x1C: STR  W0, [X1]\n\t0x80, 0x00, 0x00, 0x58, // 0x20: LDR  X0, =0x4002B000\n\t0x00, 0x00, 0x1F, 0xD6, // 0x28: BR   X0\n\t0x10, 0x90, 0x01, 0x70, // 0x28: MC_SMMU_CONFIG\n\t0x00, 0x00, 0x00, 0x00, // 0x2C:\n\t0x00, 0x00, 0x00, 0x00, // 0x30: secmon address\n\t0x00, 0x00, 0x00, 0x00  // 0x34:\n};\n\nvoid *page_alloc(u32 num)\n{\n\tu8 *res = _pageheap;\n\t_pageheap += 0x1000 * num;\n\tmemset(res, 0, 0x1000 * num);\n\treturn res;\n}\n\nu32 *smmu_alloc_pdir()\n{\n\tu32 *pdir = (u32 *)page_alloc(1);\n\tfor (int pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)\n\t\tpdir[pdn] = _PDE_VACANT(pdn);\n\treturn pdir;\n}\n\nvoid smmu_flush_regs()\n{\n\t(void)MC(MC_SMMU_PTB_DATA);\n}\n\nvoid smmu_flush_all()\n{\n\tMC(MC_SMMU_PTC_FLUSH) = 0;\n\tsmmu_flush_regs();\n\tMC(MC_SMMU_TLB_FLUSH) = 0;\n\tsmmu_flush_regs();\n}\n\nvoid smmu_init(u32 secmon_base)\n{\n\tMC(MC_SMMU_PTB_ASID) = 0;\n\tMC(MC_SMMU_PTB_DATA) = 0;\n\tMC(MC_SMMU_TLB_CONFIG) = 0x30000030;\n\tMC(MC_SMMU_PTC_CONFIG) = 0x28000F3F;\n\tMC(MC_SMMU_PTC_FLUSH) = 0;\n\tMC(MC_SMMU_TLB_FLUSH) = 0;\n\n\t// Set the secmon address\n\t*(u32 *)(smmu_payload + 0x30) = secmon_base;\n}\n\nvoid smmu_enable()\n{\n\tif (smmu_used)\n\t\treturn;\n\n\tcluster_boot_cpu0((u32)smmu_payload);\n\tsmmu_used = true;\n\tmsleep(150);\n\n\tsmmu_flush_all();\n}\n\nbool smmu_is_used()\n{\n\treturn smmu_used;\n}\n\nvoid smmu_exit()\n{\n\t*(uint32_t *)(smmu_payload + 0x14) = _NOP();\n}\n\nu32 *smmu_init_domain4(u32 dev_base, u32 asid)\n{\n\tu32 *pdir = smmu_alloc_pdir();\n\n\tMC(MC_SMMU_PTB_ASID) = asid;\n\tMC(MC_SMMU_PTB_DATA) = SMMU_MK_PDIR((u32)pdir, _PDIR_ATTR);\n\tsmmu_flush_regs();\n\n\tMC(dev_base) = 0x80000000 | (asid << 24) | (asid << 16) | (asid << 8) | (asid);\n\tsmmu_flush_regs();\n\n\treturn pdir;\n}\n\nu32 *smmu_get_pte(u32 *pdir, u32 iova)\n{\n\tu32 ptn = SMMU_ADDR_TO_PFN(iova);\n\tu32 pdn = SMMU_ADDR_TO_PDN(iova);\n\tu32 *ptbl;\n\n\tif (pdir[pdn] != _PDE_VACANT(pdn))\n\t\tptbl = (u32 *)((pdir[pdn] & SMMU_PFN_MASK) << SMMU_PDIR_SHIFT);\n\telse\n\t{\n\t\tptbl = (u32 *)page_alloc(1);\n\t\tu32 addr = SMMU_PDN_TO_ADDR(pdn);\n\t\tfor (int pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SMMU_PAGE_SIZE)\n\t\t\tptbl[pn] = _PTE_VACANT(addr);\n\t\tpdir[pdn] = SMMU_MK_PDE((u32)ptbl, _PDE_ATTR | _PDE_NEXT);\n\t\tsmmu_flush_all();\n\t}\n\n\treturn &ptbl[ptn % SMMU_PTBL_COUNT];\n}\n\nvoid smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr)\n{\n\tfor (int i = 0; i < cnt; i++)\n\t{\n\t\tu32 *pte = smmu_get_pte(pdir, addr);\n\t\t*pte = SMMU_ADDR_TO_PFN(page) | attr;\n\t\taddr += 0x1000;\n\t\tpage += 0x1000;\n\t}\n\tsmmu_flush_all();\n}\n\nu32 *smmu_init_for_tsec()\n{\n\treturn smmu_init_domain4(MC_SMMU_TSEC_ASID, 1);\n}\n\nvoid smmu_deinit_for_tsec()\n{\n\tMC(MC_SMMU_PTB_ASID) = 1;\n\tMC(MC_SMMU_PTB_DATA) = 0;\n\tMC(MC_SMMU_TSEC_ASID) = 0;\n\tsmmu_flush_regs();\n}\n\n"
  },
  {
    "path": "argon-first-stage/src/soc/uart.c",
    "content": "/*\n* Copyright (c) 2018 naehrwert\n*\n* This program is free software; you can redistribute it and/or modify it\n* under the terms and conditions of the GNU General Public License,\n* version 2, as published by the Free Software Foundation.\n*\n* This program is distributed in the hope it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include \"soc/uart.h\"\n#include \"soc/t210.h\"\n#include \"utils/util.h\"\n\n/* UART A, B, C, D and E. */\nstatic const u32 uart_baseoff[5] = { 0, 0x40, 0x200, 0x300, 0x400 };\n\nvoid uart_init(u32 idx, u32 baud)\n{\n\tuart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);\n\n\t// Make sure no data is being sent.\n\tuart_wait_idle(idx, UART_TX_IDLE);\n\n\t// Misc settings.\n\tu32 rate = (8 * baud + 408000000) / (16 * baud);\n\tuart->UART_IER_DLAB = 0; // Disable interrupts.\n\tuart->UART_MCR = 0; // Disable hardware flow control.\n\tuart->UART_LCR = UART_LCR_DLAB | UART_LCR_WORD_LENGTH_8; // Enable DLAB & set 8n1 mode.\n\tuart->UART_THR_DLAB = (u8)rate; // Divisor latch LSB.\n\tuart->UART_IER_DLAB = (u8)(rate >> 8); // Divisor latch MSB.\n\tuart->UART_LCR = UART_LCR_WORD_LENGTH_8; // Diable DLAB.\n\n\t// Setup and flush fifo.\n\tuart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO | UART_IIR_FCR_RX_CLR | UART_IIR_FCR_TX_CLR;\n\tusleep(3 * ((baud + 999999) / baud));\n\tuart_wait_idle(idx, UART_TX_IDLE | UART_RX_IDLE);\n}\n\nvoid uart_wait_idle(u32 idx, u32 which)\n{\n\tuart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);\n\tif (UART_TX_IDLE & which)\n\t{\n\t\twhile (!(uart->UART_LSR & UART_LSR_TMTY))\n\t\t\t;\n\t}\n\tif (UART_RX_IDLE & which)\n\t{\n\t\twhile (uart->UART_LSR & UART_LSR_RDR)\n\t\t\t;\n\t}\n}\n\nvoid uart_send(u32 idx, u8 *buf, u32 len)\n{\n\tuart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);\n\n\tfor (u32 i = 0; i != len; i++)\n\t{\n\t\twhile (!(uart->UART_LSR & UART_LSR_THRE))\n\t\t\t;\n\t\tuart->UART_THR_DLAB = buf[i];\n\t};\n}\n\nvoid uart_recv(u32 idx, u8 *buf, u32 len)\n{\n\tuart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);\n\n\tfor (u32 i = 0; i != len; i++)\n\t{\n\t\twhile (!(uart->UART_LSR & UART_LSR_RDR))\n\t\t\t;\n\t\tbuf[i] = uart->UART_THR_DLAB;\n\t};\n}\n"
  },
  {
    "path": "argon-first-stage/src/start.s",
    "content": "/*\n* Copyright (c) 2018 naehrwert\n*\n* This program is free software; you can redistribute it and/or modify it\n* under the terms and conditions of the GNU General Public License,\n* version 2, as published by the Free Software Foundation.\n*\n* This program is distributed in the hope it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n.section .text._start\n.arm\n\n.extern _reloc_ipl\n.type _reloc_ipl, %function\n\n.extern memset\n.type memset, %function\n\n.extern ipl_main\n.type ipl_main, %function\n\n.globl _start\n.type _start, %function\n_start:\n\tADR R0, _start\n\tLDR R1, =__ipl_start\n\tCMP R0, R1\n\tBEQ _real_start\n\n\t/* If we are not in the right location already, copy a relocator to upper IRAM. */\n\tADR R2, _reloc_ipl\n\tLDR R3, =0x4003FF00\n\tMOV R4, #(_real_start - _reloc_ipl)\n_copy_loop:\n\tLDMIA R2!, {R5}\n\tSTMIA R3!, {R5}\n\tSUBS R4, #4\n\tBNE _copy_loop\n\n\t/* Use the relocator to copy ourselves into the right place. */\n\tLDR R2, =__ipl_end\n\tSUB R2, R2, R1\n\tLDR R3, =_real_start\n\tLDR R4, =0x4003FF00\n\tBX R4\n\n_reloc_ipl:\n\tLDMIA R0!, {R4-R7}\n\tSTMIA R1!, {R4-R7}\n\tSUBS R2, #0x10\n\tBNE _reloc_ipl\n\t/* Jump to the relocated entry. */\n\tBX R3\n\n_real_start:\n\t/* Initially, we place our stack in IRAM but will move it to SDRAM later. */\n\tLDR SP, =0x4003FF00\n\tLDR R0, =__bss_start\n\tEOR R1, R1, R1\n\tLDR R2, =__bss_end\n\tSUB R2, R2, R0\n\tBL memset\n\tBL ipl_main\n\tB .\n\n.globl pivot_stack\n.type pivot_stack, %function\npivot_stack:\n\tMOV SP, R0\n\tBX LR"
  },
  {
    "path": "argon-first-stage/src/storage/sdmmc.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n#include \"storage/sdmmc.h\"\n#include \"storage/mmc.h\"\n#include \"storage/sd.h\"\n#include \"gfx/gfx.h\"\n#include \"mem/heap.h\"\n#include \"utils/util.h\"\n\n#define DPRINTF(...)\n\n#pragma GCC push_options\n#pragma GCC target (\"thumb\")\n\nstatic inline u32 unstuff_bits(u32 *resp, u32 start, u32 size)\n{\n\tconst u32 mask = (size < 32 ? 1 << size : 0) - 1;\n\tconst u32 off = 3 - ((start) / 32);\n\tconst u32 shft = (start) & 31;\n\tu32 res = resp[off] >> shft;\n\tif (size + shft > 32)\n\t\tres |= resp[off - 1] << ((32 - shft) % 32);\n\treturn res & mask;\n}\n\n/*\n* Common functions for SD and MMC.\n*/\n\nstatic int _sdmmc_storage_check_result(u32 res)\n{\n\t//Error mask:\n\t//R1_OUT_OF_RANGE, R1_ADDRESS_ERROR, R1_BLOCK_LEN_ERROR,\n\t//R1_ERASE_SEQ_ERROR, R1_ERASE_PARAM, R1_WP_VIOLATION,\n\t//R1_LOCK_UNLOCK_FAILED, R1_COM_CRC_ERROR, R1_ILLEGAL_COMMAND,\n\t//R1_CARD_ECC_FAILED, R1_CC_ERROR, R1_ERROR, R1_CID_CSD_OVERWRITE,\n\t//R1_WP_ERASE_SKIP, R1_ERASE_RESET, R1_SWITCH_ERROR\n\tif (!(res & 0xFDF9A080))\n\t\treturn 1;\n\t//TODO: R1_SWITCH_ERROR we can skip for certain card types.\n\treturn 0;\n}\n\nstatic int _sdmmc_storage_execute_cmd_type1_ex(sdmmc_storage_t *storage, u32 *resp, u32 cmd, u32 arg, u32 check_busy, u32 expected_state, u32 mask)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, cmd, arg, SDMMC_RSP_TYPE_1, check_busy);\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0))\n\t\treturn 0;\n\n\tsdmmc_get_rsp(storage->sdmmc, resp, 4, SDMMC_RSP_TYPE_1);\n\tif (mask)\n\t\t*resp &= ~mask;\n\n\tif (_sdmmc_storage_check_result(*resp))\n\t\tif (expected_state == 0x10 || R1_CURRENT_STATE(*resp) == expected_state)\n\t\t\treturn 1;\n\treturn 0;\n}\n\nstatic int _sdmmc_storage_execute_cmd_type1(sdmmc_storage_t *storage, u32 cmd, u32 arg, u32 check_busy, u32 expected_state)\n{\n\tu32 tmp;\n\treturn _sdmmc_storage_execute_cmd_type1_ex(storage, &tmp, cmd, arg, check_busy, expected_state, 0);\n}\n\nstatic int _sdmmc_storage_go_idle_state(sdmmc_storage_t *storage)\n{\n\tsdmmc_cmd_t cmd;\n\tsdmmc_init_cmd(&cmd, MMC_GO_IDLE_STATE, 0, SDMMC_RSP_TYPE_0, 0);\n\treturn sdmmc_execute_cmd(storage->sdmmc, &cmd, 0, 0);\n}\n\nstatic int _sdmmc_storage_get_cid(sdmmc_storage_t *storage, void *buf)\n{\n\tsdmmc_cmd_t cmd;\n\tsdmmc_init_cmd(&cmd, MMC_ALL_SEND_CID, 0, SDMMC_RSP_TYPE_2, 0);\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmd, 0, 0))\n\t\treturn 0;\n\tsdmmc_get_rsp(storage->sdmmc, buf, 0x10, SDMMC_RSP_TYPE_2);\n\treturn 1;\n}\n\nstatic int _sdmmc_storage_select_card(sdmmc_storage_t *storage)\n{\n\treturn _sdmmc_storage_execute_cmd_type1(storage, MMC_SELECT_CARD, storage->rca << 16, 1, 0x10);\n}\n\nstatic int _sdmmc_storage_get_csd(sdmmc_storage_t *storage, void *buf)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, MMC_SEND_CSD, storage->rca << 16, SDMMC_RSP_TYPE_2, 0);\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0))\n\t\treturn 0;\n\tsdmmc_get_rsp(storage->sdmmc, buf, 0x10, SDMMC_RSP_TYPE_2);\n\treturn 1;\n}\n\nstatic int _sdmmc_storage_set_blocklen(sdmmc_storage_t *storage, u32 blocklen)\n{\n\treturn _sdmmc_storage_execute_cmd_type1(storage, MMC_SET_BLOCKLEN, blocklen, 0, R1_STATE_TRAN);\n}\n\nstatic int _sdmmc_storage_get_status(sdmmc_storage_t *storage, u32 *resp, u32 mask)\n{\n\treturn _sdmmc_storage_execute_cmd_type1_ex(storage, resp, MMC_SEND_STATUS, storage->rca << 16, 0, R1_STATE_TRAN, mask);\n}\n\nstatic int _sdmmc_storage_check_status(sdmmc_storage_t *storage)\n{\n\tu32 tmp;\n\treturn _sdmmc_storage_get_status(storage, &tmp, 0);\n}\n\nstatic int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out, u32 sector, u32 num_sectors, void *buf, u32 is_write)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, is_write ? MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK, sector, SDMMC_RSP_TYPE_1, 0);\n\n\tsdmmc_req_t reqbuf;\n\treqbuf.buf = buf;\n\treqbuf.num_sectors = num_sectors;\n\treqbuf.blksize = 512;\n\treqbuf.is_write = is_write;\n\treqbuf.is_multi_block = 1;\n\treqbuf.is_auto_cmd12 = 1;\n\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, blkcnt_out))\n\t{\n\t\tu32 tmp = 0;\n\t\tsdmmc_stop_transmission(storage->sdmmc, &tmp);\n\t\t_sdmmc_storage_get_status(storage, &tmp, 0);\n\t\treturn 0;\n\t}\n\treturn 1;\n}\n\nint sdmmc_storage_end(sdmmc_storage_t *storage)\n{\n\tif (!_sdmmc_storage_go_idle_state(storage))\n\t\treturn 0;\n\tsdmmc_end(storage->sdmmc);\n\treturn 1;\n}\n\nstatic int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf, u32 is_write)\n{\n\tu8 *bbuf = (u8 *)buf;\n\n\twhile (num_sectors)\n\t{\n\t\tu32 blkcnt = 0;\n\t\t//Retry 9 times on error.\n\t\tu32 retries = 10;\n\t\tdo\n\t\t{\n\t\t\tif (_sdmmc_storage_readwrite_ex(storage, &blkcnt, sector, MIN(num_sectors, 0xFFFF), bbuf, is_write))\n\t\t\t\tgoto out;\n\t\t\telse\n\t\t\t\tretries--;\n\n\t\t\tmsleep(100);\n\t\t} while (retries);\n\t\treturn 0;\n\nout:;\n\t\tDPRINTF(\"readwrite: %08X\\n\", blkcnt);\n\t\tsector += blkcnt;\n\t\tnum_sectors -= blkcnt;\n\t\tbbuf += 512 * blkcnt;\n\t}\n\treturn 1;\n}\n\nint sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf)\n{\n\treturn _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 0);\n}\n\nint sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf)\n{\n\treturn _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 1);\n}\n\n/*\n* MMC specific functions.\n*/\n\nstatic int _mmc_storage_get_op_cond_inner(sdmmc_storage_t *storage, u32 *pout, u32 power)\n{\n\tsdmmc_cmd_t cmd;\n\n\tu32 arg = 0;\n\tswitch (power)\n\t{\n\tcase SDMMC_POWER_1_8:\n\t\targ = 0x40000080; //Sector access, voltage.\n\t\tbreak;\n\tcase SDMMC_POWER_3_3:\n\t\targ = 0x403F8000; //Sector access, voltage.\n\t\tbreak;\n\tdefault:\n\t\treturn 0;\n\t}\n\n\tsdmmc_init_cmd(&cmd, MMC_SEND_OP_COND, arg, SDMMC_RSP_TYPE_3, 0);\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmd, 0, 0))\n\t\treturn 0;\n\n\treturn sdmmc_get_rsp(storage->sdmmc, pout, 4, SDMMC_RSP_TYPE_3);\n}\n\nstatic int _mmc_storage_get_op_cond(sdmmc_storage_t *storage, u32 power)\n{\n\tu32 timeout = get_tmr_ms() + 1500;\n\n\twhile (1)\n\t{\n\t\tu32 cond = 0;\n\t\tif (!_mmc_storage_get_op_cond_inner(storage, &cond, power))\n\t\t\tbreak;\n\t\tif (cond & MMC_CARD_BUSY)\n\t\t{\n\t\t\tif (cond & 0x40000000)\n\t\t\t\tstorage->has_sector_access = 1;\n\t\t\treturn 1;\n\t\t}\n\t\tif (get_tmr_ms() > timeout)\n\t\t\tbreak;\n\t\tusleep(1000);\n\t}\n\n\treturn 0;\n}\n\nstatic int _mmc_storage_set_relative_addr(sdmmc_storage_t *storage)\n{\n\treturn _sdmmc_storage_execute_cmd_type1(storage, MMC_SET_RELATIVE_ADDR, storage->rca << 16, 0, 0x10);\n}\n\nstatic void _mmc_storage_parse_cid(sdmmc_storage_t *storage)\n{\n\tu32 *raw_cid = (u32 *)&(storage->raw_cid);\n\n\tswitch (storage->csd.mmca_vsn)\n\t{\n\tcase 0: /* MMC v1.0 - v1.2 */\n\tcase 1: /* MMC v1.4 */\n\t\tstorage->cid.prod_name[6] = unstuff_bits(raw_cid, 48, 8);\n\t\tstorage->cid.manfid = unstuff_bits(raw_cid, 104, 24);\n\t\tstorage->cid.hwrev  = unstuff_bits(raw_cid, 44, 4);\n\t\tstorage->cid.fwrev  = unstuff_bits(raw_cid, 40, 4);\n\t\tstorage->cid.serial = unstuff_bits(raw_cid, 16, 24);\n\t\tbreak;\n\tcase 2: /* MMC v2.0 - v2.2 */\n\tcase 3: /* MMC v3.1 - v3.3 */\n\tcase 4: /* MMC v4 */\n\t\tstorage->cid.manfid   = unstuff_bits(raw_cid, 120, 8);\n\t\tstorage->cid.card_bga = unstuff_bits(raw_cid, 112, 2);\n\t\tstorage->cid.oemid    = unstuff_bits(raw_cid, 104, 8);\n\t\tstorage->cid.prv      = unstuff_bits(raw_cid, 48, 8);\n\t\tstorage->cid.serial   = unstuff_bits(raw_cid, 16, 32);\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\tstorage->cid.prod_name[0] = unstuff_bits(raw_cid, 96, 8);\n\tstorage->cid.prod_name[1] = unstuff_bits(raw_cid, 88, 8);\n\tstorage->cid.prod_name[2] = unstuff_bits(raw_cid, 80, 8);\n\tstorage->cid.prod_name[3] = unstuff_bits(raw_cid, 72, 8);\n\tstorage->cid.prod_name[4] = unstuff_bits(raw_cid, 64, 8);\n\tstorage->cid.prod_name[5] = unstuff_bits(raw_cid, 56, 8);\n\n\tstorage->cid.month = unstuff_bits(raw_cid, 12, 4);\n\tstorage->cid.year  = unstuff_bits(raw_cid, 8, 4) + 1997;\n\tif (storage->ext_csd.rev >= 5)\n\t{\n\t\tif (storage->cid.year < 2010)\n\t\t\tstorage->cid.year += 16;\n\t}\n}\n\nstatic void _mmc_storage_parse_csd(sdmmc_storage_t *storage)\n{\n\tu32 *raw_csd = (u32 *)&(storage->raw_csd);\n\n\tstorage->csd.mmca_vsn = unstuff_bits(raw_csd, 122, 4);\n\tstorage->csd.structure = unstuff_bits(raw_csd, 126, 2);\n\tstorage->csd.cmdclass = unstuff_bits(raw_csd, 84, 12);\n\tstorage->csd.read_blkbits = unstuff_bits(raw_csd, 80, 4);\n\tstorage->csd.capacity = (1 + unstuff_bits(raw_csd, 62, 12)) << (unstuff_bits(raw_csd, 47, 3) + 2);\n}\n\nstatic void _mmc_storage_parse_ext_csd(sdmmc_storage_t *storage, u8 *buf)\n{\n\tstorage->ext_csd.rev = buf[EXT_CSD_REV];\n\tstorage->ext_csd.ext_struct = buf[EXT_CSD_STRUCTURE];\n\tstorage->ext_csd.card_type = buf[EXT_CSD_CARD_TYPE];\n\tstorage->ext_csd.dev_version = *(u16 *)&buf[EXT_CSD_DEVICE_VERSION];\n\tstorage->ext_csd.boot_mult = buf[EXT_CSD_BOOT_MULT];\n\tstorage->ext_csd.rpmb_mult = buf[EXT_CSD_RPMB_MULT];\n\tstorage->ext_csd.sectors = *(u32 *)&buf[EXT_CSD_SEC_CNT];\n\tstorage->ext_csd.bkops = buf[EXT_CSD_BKOPS_SUPPORT];\n\tstorage->ext_csd.bkops_en = buf[EXT_CSD_BKOPS_EN];\n\tstorage->ext_csd.bkops_status = buf[EXT_CSD_BKOPS_STATUS];\n\n\tstorage->sec_cnt  = *(u32 *)&buf[EXT_CSD_SEC_CNT];\n}\n\nstatic int _mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, MMC_SEND_EXT_CSD, 0, SDMMC_RSP_TYPE_1, 0);\n\n\tsdmmc_req_t reqbuf;\n\treqbuf.buf = buf;\n\treqbuf.blksize = 512;\n\treqbuf.num_sectors = 1;\n\treqbuf.is_write = 0;\n\treqbuf.is_multi_block = 0;\n\treqbuf.is_auto_cmd12 = 0;\n\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, 0))\n\t\treturn 0;\n\n\tu32 tmp = 0;\n\tsdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);\n\t_mmc_storage_parse_ext_csd(storage, buf);\n\n\treturn _sdmmc_storage_check_result(tmp);\n}\n\nstatic int _mmc_storage_switch(sdmmc_storage_t *storage, u32 arg)\n{\n\treturn _sdmmc_storage_execute_cmd_type1(storage, MMC_SWITCH, arg, 1, 0x10);\n}\n\nstatic int _mmc_storage_switch_buswidth(sdmmc_storage_t *storage, u32 bus_width)\n{\n\tif (bus_width == SDMMC_BUS_WIDTH_1)\n\t\treturn 1;\n\n\tu32 arg = 0;\n\tswitch (bus_width)\n\t{\n\tcase SDMMC_BUS_WIDTH_4:\n\t\targ = SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4);\n\t\tbreak;\n\tcase SDMMC_BUS_WIDTH_8:\n\t\targ = SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8);\n\t\tbreak;\n\t}\n\n\tif (_mmc_storage_switch(storage, arg))\n\t\tif (_sdmmc_storage_check_status(storage))\n\t\t{\n\t\t\tsdmmc_set_bus_width(storage->sdmmc, bus_width);\n\t\t\treturn 1;\n\t\t}\n\n\treturn 0;\n}\n\nstatic int _mmc_storage_enable_HS(sdmmc_storage_t *storage, int check)\n{\n\tif (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS)))\n\t\treturn 0;\n\tif (check && !_sdmmc_storage_check_status(storage))\n\t\treturn 0;\n\tif (!sdmmc_setup_clock(storage->sdmmc, 2))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] switched to HS\\n\");\n\tstorage->csd.busspeed = 52;\n\tif (check || _sdmmc_storage_check_status(storage))\n\t\treturn 1;\n\treturn 0;\n}\n\nstatic int _mmc_storage_enable_HS200(sdmmc_storage_t *storage)\n{\n\tif (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS200)))\n\t\treturn 0;\n\tif (!sdmmc_setup_clock(storage->sdmmc, 3))\n\t\treturn 0;\n\tif (!sdmmc_config_tuning(storage->sdmmc, 3, MMC_SEND_TUNING_BLOCK_HS200))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] switched to HS200\\n\");\n\tstorage->csd.busspeed = 200;\n\treturn _sdmmc_storage_check_status(storage);\n}\n\nstatic int _mmc_storage_enable_HS400(sdmmc_storage_t *storage)\n{\n\tif (!_mmc_storage_enable_HS200(storage))\n\t\treturn 0;\n\tsdmmc_get_venclkctl(storage->sdmmc);\n\tif (!_mmc_storage_enable_HS(storage, 0))\n\t\treturn 0;\n\tif (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_DDR_BUS_WIDTH_8)))\n\t\treturn 0;\n\tif (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400)))\n\t\treturn 0;\n\tif (!sdmmc_setup_clock(storage->sdmmc, 4))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] switched to HS400\\n\");\n\tstorage->csd.busspeed = 400;\n\treturn _sdmmc_storage_check_status(storage);\n}\n\nstatic int _mmc_storage_enable_highspeed(sdmmc_storage_t *storage, u32 card_type, u32 type)\n{\n\t//TODO: this should be a config item.\n\t// --v\n\tif (!1 || sdmmc_get_voltage(storage->sdmmc) != SDMMC_POWER_1_8)\n\t\tgoto out;\n\n\tif (sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_8 &&\n\t\tcard_type & EXT_CSD_CARD_TYPE_HS400_1_8V &&\n\t\ttype == 4)\n\t\treturn _mmc_storage_enable_HS400(storage);\n\n\tif (sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_8 ||\n\t\t(sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_4\n\t\t&& card_type & EXT_CSD_CARD_TYPE_HS200_1_8V\n\t\t&& (type == 4 || type == 3)))\n\t\treturn _mmc_storage_enable_HS200(storage);\n\nout:;\n\tif (card_type & EXT_CSD_CARD_TYPE_HS_52)\n\t\treturn _mmc_storage_enable_HS(storage, 1);\n\treturn 1;\n}\n\nstatic int _mmc_storage_enable_bkops(sdmmc_storage_t *storage)\n{\n\tif (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_SET_BITS, EXT_CSD_BKOPS_EN, EXT_CSD_BKOPS_LEVEL_2)))\n\t\treturn 0;\n\treturn _sdmmc_storage_check_status(storage);\n}\n\nint sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type)\n{\n\tmemset(storage, 0, sizeof(sdmmc_storage_t));\n\tstorage->sdmmc = sdmmc;\n\tstorage->rca = 2; //TODO: this could be a config item.\n\n\tif (!sdmmc_init(sdmmc, id, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_1, 0, 0))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] after init\\n\");\n\n\tusleep(1000 + (74000 + sdmmc->divisor - 1) / sdmmc->divisor);\n\n\tif (!_sdmmc_storage_go_idle_state(storage))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] went to idle state\\n\");\n\n\tif (!_mmc_storage_get_op_cond(storage, SDMMC_POWER_1_8))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] got op cond\\n\");\n\n\tif (!_sdmmc_storage_get_cid(storage, storage->raw_cid))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] got cid\\n\");\n\n\tif (!_mmc_storage_set_relative_addr(storage))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] set relative addr\\n\");\n\n\tif (!_sdmmc_storage_get_csd(storage, storage->raw_csd))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] got csd\\n\");\n\t_mmc_storage_parse_csd(storage);\n\n\tif (!sdmmc_setup_clock(storage->sdmmc, 1))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] after setup clock\\n\");\n\n\tif (!_sdmmc_storage_select_card(storage))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] card selected\\n\");\n\n\tif (!_sdmmc_storage_set_blocklen(storage, 512))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] set blocklen to 512\\n\");\n\n\tu32 *csd = (u32 *)storage->raw_csd;\n\t//Check system specification version, only version 4.0 and later support below features.\n\tif (unstuff_bits(csd, 122, 4) < CSD_SPEC_VER_4)\n\t{\n\t\tstorage->sec_cnt = (1 + unstuff_bits(csd, 62, 12)) << (unstuff_bits(csd, 47, 3) + 2);\n\t\treturn 1;\n\t}\n\n\tif (!_mmc_storage_switch_buswidth(storage, bus_width))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] switched buswidth\\n\");\n\n\tu8 *ext_csd = (u8 *)malloc(512);\n\tif (!_mmc_storage_get_ext_csd(storage, ext_csd))\n\t{\n\t\tfree(ext_csd);\n\t\treturn 0;\n\t}\n\tfree(ext_csd);\n\tDPRINTF(\"[MMC] got ext_csd\\n\");\n\t_mmc_storage_parse_cid(storage); //This needs to be after csd and ext_csd\n\t//gfx_hexdump(0, ext_csd, 512);\n\n\t/* When auto BKOPS is enabled the mmc device should be powered all the time until we disable this and check status.\n\t   Disable it for now until BKOPS disable added to power down sequence at sdmmc_storage_end().\n\t   Additionally this works only when we put the device in idle mode which we don't after enabling it. */\n\tif (storage->ext_csd.bkops & 0x1 && !(storage->ext_csd.bkops_en & EXT_CSD_BKOPS_LEVEL_2) && 0)\n\t{\n\t\t_mmc_storage_enable_bkops(storage);\n\t\tDPRINTF(\"[MMC] BKOPS enabled\\n\");\n\t}\n\telse\n\t{\n\t\tDPRINTF(\"[MMC] BKOPS disabled\\n\");\n\t}\n\n\tif (!_mmc_storage_enable_highspeed(storage, storage->ext_csd.card_type, type))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] succesfully switched to highspeed mode\\n\");\n\n\tsdmmc_sd_clock_ctrl(storage->sdmmc, 1);\n\n\treturn 1;\n}\n\nint sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition)\n{\n\tif (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_PART_CONFIG, partition)))\n\t\treturn 0;\n\tif (!_sdmmc_storage_check_status(storage))\n\t\treturn 0;\n\tstorage->partition = partition;\n\treturn 1;\n}\n\n/*\n* SD specific functions.\n*/\n\nstatic int _sd_storage_execute_app_cmd(sdmmc_storage_t *storage, u32 expected_state, u32 mask, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out)\n{\n\tu32 tmp;\n\tif (!_sdmmc_storage_execute_cmd_type1_ex(storage, &tmp, MMC_APP_CMD, storage->rca << 16, 0, expected_state, mask))\n\t\treturn 0;\n\treturn sdmmc_execute_cmd(storage->sdmmc, cmd, req, blkcnt_out);\n}\n\nstatic int _sd_storage_execute_app_cmd_type1(sdmmc_storage_t *storage, u32 *resp, u32 cmd, u32 arg, u32 check_busy, u32 expected_state)\n{\n\tif (!_sdmmc_storage_execute_cmd_type1(storage, MMC_APP_CMD, storage->rca << 16, 0, R1_STATE_TRAN))\n\t\treturn 0;\n\treturn _sdmmc_storage_execute_cmd_type1_ex(storage, resp, cmd, arg, check_busy, expected_state, 0);\n}\n\nstatic int _sd_storage_send_if_cond(sdmmc_storage_t *storage)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, 0x1AA, SDMMC_RSP_TYPE_5, 0);\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0))\n\t\treturn 1; // The SD Card is version 1.X\n\n\tu32 resp = 0;\n\tif (!sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_5))\n\t\treturn 2;\n\n\treturn (resp & 0xFF) == 0xAA ? 0 : 2;\n}\n\nstatic int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, int is_version_1, int supports_low_voltage)\n{\n\tsdmmc_cmd_t cmdbuf;\n\t// Support for Current > 150mA\n\tu32 arg = (~is_version_1 & 1) ? SD_OCR_XPC : 0;\n\t// Support for handling block-addressed SDHC cards\n\targ\t|= (~is_version_1 & 1) ? SD_OCR_CCS : 0;\n\t// Support for 1.8V\n\targ |= (supports_low_voltage & ~is_version_1 & 1) ? SD_OCR_S18R : 0;\n\t// This is needed for most cards. Do not set bit7 even if 1.8V is supported.\n\targ |= SD_OCR_VDD_32_33;\n\tsdmmc_init_cmd(&cmdbuf, SD_APP_OP_COND, arg, SDMMC_RSP_TYPE_3, 0);\n\tif (!_sd_storage_execute_app_cmd(storage, 0x10, is_version_1 ? 0x400000 : 0, &cmdbuf, 0, 0))\n\t\treturn 0;\n\treturn sdmmc_get_rsp(storage->sdmmc, cond, 4, SDMMC_RSP_TYPE_3);\n}\n\nstatic int _sd_storage_get_op_cond(sdmmc_storage_t *storage, int is_version_1, int supports_low_voltage)\n{\n\tu32 timeout = get_tmr_ms() + 1500;\n\n\twhile (1)\n\t{\n\t\tu32 cond = 0;\n\t\tif (!_sd_storage_get_op_cond_once(storage, &cond, is_version_1, supports_low_voltage))\n\t\t\tbreak;\n\t\tif (cond & MMC_CARD_BUSY)\n\t\t{\n\t\t\tif (cond & SD_OCR_CCS)\n\t\t\t\tstorage->has_sector_access = 1;\n\n\t\t\tif (cond & SD_ROCR_S18A && supports_low_voltage)\n\t\t\t{\n\t\t\t\t//The low voltage regulator configuration is valid for SDMMC1 only.\n\t\t\t\tif (storage->sdmmc->id == SDMMC_1 &&\n\t\t\t\t\t_sdmmc_storage_execute_cmd_type1(storage, SD_SWITCH_VOLTAGE, 0, 0, R1_STATE_READY))\n\t\t\t\t{\n\t\t\t\t\tif (!sdmmc_enable_low_voltage(storage->sdmmc))\n\t\t\t\t\t\treturn 0;\n\t\t\t\t\tstorage->is_low_voltage = 1;\n\n\t\t\t\t\tDPRINTF(\"-> switched to low voltage\\n\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn 1;\n\t\t}\n\t\tif (get_tmr_ms() > timeout)\n\t\t\tbreak;\n\t\tmsleep(10); // Needs to be at least 10ms for some SD Cards\n\t}\n\n\treturn 0;\n}\n\nstatic int _sd_storage_get_rca(sdmmc_storage_t *storage)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, SD_SEND_RELATIVE_ADDR, 0, SDMMC_RSP_TYPE_4, 0);\n\n\tu32 timeout = get_tmr_ms() + 1500;\n\n\twhile (1)\n\t{\n\t\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0))\n\t\t\tbreak;\n\n\t\tu32 resp = 0;\n\t\tif (!sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_4))\n\t\t\tbreak;\n\n\t\tif (resp >> 16)\n\t\t{\n\t\t\tstorage->rca = resp >> 16;\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (get_tmr_ms() > timeout)\n\t\t\tbreak;\n\t\tusleep(1000);\n\t}\n\n\treturn 0;\n}\n\nstatic void _sd_storage_parse_scr(sdmmc_storage_t *storage)\n{\n\t// unstuff_bits can parse only 4 u32\n\tu32 resp[4];\n\n\tresp[3] = *(u32 *)&storage->raw_scr[4];\n\tresp[2] = *(u32 *)&storage->raw_scr[0];\n\n\tstorage->scr.sda_vsn = unstuff_bits(resp, 56, 4);\n\tstorage->scr.bus_widths = unstuff_bits(resp, 48, 4);\n\tif (storage->scr.sda_vsn == SCR_SPEC_VER_2)\n\t\t/* Check if Physical Layer Spec v3.0 is supported */\n\t\tstorage->scr.sda_spec3 = unstuff_bits(resp, 47, 1);\n\tif (storage->scr.sda_spec3)\n\t\tstorage->scr.cmds = unstuff_bits(resp, 32, 2);\n}\n\nint _sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, SD_APP_SEND_SCR, 0, SDMMC_RSP_TYPE_1, 0);\n\n\tsdmmc_req_t reqbuf;\n\treqbuf.buf = buf;\n\treqbuf.blksize = 8;\n\treqbuf.num_sectors = 1;\n\treqbuf.is_write = 0;\n\treqbuf.is_multi_block = 0;\n\treqbuf.is_auto_cmd12 = 0;\n\n\tif (!_sd_storage_execute_app_cmd(storage, R1_STATE_TRAN, 0, &cmdbuf, &reqbuf, 0))\n\t\treturn 0;\n\n\tu32 tmp = 0;\n\tsdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);\n\t//Prepare buffer for unstuff_bits\n\tfor (int i = 0; i < 8; i+=4)\n\t{\n\t\tstorage->raw_scr[i + 3] = buf[i];\n\t\tstorage->raw_scr[i + 2] = buf[i + 1];\n\t\tstorage->raw_scr[i + 1] = buf[i + 2];\n\t\tstorage->raw_scr[i]     = buf[i + 3];\n\t}\n\t_sd_storage_parse_scr(storage);\n\t//gfx_hexdump(0, storage->raw_scr, 8);\n\n\treturn _sdmmc_storage_check_result(tmp);\n}\n\nint _sd_storage_switch_get(sdmmc_storage_t *storage, void *buf)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, SD_SWITCH, 0xFFFFFF, SDMMC_RSP_TYPE_1, 0);\n\n\tsdmmc_req_t reqbuf;\n\treqbuf.buf = buf;\n\treqbuf.blksize = 64;\n\treqbuf.num_sectors = 1;\n\treqbuf.is_write = 0;\n\treqbuf.is_multi_block = 0;\n\treqbuf.is_auto_cmd12 = 0;\n\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, 0))\n\t\treturn 0;\n\n\tu32 tmp = 0;\n\tsdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);\n\treturn _sdmmc_storage_check_result(tmp);\n}\n\nint _sd_storage_switch(sdmmc_storage_t *storage, void *buf, int mode, int group, u32 arg)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tu32 switchcmd = mode << 31 | 0x00FFFFFF;\n\tswitchcmd &= ~(0xF << (group * 4));\n\tswitchcmd |= arg << (group * 4);\n\tsdmmc_init_cmd(&cmdbuf, SD_SWITCH, switchcmd, SDMMC_RSP_TYPE_1, 0);\n\n\tsdmmc_req_t reqbuf;\n\treqbuf.buf = buf;\n\treqbuf.blksize = 64;\n\treqbuf.num_sectors = 1;\n\treqbuf.is_write = 0;\n\treqbuf.is_multi_block = 0;\n\treqbuf.is_auto_cmd12 = 0;\n\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, 0))\n\t\treturn 0;\n\n\tu32 tmp = 0;\n\tsdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);\n\treturn _sdmmc_storage_check_result(tmp);\n}\n\nvoid _sd_storage_set_current_limit(sdmmc_storage_t *storage, u8 *buf)\n{\n\tu32 pwr = SD_SET_CURRENT_LIMIT_800;\n\t_sd_storage_switch(storage, buf, SD_SWITCH_SET, 3, pwr);\n\n\twhile (pwr > 0)\n\t{\n\t\tpwr--;\n\t\t_sd_storage_switch(storage, buf, SD_SWITCH_SET, 3, pwr);\n\t\tif (((buf[15] >> 4) & 0x0F) == pwr)\n\t\t\tbreak;\n\t}\n\n\tswitch (pwr)\n\t{\n\tcase SD_SET_CURRENT_LIMIT_800:\n\t\tDPRINTF(\"[SD] Power limit raised to 800mA\\n\");\n\t\tbreak;\n\tcase SD_SET_CURRENT_LIMIT_600:\n\t\tDPRINTF(\"[SD] Power limit raised to 600mA\\n\");\n\t\tbreak;\n\tcase SD_SET_CURRENT_LIMIT_400:\n\t\tDPRINTF(\"[SD] Power limit raised to 800mA\\n\");\n\t\tbreak;\n\tdefault:\n\tcase SD_SET_CURRENT_LIMIT_200:\n\t\tDPRINTF(\"[SD] Power limit defaulted to 200mA\\n\");\n\t\tbreak;\n\t}\n}\n\nint _sd_storage_enable_highspeed(sdmmc_storage_t *storage, u32 hs_type, u8 *buf)\n{\n\tif (!_sd_storage_switch(storage, buf, SD_SWITCH_CHECK, 0, hs_type))\n\t\treturn 0;\n\n\tu32 type_out = buf[16] & 0xF;\n\tif (type_out != hs_type)\n\t\treturn 0;\n\n\tif ((((u16)buf[0] << 8) | buf[1]) < 0x320)\n\t{\n\t\tif (!_sd_storage_switch(storage, buf, SD_SWITCH_SET, 0, hs_type))\n\t\t\treturn 0;\n\n\t\tif (type_out != (buf[16] & 0xF))\n\t\t\treturn 0;\n\t}\n\n\treturn 1;\n}\n\nint _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8 *buf)\n{\n\t// Try to raise the current limit to let the card perform better.\n\t_sd_storage_set_current_limit(storage, buf);\n\n\tif (sdmmc_get_bus_width(storage->sdmmc) != SDMMC_BUS_WIDTH_4)\n\t\treturn 0;\n\n\tif (!_sd_storage_switch_get(storage, buf))\n\t\treturn 0;\n\t//gfx_hexdump(0, (u8 *)buf, 64);\n\n\tu32 hs_type = 0;\n\tswitch (type)\n\t{\n\tcase 11:\n\t\t// Fall through if not supported.\n\t\tif (buf[13] & SD_MODE_UHS_SDR104)\n\t\t{\n\t\t\ttype = 11;\n\t\t\ths_type = UHS_SDR104_BUS_SPEED;\n\t\t\tDPRINTF(\"[SD] Bus speed set to SDR104\\n\");\n\t\t\tstorage->csd.busspeed = 104;\n\t\t\tbreak;\n\t\t}\n\tcase 10:\n\t\tif (buf[13] & SD_MODE_UHS_SDR50)\n\t\t{\n\t\t\ttype = 10;\n\t\t\ths_type = UHS_SDR50_BUS_SPEED;\n\t\t\tDPRINTF(\"[SD] Bus speed set to SDR50\\n\");\n\t\t\tstorage->csd.busspeed = 50;\n\t\t\tbreak;\n\t\t}\n\tcase 8:\n\t\tif (!(buf[13] & SD_MODE_UHS_SDR12))\n\t\t\treturn 0;\n\t\ttype = 8;\n\t\ths_type = UHS_SDR12_BUS_SPEED;\n\t\tDPRINTF(\"[SD] Bus speed set to SDR12\\n\");\n\t\tstorage->csd.busspeed = 12;\n\t\tbreak;\n\tdefault:\n\t\treturn 0;\n\t\tbreak;\n\t}\n\n\tif (!_sd_storage_enable_highspeed(storage, hs_type, buf))\n\t\treturn 0;\n\tif (!sdmmc_setup_clock(storage->sdmmc, type))\n\t\treturn 0;\n\tif (!sdmmc_config_tuning(storage->sdmmc, type, MMC_SEND_TUNING_BLOCK))\n\t\treturn 0;\n\treturn _sdmmc_storage_check_status(storage);\n}\n\nint _sd_storage_enable_highspeed_high_volt(sdmmc_storage_t *storage, u8 *buf)\n{\n\tif (!_sd_storage_switch_get(storage, buf))\n\t\treturn 0;\n\t//gfx_hexdump(0, (u8 *)buf, 64);\n\tif (!(buf[13] & SD_MODE_HIGH_SPEED))\n\t\treturn 1;\n\n\tif (!_sd_storage_enable_highspeed(storage, 1, buf))\n\t\treturn 0;\n\tif (!_sdmmc_storage_check_status(storage))\n\t\treturn 0;\n\treturn sdmmc_setup_clock(storage->sdmmc, 7);\n}\n\nstatic void _sd_storage_parse_ssr(sdmmc_storage_t *storage)\n{\n\t// unstuff_bits supports only 4 u32 so break into 2 x 16byte groups\n\tu32 raw_ssr1[4];\n\tu32 raw_ssr2[4];\n\n\traw_ssr1[3] = *(u32 *)&storage->raw_ssr[12];\n\traw_ssr1[2] = *(u32 *)&storage->raw_ssr[8];\n\traw_ssr1[1] = *(u32 *)&storage->raw_ssr[4];\n\traw_ssr1[0] = *(u32 *)&storage->raw_ssr[0];\n\n\traw_ssr2[3] = *(u32 *)&storage->raw_ssr[28];\n\traw_ssr2[2] = *(u32 *)&storage->raw_ssr[24];\n\traw_ssr2[1] = *(u32 *)&storage->raw_ssr[20];\n\traw_ssr2[0] = *(u32 *)&storage->raw_ssr[16];\n\n\tstorage->ssr.bus_width = (unstuff_bits(raw_ssr1, 510 - 384, 2) & SD_BUS_WIDTH_4) ? 4 : 1;\n\tswitch(unstuff_bits(raw_ssr1, 440 - 384, 8))\n\t{\n\tcase 0:\n\t\tstorage->ssr.speed_class = 0;\n\t\tbreak;\n\tcase 1:\n\t\tstorage->ssr.speed_class = 2;\n\t\tbreak;\n\tcase 2:\n\t\tstorage->ssr.speed_class = 4;\n\t\tbreak;\n\tcase 3:\n\t\tstorage->ssr.speed_class = 6;\n\t\tbreak;\n\tcase 4:\n\t\tstorage->ssr.speed_class = 10;\n\t\tbreak;\n\tdefault:\n\t\tstorage->ssr.speed_class = unstuff_bits(raw_ssr1, 440 - 384, 8);\n\t\tbreak;\n\t}\n\tstorage->ssr.uhs_grade = unstuff_bits(raw_ssr1, 396 - 384, 4);\n\tstorage->ssr.video_class = unstuff_bits(raw_ssr1, 384 - 384, 8);\n\n\tstorage->ssr.app_class = unstuff_bits(raw_ssr2, 336 - 256, 4);\n}\n\nstatic int _sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, SD_APP_SD_STATUS, 0, SDMMC_RSP_TYPE_1, 0);\n\n\tsdmmc_req_t reqbuf;\n\treqbuf.buf = buf;\n\treqbuf.blksize = 64;\n\treqbuf.num_sectors = 1;\n\treqbuf.is_write = 0;\n\treqbuf.is_multi_block = 0;\n\treqbuf.is_auto_cmd12 = 0;\n\n\tif (!(storage->csd.cmdclass & CCC_APP_SPEC))\n\t{\n\t\tDPRINTF(\"[SD] ssr: Card lacks mandatory SD Status function\\n\");\n\t\treturn 0;\n\t}\n\n\tif (!_sd_storage_execute_app_cmd(storage, R1_STATE_TRAN, 0, &cmdbuf, &reqbuf, 0))\n\t\treturn 0;\n\n\tu32 tmp = 0;\n\tsdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);\n    //Prepare buffer for unstuff_bits\n\tfor (int i = 0; i < 64; i+=4)\n\t{\n\t\tstorage->raw_ssr[i + 3] = buf[i];\n\t\tstorage->raw_ssr[i + 2] = buf[i + 1];\n\t\tstorage->raw_ssr[i + 1] = buf[i + 2];\n\t\tstorage->raw_ssr[i]     = buf[i + 3];\n\t}\n\t_sd_storage_parse_ssr(storage);\n\t//gfx_hexdump(0, storage->raw_ssr, 64);\n\n\treturn _sdmmc_storage_check_result(tmp);\n}\n\nstatic void _sd_storage_parse_cid(sdmmc_storage_t *storage)\n{\n\tu32 *raw_cid = (u32 *)&(storage->raw_cid);\n\n\tstorage->cid.manfid = unstuff_bits(raw_cid, 120, 8);\n\tstorage->cid.oemid  = unstuff_bits(raw_cid, 104, 16);\n\tstorage->cid.prod_name[0] = unstuff_bits(raw_cid, 96, 8);\n\tstorage->cid.prod_name[1] = unstuff_bits(raw_cid, 88, 8);\n\tstorage->cid.prod_name[2] = unstuff_bits(raw_cid, 80, 8);\n\tstorage->cid.prod_name[3] = unstuff_bits(raw_cid, 72, 8);\n\tstorage->cid.prod_name[4] = unstuff_bits(raw_cid, 64, 8);\n\tstorage->cid.hwrev  = unstuff_bits(raw_cid, 60, 4);\n\tstorage->cid.fwrev  = unstuff_bits(raw_cid, 56, 4);\n\tstorage->cid.serial = unstuff_bits(raw_cid, 24, 32);\n\tstorage->cid.month  = unstuff_bits(raw_cid, 8, 4);\n\tstorage->cid.year   = unstuff_bits(raw_cid, 12, 8) + 2000;\n}\n\nstatic void _sd_storage_parse_csd(sdmmc_storage_t *storage)\n{\n\tu32 *raw_csd = (u32 *)&(storage->raw_csd);\n\n\tstorage->csd.structure = unstuff_bits(raw_csd, 126, 2);\n\tstorage->csd.cmdclass  = unstuff_bits(raw_csd, 84, 12);\n\tstorage->csd.read_blkbits  = unstuff_bits(raw_csd, 80, 4);\n\tstorage->csd.write_protect = unstuff_bits(raw_csd, 12, 2);\n\tswitch(storage->csd.structure)\n\t{\n\tcase 0:\n\t\tstorage->csd.capacity = (1 + unstuff_bits(raw_csd, 62, 12)) << (unstuff_bits(raw_csd, 47, 3) + 2);\n\t\tbreak;\n\tcase 1:\n\t\tstorage->csd.c_size = (1 + unstuff_bits(raw_csd, 48, 22));\n\t\tstorage->csd.capacity = storage->csd.c_size << 10;\n\t\tstorage->csd.read_blkbits = 9;\n\t\tbreak;\n\t}\n}\n\nint sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type)\n{\n\tint is_version_1 = 0;\n\t\n\t// Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.\n\tmsleep(100);\n\n\tmemset(storage, 0, sizeof(sdmmc_storage_t));\n\tstorage->sdmmc = sdmmc;\n\n\tif (!sdmmc_init(sdmmc, id, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, 5, 0))\n\t\treturn 0;\n\tDPRINTF(\"[SD] after init\\n\");\n\n\tusleep(1000 + (74000 + sdmmc->divisor - 1) / sdmmc->divisor);\n\n\tif (!_sdmmc_storage_go_idle_state(storage))\n\t\treturn 0;\n\tDPRINTF(\"[SD] went to idle state\\n\");\n\n\tis_version_1 = _sd_storage_send_if_cond(storage);\n\tif (is_version_1 == 2)\n\t\treturn 0;\n\tDPRINTF(\"[SD] after send if cond\\n\");\n\n\tif (!_sd_storage_get_op_cond(storage, is_version_1, bus_width == SDMMC_BUS_WIDTH_4 && type == 11))\n\t\treturn 0;\n\tDPRINTF(\"[SD] got op cond\\n\");\n\n\tif (!_sdmmc_storage_get_cid(storage, storage->raw_cid))\n\t\treturn 0;\n\tDPRINTF(\"[SD] got cid\\n\");\n\t_sd_storage_parse_cid(storage);\n\n\tif (!_sd_storage_get_rca(storage))\n\t\treturn 0;\n\tDPRINTF(\"[SD] got rca (= %04X)\\n\", storage->rca);\n\n\tif (!_sdmmc_storage_get_csd(storage, storage->raw_csd))\n\t\treturn 0;\n\tDPRINTF(\"[SD] got csd\\n\");\n\n\t//Parse CSD.\n\t_sd_storage_parse_csd(storage);\n\tswitch (storage->csd.structure)\n\t{\n\tcase 0:\n\t\tstorage->sec_cnt = storage->csd.capacity;\n\t\tbreak;\n\tcase 1:\n\t\tstorage->sec_cnt = storage->csd.c_size << 10;\n\t\tbreak;\n\tdefault:\n\t\tDPRINTF(\"[SD] Unknown CSD structure %d\\n\", storage->csd.structure);\n\t\tbreak;\n\t}\n\n\tif (!storage->is_low_voltage)\n\t{\n\t\tif (!sdmmc_setup_clock(storage->sdmmc, 6))\n\t\t\treturn 0;\n\t\tDPRINTF(\"[SD] after setup clock\\n\");\n\t}\n\n\tif (!_sdmmc_storage_select_card(storage))\n\t\treturn 0;\n\tDPRINTF(\"[SD] card selected\\n\");\n\n\tif (!_sdmmc_storage_set_blocklen(storage, 512))\n\t\treturn 0;\n\tDPRINTF(\"[SD] set blocklen to 512\\n\");\n\n\tu32 tmp = 0;\n\tif (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_CLR_CARD_DETECT, 0, 0, R1_STATE_TRAN))\n\t\treturn 0;\n\tDPRINTF(\"[SD] cleared card detect\\n\");\n\n\tu8 *buf = (u8 *)malloc(512);\n\tif (!_sd_storage_get_scr(storage, buf))\n\t{\n\t\tfree(buf);\n\t\treturn 0;\n\t}\n\t\t\n\t//gfx_hexdump(0, storage->raw_scr, 8);\n\tDPRINTF(\"[SD] got scr\\n\");\n\n\t// Check if card supports a wider bus and if it's not SD Version 1.X\n\tif (bus_width == SDMMC_BUS_WIDTH_4 && (storage->scr.bus_widths & 4) && (storage->scr.sda_vsn & 0xF))\n\t{\n\t\tif (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_BUS_WIDTH, SD_BUS_WIDTH_4, 0, R1_STATE_TRAN))\n\t\t{\n\t\t\tfree(buf);\n\t\t\treturn 0;\n\t\t}\n\t\tsdmmc_set_bus_width(storage->sdmmc, SDMMC_BUS_WIDTH_4);\n\t\tDPRINTF(\"[SD] switched to wide bus width\\n\");\n\t}\n\telse\n\t{\n\t\tDPRINTF(\"[SD] SD does not support wide bus width\\n\");\n\t}\n\n\tif (storage->is_low_voltage)\n\t{\n\t\tif (!_sd_storage_enable_highspeed_low_volt(storage, type, buf))\n\t\t{\n\t\t\tfree(buf);\n\t\t\treturn 0;\n\t\t}\n\t\tDPRINTF(\"[SD] enabled highspeed (low voltage)\\n\");\n\t}\n\telse if (type != 6 && (storage->scr.sda_vsn & 0xF) != 0)\n\t{\n\t\tif (!_sd_storage_enable_highspeed_high_volt(storage, buf))\n\t\t{\n\t\t\tfree(buf);\n\t\t\treturn 0;\n\t\t}\n\t\tDPRINTF(\"[SD] enabled highspeed (high voltage)\\n\");\n\t\tstorage->csd.busspeed = 25;\n\t}\n\n\tsdmmc_sd_clock_ctrl(sdmmc, 1);\n\n\t// Parse additional card info from sd status.\n\tif (_sd_storage_get_ssr(storage, buf))\n\t{\n\t\tDPRINTF(\"[SD] got sd status\\n\");\n\t}\n\n\tfree(buf);\n\treturn 1;\n}\n\n/*\n* Gamecard specific functions.\n*/\n\nint _gc_storage_custom_cmd(sdmmc_storage_t *storage, void *buf)\n{\n\tu32 resp;\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, 60, 0, SDMMC_RSP_TYPE_1, 1);\n\n\tsdmmc_req_t reqbuf;\n\treqbuf.buf = buf;\n\treqbuf.blksize = 64;\n\treqbuf.num_sectors = 1;\n\treqbuf.is_write = 1;\n\treqbuf.is_multi_block = 0;\n\treqbuf.is_auto_cmd12 = 0;\n\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, 0))\n\t{\n\t\tsdmmc_stop_transmission(storage->sdmmc, &resp);\n\t\treturn 0;\n\t}\n\n\tif (!sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_1))\n\t\treturn 0;\n\tif (!_sdmmc_storage_check_result(resp))\n\t\treturn 0;\n\treturn _sdmmc_storage_check_status(storage);\n}\n\nint sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc)\n{\n\tmemset(storage, 0, sizeof(sdmmc_storage_t));\n\tstorage->sdmmc = sdmmc;\n\n\tif (!sdmmc_init(sdmmc, SDMMC_2, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_8, 14, 0))\n\t\treturn 0;\n\tDPRINTF(\"[gc] after init\\n\");\n\n\tusleep(1000 + (10000 + sdmmc->divisor - 1) / sdmmc->divisor);\n\n\tif (!sdmmc_config_tuning(storage->sdmmc, 14, MMC_SEND_TUNING_BLOCK_HS200))\n\t\treturn 0;\n\tDPRINTF(\"[gc] after tuning\\n\");\n\n\tsdmmc_sd_clock_ctrl(sdmmc, 1);\n\n\treturn 1;\n}\n\n#pragma GCC pop_options\n"
  },
  {
    "path": "argon-first-stage/src/storage/sdmmc_driver.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"storage/mmc.h\"\n#include \"storage/sdmmc.h\"\n#include \"gfx/gfx.h\"\n#include \"power/max7762x.h\"\n#include \"soc/bpmp.h\"\n#include \"soc/clock.h\"\n#include \"soc/gpio.h\"\n#include \"soc/pinmux.h\"\n#include \"soc/pmc.h\"\n#include \"soc/t210.h\"\n#include \"utils/util.h\"\n\n//#define DPRINTF(...) gfx_printf(__VA_ARGS__)\n#define DPRINTF(...)\n\n\n/*! SCMMC controller base addresses. */\nstatic const u32 _sdmmc_bases[4] = {\n\t0x700B0000,\n\t0x700B0200,\n\t0x700B0400,\n\t0x700B0600,\n};\n\nint sdmmc_get_voltage(sdmmc_t *sdmmc)\n{\n\tu32 p = sdmmc->regs->pwrcon;\n\tif (!(p & TEGRA_MMC_PWRCTL_SD_BUS_POWER))\n\t\treturn SDMMC_POWER_OFF;\n\tif (p & TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8)\n\t\treturn SDMMC_POWER_1_8;\n\tif (p & TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3)\n\t\treturn SDMMC_POWER_3_3;\n\treturn -1;\n}\n\nstatic int _sdmmc_set_voltage(sdmmc_t *sdmmc, u32 power)\n{\n\tu8 pwr = 0;\n\n\tswitch (power)\n\t{\n\tcase SDMMC_POWER_OFF:\n\t\tsdmmc->regs->pwrcon &= ~TEGRA_MMC_PWRCTL_SD_BUS_POWER;\n\t\tbreak;\n\tcase SDMMC_POWER_1_8:\n\t\tsdmmc->regs->pwrcon = TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8;\n\t\tpwr = TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8;\n\t\tbreak;\n\tcase SDMMC_POWER_3_3:\n\t\tsdmmc->regs->pwrcon = TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3;\n\t\tpwr = TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3;\n\t\tbreak;\n\tdefault:\n\t\treturn 0;\n\t}\n\n\tif (power != SDMMC_POWER_OFF)\n\t{\n\t\tpwr |= TEGRA_MMC_PWRCTL_SD_BUS_POWER;\n\t\tsdmmc->regs->pwrcon = pwr;\n\t}\t\n\n\treturn 1;\n}\n\nu32 sdmmc_get_bus_width(sdmmc_t *sdmmc)\n{\n\tu32 h = sdmmc->regs->hostctl;\n\tif (h & TEGRA_MMC_HOSTCTL_8BIT)\n\t\treturn SDMMC_BUS_WIDTH_8;\n\tif (h & TEGRA_MMC_HOSTCTL_4BIT)\n\t\treturn SDMMC_BUS_WIDTH_4;\n\treturn SDMMC_BUS_WIDTH_1;\n}\n\nvoid sdmmc_set_bus_width(sdmmc_t *sdmmc, u32 bus_width)\n{\n\tif (bus_width == SDMMC_BUS_WIDTH_1)\n\t\tsdmmc->regs->hostctl &= ~(TEGRA_MMC_HOSTCTL_4BIT | TEGRA_MMC_HOSTCTL_8BIT);\n\telse if (bus_width == SDMMC_BUS_WIDTH_4)\n\t{\n\t\tsdmmc->regs->hostctl |= TEGRA_MMC_HOSTCTL_4BIT;\n\t\tsdmmc->regs->hostctl &= ~TEGRA_MMC_HOSTCTL_8BIT;\n\t}\n\telse if (bus_width == SDMMC_BUS_WIDTH_8)\n\t\tsdmmc->regs->hostctl |= TEGRA_MMC_HOSTCTL_8BIT;\n}\n\nvoid sdmmc_get_venclkctl(sdmmc_t *sdmmc)\n{\n\tsdmmc->venclkctl_tap = sdmmc->regs->venclkctl >> 16;\n\tsdmmc->venclkctl_set = 1;\n}\n\nstatic int _sdmmc_config_ven_ceata_clk(sdmmc_t *sdmmc, u32 id)\n{\n\tu32 tap_val = 0;\n\n\tif (id == 4)\n\t\tsdmmc->regs->venceatactl = (sdmmc->regs->venceatactl & 0xFFFFC0FF) | 0x2800;\n\tsdmmc->regs->ventunctl0 &= 0xFFFDFFFF;\n\tif (id == 4)\n\t{\n\t\tif (!sdmmc->venclkctl_set)\n\t\t\treturn 0;\n\t\ttap_val = sdmmc->venclkctl_tap;\n\t}\n\telse\n\t{\n\t\tstatic const u32 tap_values[] = { 4, 0, 3, 0 };\n\t\ttap_val = tap_values[sdmmc->id];\n\t}\n\tsdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (tap_val << 16);\n\n\treturn 1;\n}\n\nstatic int _sdmmc_get_clkcon(sdmmc_t *sdmmc)\n{\n\treturn sdmmc->regs->clkcon;\n}\n\nstatic void _sdmmc_pad_config_fallback(sdmmc_t *sdmmc, u32 power)\n{\n\t_sdmmc_get_clkcon(sdmmc);\n\tswitch (sdmmc->id)\n\t{\n\tcase SDMMC_1:\n\t\tif (power == SDMMC_POWER_OFF)\n\t\t\tbreak;\n\t\tif (power == SDMMC_POWER_1_8)\n\t\t\tAPB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = 0x304; // Up: 3, Dn: 4.\n\t\telse if (power == SDMMC_POWER_3_3)\n\t\t\tAPB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = 0x808; // Up: 8, Dn: 8.\n\t\tbreak;\n\tcase SDMMC_4:\n\t\tAPB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) & 0x3FFC) | 0x1040;\n\t\tbreak;\n\t}\n\t//TODO: load standard values for other controllers, can depend on power.\n}\n\nstatic int _sdmmc_wait_type4(sdmmc_t *sdmmc)\n{\n\tint res = 1, should_disable_sd_clock = 0;\n\n\tif (!(sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE))\n\t{\n\t\tshould_disable_sd_clock = 1;\n\t\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t}\n\n\tsdmmc->regs->vendllcal |= 0x80000000;\n\t_sdmmc_get_clkcon(sdmmc);\n\n\tu32 timeout = get_tmr_ms() + 5;\n\twhile (sdmmc->regs->vendllcal & 0x80000000)\n\t{\n\t\tif (get_tmr_ms() > timeout)\n\t\t{\n\t\t\tres = 0;\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\ttimeout = get_tmr_ms() + 10;\n\twhile (sdmmc->regs->dllcfgstatus & 0x80000000)\n\t{\n\t\tif (get_tmr_ms() > timeout)\n\t\t{\n\t\t\tres = 0;\n\t\t\tgoto out;\n\t\t}\n\t}\n\nout:;\n\tif (should_disable_sd_clock)\n\t\tsdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\treturn res;\n}\n\nint sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)\n{\n\t// Disable the SD clock if it was enabled, and reenable it later.\n\tbool should_enable_sd_clock = false;\n\tif (sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE)\n\t{\n\t\tshould_enable_sd_clock = true;\n\t\tsdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t}\n\n\t_sdmmc_config_ven_ceata_clk(sdmmc, type);\n\n\tswitch (type)\n\t{\n\tcase 0:\n\tcase 1:\n\tcase 5:\n\tcase 6:\n\t\tsdmmc->regs->hostctl  &= 0xFB; // Should this be 0xFFFB (~4) ?\n\t\tsdmmc->regs->hostctl2 &= SDHCI_CTRL_VDD_330;\n\t\tbreak;\n\tcase 2:\n\tcase 7:\n\t\tsdmmc->regs->hostctl  |= 4;\n\t\tsdmmc->regs->hostctl2 &= SDHCI_CTRL_VDD_330;\n\t\tbreak;\n\tcase 3:\n\tcase 11:\n\tcase 13:\n\tcase 14:\n\t\tsdmmc->regs->hostctl2  = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR104_BUS_SPEED;\n\t\tsdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;\n\t\tbreak;\n\tcase 4:\n\t\t // Non standard\n\t\tsdmmc->regs->hostctl2  = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | HS400_BUS_SPEED;\n\t\tsdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;\n\t\tbreak;\n\tcase 8:\n\t\tsdmmc->regs->hostctl2  = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR12_BUS_SPEED;\n\t\tsdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;\n\t\tbreak;\n\tcase 10:\n\t\t// T210 Errata for SDR50, the host must be set to SDR104.\n\t\tsdmmc->regs->hostctl2  = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR104_BUS_SPEED;\n\t\tsdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;\n\t\tbreak;\n\t}\n\n\t_sdmmc_get_clkcon(sdmmc);\n\n\tu32 tmp;\n\tu16 divisor;\n\tclock_sdmmc_get_params(&tmp, &divisor, type);\n\tclock_sdmmc_config_clock_source(&tmp, sdmmc->id, tmp);\n\tsdmmc->divisor = (tmp + divisor - 1) / divisor;\n\n\t//if divisor != 1 && divisor << 31 -> error\n\n\tu16 div = divisor >> 1;\n\tdivisor = 0;\n\tif (div > 0xFF)\n\t\tdivisor = div >> 8;\n\tsdmmc->regs->clkcon = (sdmmc->regs->clkcon & 0x3F) | (div << 8) | (divisor << 6);\n\n\t// Enable the SD clock again.\n\tif (should_enable_sd_clock)\n\t\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\n\tif (type == 4)\n\t\treturn _sdmmc_wait_type4(sdmmc);\n\treturn 1;\n}\n\nstatic void _sdmmc_sd_clock_enable(sdmmc_t *sdmmc)\n{\n\tif (!sdmmc->no_sd)\n\t{\n\t\tif (!(sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE))\n\t\t\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t}\n\tsdmmc->sd_clock_enabled = 1;\n}\n\nstatic void _sdmmc_sd_clock_disable(sdmmc_t *sdmmc)\n{\n\tsdmmc->sd_clock_enabled = 0;\n\tsdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n}\n\nvoid sdmmc_sd_clock_ctrl(sdmmc_t *sdmmc, int no_sd)\n{\n\tsdmmc->no_sd = no_sd;\n\tif (no_sd)\n\t{\n\t\tif (!(sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE))\n\t\t\treturn;\n\t\tsdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t\treturn;\n\t}\n\tif (sdmmc->sd_clock_enabled)\n\t\tif (!(sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE))\n\t\t\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n}\n\nstatic int _sdmmc_cache_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)\n{\n\tswitch (type)\n\t{\n\tcase SDMMC_RSP_TYPE_1:\n\tcase SDMMC_RSP_TYPE_3:\n\tcase SDMMC_RSP_TYPE_4:\n\tcase SDMMC_RSP_TYPE_5:\n\t\tif (size < 4)\n\t\t\treturn 0;\n\t\trsp[0] = sdmmc->regs->rspreg0;\n\t\tbreak;\n\tcase SDMMC_RSP_TYPE_2:\n\t\tif (size < 0x10)\n\t\t\treturn 0;\n\t\t// CRC is stripped, so shifting is needed.\n\t\tu32 tempreg;\n\t\tfor (int i = 0; i < 4; i++)\n\t\t{\n\t\t\tswitch(i)\n\t\t\t{\n\t\t\tcase 0:\n\t\t\t\ttempreg = sdmmc->regs->rspreg3;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\ttempreg = sdmmc->regs->rspreg2;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\ttempreg = sdmmc->regs->rspreg1;\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\ttempreg = sdmmc->regs->rspreg0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\trsp[i] = tempreg << 8;\n\n\t\t\tif (i != 0)\n\t\t\t\trsp[i - 1] |= (tempreg >> 24) & 0xFF;\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\treturn 0;\n\t\tbreak;\n\t}\n\n\treturn 1;\n}\n\nint sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)\n{\n\tif (!rsp || sdmmc->expected_rsp_type != type)\n\t\treturn 0;\n\n\tswitch (type)\n\t{\n\tcase SDMMC_RSP_TYPE_1:\n\tcase SDMMC_RSP_TYPE_3:\n\tcase SDMMC_RSP_TYPE_4:\n\tcase SDMMC_RSP_TYPE_5:\n\t\tif (size < 4)\n\t\t\treturn 0;\n\t\trsp[0] = sdmmc->rsp[0];\n\t\tbreak;\n\tcase SDMMC_RSP_TYPE_2:\n\t\tif (size < 0x10)\n\t\t\treturn 0;\n\t\trsp[0] = sdmmc->rsp[0];\n\t\trsp[1] = sdmmc->rsp[1];\n\t\trsp[2] = sdmmc->rsp[2];\n\t\trsp[3] = sdmmc->rsp[3];\n\t\tbreak;\n\tdefault:\n\t\treturn 0;\n\t\tbreak;\n\t}\n\n\treturn 1;\n}\n\nstatic void _sdmmc_reset(sdmmc_t *sdmmc)\n{\n\tsdmmc->regs->swrst |= \n\t\tTEGRA_MMC_SWRST_SW_RESET_FOR_CMD_LINE | TEGRA_MMC_SWRST_SW_RESET_FOR_DAT_LINE;\n\t_sdmmc_get_clkcon(sdmmc);\n\tu32 timeout = get_tmr_ms() + 2000;\n\twhile (sdmmc->regs->swrst << 29 >> 30 && get_tmr_ms() < timeout)\n\t\t;\n}\n\nstatic int _sdmmc_wait_prnsts_type0(sdmmc_t *sdmmc, u32 wait_dat)\n{\n\t_sdmmc_get_clkcon(sdmmc);\n\n\tu32 timeout = get_tmr_ms() + 2000;\n\twhile(sdmmc->regs->prnsts & 1) // CMD inhibit.\n\t\tif (get_tmr_ms() > timeout)\n\t\t{\n\t\t\t_sdmmc_reset(sdmmc);\n\t\t\treturn 0;\n\t\t}\n\n\tif (wait_dat)\n\t{\n\t\ttimeout = get_tmr_ms() + 2000;\n\t\twhile (sdmmc->regs->prnsts & 2) // DAT inhibit.\n\t\t\tif (get_tmr_ms() > timeout)\n\t\t\t{\n\t\t\t\t_sdmmc_reset(sdmmc);\n\t\t\t\treturn 0;\n\t\t\t}\n\t}\n\n\treturn 1;\n}\n\nstatic int _sdmmc_wait_prnsts_type1(sdmmc_t *sdmmc)\n{\n\t_sdmmc_get_clkcon(sdmmc);\n\n\tu32 timeout = get_tmr_ms() + 2000;\n\twhile (!(sdmmc->regs->prnsts & 0x100000)) // DAT0 line level.\n\t\tif (get_tmr_ms() > timeout)\n\t\t{\n\t\t\t_sdmmc_reset(sdmmc);\n\t\t\treturn 0;\n\t\t}\n\n\treturn 1;\n}\n\nstatic int _sdmmc_setup_read_small_block(sdmmc_t *sdmmc)\n{\n\tswitch (sdmmc_get_bus_width(sdmmc))\n\t{\n\tcase SDMMC_BUS_WIDTH_1:\n\t\treturn 0;\n\t\tbreak;\n\tcase SDMMC_BUS_WIDTH_4:\n\t\tsdmmc->regs->blksize = 0x40;\n\t\tbreak;\n\tcase SDMMC_BUS_WIDTH_8:\n\t\tsdmmc->regs->blksize = 0x80;\n\t\tbreak;\n\t}\n\tsdmmc->regs->blkcnt = 1;\n\tsdmmc->regs->trnmod = TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ;\n\treturn 1;\n}\n\nstatic int _sdmmc_parse_cmdbuf(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, bool is_data_present)\n{\n\tu16 cmdflags = 0;\n\t\n\tswitch (cmd->rsp_type)\n\t{\n\tcase SDMMC_RSP_TYPE_0:\n\t\tbreak;\n\tcase SDMMC_RSP_TYPE_1:\n\tcase SDMMC_RSP_TYPE_4:\n\tcase SDMMC_RSP_TYPE_5:\n\t\tif (cmd->check_busy)\n\t\t\tcmdflags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48_BUSY |\n\t\t\t\tTEGRA_MMC_TRNMOD_CMD_INDEX_CHECK |\n\t\t\t\tTEGRA_MMC_TRNMOD_CMD_CRC_CHECK;\n\t\telse\n\t\t\tcmdflags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48 |\n\t\t\t\tTEGRA_MMC_TRNMOD_CMD_INDEX_CHECK |\n\t\t\t\tTEGRA_MMC_TRNMOD_CMD_CRC_CHECK;\n\t\tbreak;\n\tcase SDMMC_RSP_TYPE_2:\n\t\tcmdflags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_136 |\n\t\t\tTEGRA_MMC_TRNMOD_CMD_CRC_CHECK;\n\t\tbreak;\n\tcase SDMMC_RSP_TYPE_3:\n\t\tcmdflags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48;\n\t\tbreak;\n\tdefault:\n\t\treturn 0;\n\t\tbreak;\n\t}\n\n\tif (is_data_present)\n\t\tcmdflags |= TEGRA_MMC_TRNMOD_DATA_PRESENT_SELECT_DATA_TRANSFER;\n\tsdmmc->regs->argument = cmd->arg;\n\tsdmmc->regs->cmdreg = (cmd->cmd << 8) | cmdflags;\n\n\treturn 1;\n}\n\nstatic void _sdmmc_parse_cmd_48(sdmmc_t *sdmmc, u32 cmd)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tcmdbuf.cmd = cmd;\n\tcmdbuf.arg = 0;\n\tcmdbuf.rsp_type = SDMMC_RSP_TYPE_1;\n\tcmdbuf.check_busy = 0;\n\t_sdmmc_parse_cmdbuf(sdmmc, &cmdbuf, true);\n}\n\nstatic int _sdmmc_config_tuning_once(sdmmc_t *sdmmc, u32 cmd)\n{\n\tif (sdmmc->no_sd)\n\t\treturn 0;\n\tif (!_sdmmc_wait_prnsts_type0(sdmmc, 1))\n\t\treturn 0;\n\n\t_sdmmc_setup_read_small_block(sdmmc);\n\tsdmmc->regs->norintstsen |= TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY;\n\tsdmmc->regs->norintsts = sdmmc->regs->norintsts;\n\tsdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t_sdmmc_parse_cmd_48(sdmmc, cmd);\n\t_sdmmc_get_clkcon(sdmmc);\n\tusleep(1);\n\t_sdmmc_reset(sdmmc);\n\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t_sdmmc_get_clkcon(sdmmc);\n\n\tu32 timeout = get_tmr_us() + 5000;\n\twhile (get_tmr_us() < timeout)\n\t{\n\t\tif (sdmmc->regs->norintsts & 0x20)\n\t\t{\n\t\t\tsdmmc->regs->norintsts = 0x20;\n\t\t\tsdmmc->regs->norintstsen &= 0xFFDF;\n\t\t\t_sdmmc_get_clkcon(sdmmc);\n\t\t\tusleep((1000 * 8 + sdmmc->divisor - 1) / sdmmc->divisor);\n\t\t\treturn 1;\n\t\t}\n\t}\n\t_sdmmc_reset(sdmmc);\n\tsdmmc->regs->norintstsen &= 0xFFDF;\n\t_sdmmc_get_clkcon(sdmmc);\n\tusleep((1000 * 8 + sdmmc->divisor - 1) / sdmmc->divisor);\n\treturn 0;\n}\n\nint sdmmc_config_tuning(sdmmc_t *sdmmc, u32 type, u32 cmd)\n{\n\tu32 max = 0, flag = 0;\n\n\tsdmmc->regs->field_1C4 = 0;\n\tswitch (type)\n\t{\n\tcase 3:\n\tcase 4:\n\tcase 11:\n\t\tmax = 0x80;\n\t\tflag = 0x4000;\n\t\tbreak;\n\tcase 10:\n\tcase 13:\n\tcase 14:\n\t\tmax = 0x100;\n\t\tflag = 0x8000;\n\t\tbreak;\n\tdefault:\n\t\treturn 0;\n\t}\n\n\tsdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | flag;\n\tsdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | 0x40;\n\tsdmmc->regs->ventunctl0 |= 0x20000;\n\tsdmmc->regs->hostctl2  |= SDHCI_CTRL_EXEC_TUNING;\n\n\tfor (u32 i = 0; i < max; i++)\n\t{\n\t\t_sdmmc_config_tuning_once(sdmmc, cmd);\n\t\tif (!(sdmmc->regs->hostctl2 & SDHCI_CTRL_EXEC_TUNING))\n\t\t\tbreak;\n\t}\n\n\tif (sdmmc->regs->hostctl2 & SDHCI_CTRL_TUNED_CLK)\n\t\treturn 1;\n\treturn 0;\n}\n\nstatic int _sdmmc_enable_internal_clock(sdmmc_t *sdmmc)\n{\n\t//Enable internal clock and wait till it is stable.\n\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_INTERNAL_CLOCK_ENABLE;\n\t_sdmmc_get_clkcon(sdmmc);\n\tu32 timeout = get_tmr_ms() + 2000;\n\twhile (!(sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_INTERNAL_CLOCK_STABLE))\n\t{\n\t\tif (get_tmr_ms() > timeout)\n\t\t\treturn 0;\n\t}\n\n\tsdmmc->regs->hostctl2 &= ~SDHCI_CTRL_PRESET_VAL_EN;\n\tsdmmc->regs->clkcon   &= ~TEGRA_MMC_CLKCON_CLKGEN_SELECT;\n\tsdmmc->regs->hostctl2 |= SDHCI_HOST_VERSION_4_EN;\n\n\tif (!(sdmmc->regs->capareg & 0x10000000))\n\t\treturn 0;\n\n\tsdmmc->regs->hostctl2 |= SDHCI_ADDRESSING_64BIT_EN;\n\tsdmmc->regs->hostctl &= 0xE7;\n\tsdmmc->regs->timeoutcon = (sdmmc->regs->timeoutcon & 0xF0) | 0xE;\n\n\treturn 1;\n}\n\nstatic int _sdmmc_autocal_config_offset(sdmmc_t *sdmmc, u32 power)\n{\n\tu32 off_pd = 0;\n\tu32 off_pu = 0;\n\n\tswitch (sdmmc->id)\n\t{\n\tcase SDMMC_2:\n\tcase SDMMC_4:\n\t\tif (power != SDMMC_POWER_1_8)\n\t\t\treturn 0;\n\t\toff_pd = 5;\n\t\toff_pu = 5;\n\t\tbreak;\n\tcase SDMMC_1:\n\tcase SDMMC_3:\n\t\tif (power == SDMMC_POWER_1_8)\n\t\t{\n\t\t\toff_pd = 123;\n\t\t\toff_pu = 123;\n\t\t}\n\t\telse if (power == SDMMC_POWER_3_3)\n\t\t{\n\t\t\toff_pd = 125;\n\t\t\toff_pu = 0;\n\t\t}\n\t\telse\n\t\t\treturn 0;\n\t\tbreak;\n\t}\n\n\tsdmmc->regs->autocalcfg = (((sdmmc->regs->autocalcfg & 0xFFFF80FF) | (off_pd << 8)) >> 7 << 7) | off_pu;\n\treturn 1;\n}\n\nstatic void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)\n{\n\tbool should_enable_sd_clock = false;\n\tif (sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE)\n\t{\n\t\tshould_enable_sd_clock = true;\n\t\tsdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t}\n\n\tif (!(sdmmc->regs->sdmemcmppadctl & 0x80000000))\n\t{\n\t\tsdmmc->regs->sdmemcmppadctl |= 0x80000000;\n\t\t_sdmmc_get_clkcon(sdmmc);\n\t\tusleep(1);\n\t}\n\n\tsdmmc->regs->autocalcfg |= 0xA0000000;\n\t_sdmmc_get_clkcon(sdmmc);\n\tusleep(1);\n\n\tu32 timeout = get_tmr_ms() + 10;\n\twhile (sdmmc->regs->autocalcfg & 0x80000000)\n\t{\n\t\tif (get_tmr_ms() > timeout)\n\t\t{\n\t\t\t// In case autocalibration fails, we load suggested standard values.\n\t\t\t_sdmmc_pad_config_fallback(sdmmc, power);\n\t\t\tsdmmc->regs->autocalcfg &= 0xDFFFFFFF;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tsdmmc->regs->sdmemcmppadctl &= 0x7FFFFFFF;\n\n\tif(should_enable_sd_clock)\n\t\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n}\n\nstatic void _sdmmc_enable_interrupts(sdmmc_t *sdmmc)\n{\n\tsdmmc->regs->norintstsen |= 0xB;\n\tsdmmc->regs->errintstsen |= 0x17F;\n\tsdmmc->regs->norintsts = sdmmc->regs->norintsts;\n\tsdmmc->regs->errintsts = sdmmc->regs->errintsts;\n}\n\nstatic void _sdmmc_mask_interrupts(sdmmc_t *sdmmc)\n{\n\tsdmmc->regs->errintstsen &= 0xFE80;\n\tsdmmc->regs->norintstsen &= 0xFFF4;\n}\n\nstatic int _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)\n{\n\tu16 norintsts = sdmmc->regs->norintsts;\n\tu16 errintsts = sdmmc->regs->errintsts;\n\n\tDPRINTF(\"norintsts %08X; errintsts %08X\\n\", norintsts, errintsts);\n\n\tif (pout)\n\t\t*pout = norintsts;\n\n\t// Check for error interrupt.\n\tif (norintsts & TEGRA_MMC_NORINTSTS_ERR_INTERRUPT)\n\t{\n\t\tsdmmc->regs->errintsts = errintsts;\n\t\treturn SDMMC_MASKINT_ERROR;\n\t}\n\telse if (norintsts & mask)\n\t{\n\t\tsdmmc->regs->norintsts = norintsts & mask;\n\t\treturn SDMMC_MASKINT_MASKED;\n\t}\n\t\n\treturn SDMMC_MASKINT_NOERROR;\n}\n\nstatic int _sdmmc_wait_request(sdmmc_t *sdmmc)\n{\n\t_sdmmc_get_clkcon(sdmmc);\n\n\tu32 timeout = get_tmr_ms() + 2000;\n\twhile (1)\n\t{\n\t\tint res = _sdmmc_check_mask_interrupt(sdmmc, 0, TEGRA_MMC_NORINTSTS_CMD_COMPLETE);\n\t\tif (res == SDMMC_MASKINT_MASKED)\n\t\t\tbreak;\n\t\tif (res != SDMMC_MASKINT_NOERROR || get_tmr_ms() > timeout)\n\t\t{\n\t\t\t_sdmmc_reset(sdmmc);\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\treturn 1;\n}\n\nstatic int _sdmmc_stop_transmission_inner(sdmmc_t *sdmmc, u32 *rsp)\n{\n\tsdmmc_cmd_t cmd;\n\n\tif (!_sdmmc_wait_prnsts_type0(sdmmc, 0))\n\t\treturn 0;\n\n\t_sdmmc_enable_interrupts(sdmmc);\n\tcmd.cmd = MMC_STOP_TRANSMISSION;\n\tcmd.arg = 0;\n\tcmd.rsp_type = SDMMC_RSP_TYPE_1;\n\tcmd.check_busy = 1;\n\t_sdmmc_parse_cmdbuf(sdmmc, &cmd, false);\n\tint res = _sdmmc_wait_request(sdmmc);\n\t_sdmmc_mask_interrupts(sdmmc);\n\n\tif (!res)\n\t\treturn 0;\n\t\n\t_sdmmc_cache_rsp(sdmmc, rsp, 4, SDMMC_RSP_TYPE_1);\n\treturn _sdmmc_wait_prnsts_type1(sdmmc);\n}\n\nint sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp)\n{\n\tif (!sdmmc->sd_clock_enabled)\n\t\treturn 0;\n\n\tbool should_disable_sd_clock = false;\n\tif (!(sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE))\n\t{\n\t\tshould_disable_sd_clock = true;\n\t\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t\t_sdmmc_get_clkcon(sdmmc);\n\t\tusleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor);\n\t}\n\n\tint res = _sdmmc_stop_transmission_inner(sdmmc, rsp);\n\tusleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor);\n\tif (should_disable_sd_clock)\n\t\tsdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\n\treturn res;\n}\n\nstatic int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)\n{\n\tif (!req->blksize || !req->num_sectors)\n\t\treturn 0;\n\n\tu32 blkcnt = req->num_sectors;\n\tif (blkcnt >= 0xFFFF)\n\t\tblkcnt = 0xFFFF;\n\tu32 admaaddr = (u32)req->buf;\n\n\t// Check alignment.\n\tif (admaaddr << 29)\n\t\treturn 0;\n\n\tsdmmc->regs->admaaddr = admaaddr;\n\tsdmmc->regs->admaaddr_hi = 0;\n\n\tsdmmc->dma_addr_next = (admaaddr + 0x80000) & 0xFFF80000;\n\n\tsdmmc->regs->blksize = req->blksize | 0x7000;\n\tsdmmc->regs->blkcnt = blkcnt;\n\n\tif (blkcnt_out)\n\t\t*blkcnt_out = blkcnt;\n\n\tu32 trnmode = TEGRA_MMC_TRNMOD_DMA_ENABLE;\n\tif (req->is_multi_block)\n\t\ttrnmode = TEGRA_MMC_TRNMOD_MULTI_BLOCK_SELECT |\n\t\t\tTEGRA_MMC_TRNMOD_BLOCK_COUNT_ENABLE |\n\t\t\tTEGRA_MMC_TRNMOD_DMA_ENABLE;\n\tif (!req->is_write)\n\t\ttrnmode |= TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ;\n\tif (req->is_auto_cmd12)\n\t\ttrnmode = (trnmode & 0xFFF3) | TEGRA_MMC_TRNMOD_AUTO_CMD12;\n\tbpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY);\n\tsdmmc->regs->trnmod = trnmode;\n\n\treturn 1;\n}\n\nstatic int _sdmmc_update_dma(sdmmc_t *sdmmc)\n{\n\tu16 blkcnt = 0;\n\tdo\n\t{\n\t\tblkcnt = sdmmc->regs->blkcnt;\n\t\tu32 timeout = get_tmr_ms() + 1500;\n\t\tdo\n\t\t{\n\t\t\tint res = 0;\n\t\t\twhile (1)\n\t\t\t{\n\t\t\t\tu16 intr = 0;\n\t\t\t\tres = _sdmmc_check_mask_interrupt(sdmmc, &intr, \n\t\t\t\t\tTEGRA_MMC_NORINTSTS_XFER_COMPLETE | TEGRA_MMC_NORINTSTS_DMA_INTERRUPT);\n\t\t\t\tif (res < 0)\n\t\t\t\t\tbreak;\n\t\t\t\tif (intr & TEGRA_MMC_NORINTSTS_XFER_COMPLETE)\n\t\t\t\t{\n\t\t\t\t\tbpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY);\n\t\t\t\t\treturn 1; // Transfer complete.\n\t\t\t\t}\n\t\t\t\tif (intr & TEGRA_MMC_NORINTSTS_DMA_INTERRUPT)\n\t\t\t\t{\n\t\t\t\t\t// Update DMA.\n\t\t\t\t\tsdmmc->regs->admaaddr = sdmmc->dma_addr_next;\n\t\t\t\t\tsdmmc->regs->admaaddr_hi = 0;\n\t\t\t\t\tsdmmc->dma_addr_next += 0x80000;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (res != SDMMC_MASKINT_NOERROR)\n\t\t\t{\n\t\t\t\t_sdmmc_reset(sdmmc);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t} while (get_tmr_ms() < timeout);\n\t} while (sdmmc->regs->blkcnt != blkcnt);\n\n\t_sdmmc_reset(sdmmc);\n\treturn 0;\n}\n\nstatic int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out)\n{\n\tint has_req_or_check_busy = req || cmd->check_busy;\n\tif (!_sdmmc_wait_prnsts_type0(sdmmc, has_req_or_check_busy))\n\t\treturn 0;\n\n\tu32 blkcnt = 0;\n\tbool is_data_present = false;\n\tif (req)\n\t{\n\t\t_sdmmc_config_dma(sdmmc, &blkcnt, req);\n\t\t_sdmmc_enable_interrupts(sdmmc);\n\t\tis_data_present = true;\n\t}\n\telse\n\t{\n\t\t_sdmmc_enable_interrupts(sdmmc);\n\t\tis_data_present = false;\n\t}\n\n\t_sdmmc_parse_cmdbuf(sdmmc, cmd, is_data_present);\n\n\tint res = _sdmmc_wait_request(sdmmc);\n\tDPRINTF(\"rsp(%d): %08X, %08X, %08X, %08X\\n\", res, \n\t\tsdmmc->regs->rspreg0, sdmmc->regs->rspreg1, sdmmc->regs->rspreg2, sdmmc->regs->rspreg3);\n\tif (res)\n\t{\n\t\tif (cmd->rsp_type)\n\t\t{\n\t\t\tsdmmc->expected_rsp_type = cmd->rsp_type;\n\t\t\t_sdmmc_cache_rsp(sdmmc, sdmmc->rsp, 0x10, cmd->rsp_type);\n\t\t}\n\t\tif (req)\n\t\t\t_sdmmc_update_dma(sdmmc);\n\t}\n\n\t_sdmmc_mask_interrupts(sdmmc);\n\n\tif (res)\n\t{\n\t\tif (req)\n\t\t{\n\t\t\tif (blkcnt_out)\n\t\t\t\t*blkcnt_out = blkcnt;\n\t\t\tif (req->is_auto_cmd12)\n\t\t\t\tsdmmc->rsp3 = sdmmc->regs->rspreg3;\n\t\t}\n\n\t\tif (cmd->check_busy || req)\n\t\t\treturn _sdmmc_wait_prnsts_type1(sdmmc);\n\t}\n\n\treturn res;\n}\n\nstatic int _sdmmc_config_sdmmc1()\n{\n\t// Configure SD card detect.\n\tPINMUX_AUX(PINMUX_AUX_GPIO_PZ1) = PINMUX_INPUT_ENABLE | PINMUX_PULL_UP | 1; //GPIO control, pull up.\n\tAPB_MISC(APB_MISC_GP_VGPIO_GPIO_MUX_SEL) = 0;\n\tgpio_config(GPIO_PORT_Z, GPIO_PIN_1, GPIO_MODE_GPIO);\n\tgpio_output_enable(GPIO_PORT_Z, GPIO_PIN_1, GPIO_OUTPUT_DISABLE);\n\tusleep(100);\n\tif(!!gpio_read(GPIO_PORT_Z, GPIO_PIN_1))\n\t\treturn 0;\n\n\t/*\n\t* Pinmux config:\n\t*  DRV_TYPE = DRIVE_2X\n\t*  E_SCHMT = ENABLE (for 1.8V),  DISABLE (for 3.3V)\n\t*  E_INPUT = ENABLE\n\t*  TRISTATE = PASSTHROUGH\n\t*  APB_MISC_GP_SDMMCx_CLK_LPBK_CONTROL = SDMMCx_CLK_PAD_E_LPBK for CLK\n\t*/\n\n\t// Configure SDMMC1 pinmux.\n\tAPB_MISC(APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL) = 1;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_CLK)  = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_CMD)  = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_DAT3) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_DAT2) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;\n\n\t// Make sure the SDMMC1 controller is powered.\n\tPMC(APBDEV_PMC_NO_IOPOWER) &= ~(1 << 12);\n\t// Assume 3.3V SD card voltage.\n\tPMC(APBDEV_PMC_PWR_DET_VAL) |= (1 << 12);\n\n\t// Set enable SD card power.\n\tPINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN | 1; //GPIO control, pull down.\n\tgpio_config(GPIO_PORT_E, GPIO_PIN_4, GPIO_MODE_GPIO);\n\tgpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_HIGH);\n\tgpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_ENABLE);\n\n\tusleep(1000);\n\n\t// Enable SD card power.\n\tmax77620_regulator_set_voltage(REGULATOR_LDO2, 3300000);\n\tmax77620_regulator_enable(REGULATOR_LDO2, 1);\n\n\tusleep(1000);\n\n\t// For good measure.\n\tAPB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = 0x10000000;\n\n\tusleep(1000);\n\n\treturn 1;\n}\n\nint sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int no_sd)\n{\n\tif (id > SDMMC_4)\n\t\treturn 0;\n\n\tif (id == SDMMC_1)\n\t\tif (!_sdmmc_config_sdmmc1())\n\t\t\treturn 0;\n\n\tmemset(sdmmc, 0, sizeof(sdmmc_t));\n\n\tsdmmc->regs = (t210_sdmmc_t *)_sdmmc_bases[id];\n\tsdmmc->id = id;\n\tsdmmc->clock_stopped = 1;\n\n\tif (clock_sdmmc_is_not_reset_and_enabled(id))\n\t{\n\t\t_sdmmc_sd_clock_disable(sdmmc);\n\t\t_sdmmc_get_clkcon(sdmmc);\n\t}\n\n\tu32 clock;\n\tu16 divisor;\n\tclock_sdmmc_get_params(&clock, &divisor, type);\n\tclock_sdmmc_enable(id, clock);\n\n\tsdmmc->clock_stopped = 0;\n\n\t//TODO: make this skip-able.\n\tsdmmc->regs->iospare |= 0x80000;\n\tsdmmc->regs->veniotrimctl &= 0xFFFFFFFB;\n\tstatic const u32 trim_values[] = { 2, 8, 3, 8 };\n\tsdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xE0FFFFFF) | (trim_values[sdmmc->id] << 24);\n\tsdmmc->regs->sdmemcmppadctl = (sdmmc->regs->sdmemcmppadctl & 0xF) | 7;\n\tif (!_sdmmc_autocal_config_offset(sdmmc, power))\n\t\treturn 0;\n\t_sdmmc_autocal_execute(sdmmc, power);\n\tif (_sdmmc_enable_internal_clock(sdmmc))\n\t{\n\t\tsdmmc_set_bus_width(sdmmc, bus_width);\n\t\t_sdmmc_set_voltage(sdmmc, power);\n\t\tif (sdmmc_setup_clock(sdmmc, type))\n\t\t{\n\t\t\tsdmmc_sd_clock_ctrl(sdmmc, no_sd);\n\t\t\t_sdmmc_sd_clock_enable(sdmmc);\n\t\t\t_sdmmc_get_clkcon(sdmmc);\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t}\n\treturn 0;\n}\n\nvoid sdmmc_end(sdmmc_t *sdmmc)\n{\n\tif (!sdmmc->clock_stopped)\n\t{\n\t\t_sdmmc_sd_clock_disable(sdmmc);\n\t\t// Disable SDMMC power. \n\t\t_sdmmc_set_voltage(sdmmc, SDMMC_POWER_OFF);\n\n\t\t// Disable SD card power.\n\t\tif (sdmmc->id == SDMMC_1)\n\t\t{\n\t\t\tgpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);\n\t\t\tmax77620_regulator_enable(REGULATOR_LDO2, 0);\n\t\t\tmsleep(1); // To power cycle, min 1ms without power is needed.\n\t\t}\n\n\t\t_sdmmc_get_clkcon(sdmmc);\n\t\tclock_sdmmc_disable(sdmmc->id);\n\t\tsdmmc->clock_stopped = 1;\n\t}\n}\n\nvoid sdmmc_init_cmd(sdmmc_cmd_t *cmdbuf, u16 cmd, u32 arg, u32 rsp_type, u32 check_busy)\n{\n\tcmdbuf->cmd = cmd;\n\tcmdbuf->arg = arg;\n\tcmdbuf->rsp_type = rsp_type;\n\tcmdbuf->check_busy = check_busy;\n}\n\nint sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out)\n{\n\tif (!sdmmc->sd_clock_enabled)\n\t\treturn 0;\n\n\t// Recalibrate periodically for SDMMC1.\n\tif (sdmmc->id == SDMMC_1 && sdmmc->no_sd)\n\t\t_sdmmc_autocal_execute(sdmmc, sdmmc_get_voltage(sdmmc));\n\n\tint should_disable_sd_clock = 0;\n\tif (!(sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE))\n\t{\n\t\tshould_disable_sd_clock = 1;\n\t\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t\t_sdmmc_get_clkcon(sdmmc);\n\t\tusleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor);\n\t}\n\n\tint res = _sdmmc_execute_cmd_inner(sdmmc, cmd, req, blkcnt_out);\n\tusleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor);\n\tif (should_disable_sd_clock)\n\t\tsdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\n\treturn res;\n}\n\nint sdmmc_enable_low_voltage(sdmmc_t *sdmmc)\n{\n\tif(sdmmc->id != SDMMC_1)\n\t\treturn 0;\n\n\tif (!sdmmc_setup_clock(sdmmc, 8))\n\t\treturn 0;\n\n\t_sdmmc_get_clkcon(sdmmc);\n\n\t// Enable schmitt trigger for better duty cycle and low jitter clock.\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_CLK)  |= PINMUX_SCHMT;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_CMD)  |= PINMUX_SCHMT;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_DAT3) |= PINMUX_SCHMT;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_DAT2) |= PINMUX_SCHMT;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) |= PINMUX_SCHMT;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) |= PINMUX_SCHMT;\n\n\tmax77620_regulator_set_voltage(REGULATOR_LDO2, 1800000);\n\tPMC(APBDEV_PMC_PWR_DET_VAL) &= ~(1 << 12);\n\n\t_sdmmc_autocal_config_offset(sdmmc, SDMMC_POWER_1_8);\n\t_sdmmc_autocal_execute(sdmmc, SDMMC_POWER_1_8);\n\t_sdmmc_set_voltage(sdmmc, SDMMC_POWER_1_8);\n\t_sdmmc_get_clkcon(sdmmc);\n\tmsleep(5);\n\t\n\tif (sdmmc->regs->hostctl2 & SDHCI_CTRL_VDD_180)\n\t{\n\t\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t\t_sdmmc_get_clkcon(sdmmc);\n\t\tmsleep(1);\n\t\tif ((sdmmc->regs->prnsts & 0xF00000) == 0xF00000)\n\t\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "argon-first-stage/src/utils/btn.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"utils/btn.h\"\n#include \"soc/i2c.h\"\n#include \"soc/gpio.h\"\n#include \"soc/t210.h\"\n#include \"utils/util.h\"\n#include \"power/max77620.h\"\n\nu32 btn_read()\n{\n\tu32 res = 0;\n\tif (!gpio_read(GPIO_PORT_X, GPIO_PIN_7))\n\t\tres |= BTN_VOL_DOWN;\n\tif (!gpio_read(GPIO_PORT_X, GPIO_PIN_6))\n\t\tres |= BTN_VOL_UP;\n\tif (i2c_recv_byte(4, MAX77620_I2C_ADDR, 0x15) & 0x4)\n\t\tres |= BTN_POWER;\n\treturn res;\n}\n\nu32 btn_wait()\n{\n\tu32 res = 0, btn = btn_read();\n\tbool pwr = false;\n\n\t//Power button down, raise a filter.\n\tif (btn & BTN_POWER)\n\t{\n\t\tpwr = true;\n\t\tbtn &= ~BTN_POWER;\n\t}\n\n\tdo\n\t{\n\t\tres = btn_read();\n\t\t//Power button up, remove filter.\n\t\tif (!(res & BTN_POWER) && pwr)\n\t\t\tpwr = false;\n\t\telse if (pwr) //Power button still down.\n\t\t\tres &= ~BTN_POWER;\n\t} while (btn == res);\n\n\treturn res;\n}\n\nu32 btn_wait_timeout(u32 time_ms, u32 mask)\n{\n\tu32 timeout = get_tmr_ms() + time_ms;\n\tu32 res = btn_read() & mask;\n\n\tdo\n\t{\n\t\tif (!(res & mask))\n\t\t\tres = btn_read() & mask;\n\t} while (get_tmr_ms() < timeout);\n\n\treturn res;\n}\n"
  },
  {
    "path": "argon-first-stage/src/utils/dirlist.c",
    "content": "/*\n * Copyright (c) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"libs/fatfs/ff.h\"\n#include \"mem/heap.h\"\n#include \"utils/types.h\"\n\nchar *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles)\n{\n\tu8 max_entries = 61;\n\n\tint res = 0;\n\tu32 i = 0, j = 0, k = 0;\n\tDIR dir;\n\tstatic FILINFO fno;\n\t\n\tchar *dir_entries = (char *)calloc(max_entries, 256);\n\tchar *copy_entries = (char *)calloc(max_entries, 256);\n\tchar *temp = (char *)calloc(1, 256);\n\n\tif (!pattern && !f_opendir(&dir, directory))\n\t{\n\t\tfor (;;)\n\t\t{\n\t\t\tres = f_readdir(&dir, &fno);\n\t\t\tif (res || !fno.fname[0])\n\t\t\t\tbreak;\n\t\t\tif (!(fno.fattrib & AM_DIR) && (fno.fname[0] != '.') && (includeHiddenFiles || !(fno.fattrib & AM_HID)))\n\t\t\t{\n\t\t\t\tmemcpy(dir_entries + (k * 256), fno.fname, strlen(fno.fname) + 1);\n\t\t\t\tk++;\n\t\t\t\tif (k > (max_entries - 1))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tf_closedir(&dir);\n\t}\n\telse if (pattern && !f_findfirst(&dir, &fno, directory, pattern) && fno.fname[0])\n\t{\n\t\tdo\n\t\t{\n\t\t\tif (!(fno.fattrib & AM_DIR) && (fno.fname[0] != '.') && (includeHiddenFiles || !(fno.fattrib & AM_HID)))\n\t\t\t{\n\t\t\t\tmemcpy(dir_entries + (k * 256), fno.fname, strlen(fno.fname) + 1);\n\t\t\t\tk++;\n\t\t\t\tif (k > (max_entries - 1))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tres = f_findnext(&dir, &fno);\n\t\t} while (fno.fname[0] && !res);\n\t\tf_closedir(&dir);\n\t}\n\n\tif (!k)\n\t{\n\t\tfree(temp);\n\t\tfree(dir_entries);\n\t\tfree(copy_entries);\n\n\t\treturn NULL;\n\t}\n\n\t// make copy_entries lowercase version of dir_entries\n\tfor(i = 0; i < k; i++) \n\t{\n\t\tj = i * 256;\n\t\twhile(dir_entries[j]) \n\t\t{\n\t\t\tcopy_entries[j] = dir_entries[j];\n\n\t\t\tif(dir_entries[j] >= 'A' && dir_entries[j] <= 'Z')\n\t\t\t\tcopy_entries[j] += 32;\n\t\t\t\n\t\t\tj++;\n\t\t}\n\t\t\n\t\tcopy_entries[j] = '\\0';\n\t}\n\n\t// compare copy_entries but sort dir_entries\n\tfor (i = 0; i < k - 1 ; i++)\n\t{\n\t\tfor (j = i + 1; j < k; j++)\n\t\t{\n\t\t\tif (strcmp(&copy_entries[i * 256], &copy_entries[j * 256]) > 0) \n\t\t\t{\n\t\t\t\tmemcpy(temp, &dir_entries[i * 256], strlen(&dir_entries[i * 256]) + 1);\n\t\t\t\tmemcpy(&dir_entries[i * 256], &dir_entries[j * 256], strlen(&dir_entries[j * 256]) + 1);\n\t\t\t\tmemcpy(&dir_entries[j * 256], temp, strlen(temp) + 1);\n\t\t\t}\n\t\t}\n\t}\n\n\tfree(temp);\n\tfree(copy_entries);\n\n\treturn dir_entries;\n}\n"
  },
  {
    "path": "argon-first-stage/src/utils/fs_utils.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018 CTCaer\n * Copyright (C) 2018 Guillem96\n * \n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"utils/fs_utils.h\"\n\n#include \"mem/heap.h\"\n#include \"gfx/gfx.h\"\n#include <string.h>\n#include <stdarg.h>\n\nbool sd_mount()\n{\n\tif (g_sd_mounted)\n\t\treturn true;\n\n\tif (!sdmmc_storage_init_sd(&g_sd_storage, &g_sd_sdmmc, SDMMC_1, SDMMC_BUS_WIDTH_4, 11))\n\t{\n\t\tgfx_printf(\"Failed to init SD card.\\nMake sure that it is inserted.\\nOr that SD reader is properly seated!\");\n\t}\n\telse\n\t{\n\t\tint res = 0;\n\t\tres = f_mount(&g_sd_fs, \"\", 1);\n\t\tif (res == FR_OK)\n\t\t{\n\t\t\tg_sd_mounted = 1;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tgfx_printf(\"Failed to mount SD card (FatFS Error %d).\\nMake sure that a FAT partition exists..\", res);\n\t\t}\n\t}\n\n\treturn false;\n}\n\nvoid sd_unmount()\n{\n\tif (g_sd_mounted)\n\t{\n\t\tf_mount(NULL, \"\", 1);\n\t\tsdmmc_storage_end(&g_sd_storage);\n\t\tg_sd_mounted = false;\n\t}\n}\n\nvoid *sd_file_read(char *path)\n{\n\tFIL fp;\n\tif (f_open(&fp, path, FA_READ) != FR_OK)\n\t\treturn NULL;\n\n\tu32 size = f_size(&fp);\n\tvoid *buf = malloc(size);\n\n\tu8 *ptr = buf;\n\twhile (size > 0)\n\t{\n\t\tu32 rsize = MIN(size, 512 * 512);\n\t\tif (f_read(&fp, ptr, rsize, NULL) != FR_OK)\n\t\t{\n\t\t\tfree(buf);\n\t\t\treturn NULL;\n\t\t}\n\n\t\tptr += rsize;\n\t\tsize -= rsize;\n\t}\n\n\tf_close(&fp);\n\n\treturn buf;\n}\n\nint sd_save_to_file(void *buf, u32 size, const char *filename)\n{\n\tFIL fp;\n\tu32 res = 0;\n\tres = f_open(&fp, filename, FA_CREATE_ALWAYS | FA_WRITE);\n\tif (res)\n\t{\n        gfx_printf(\"%kError (%d) creating file\\n%s.\\n%k\\n\", 0xFFFFDD00, res, filename, 0xFFCCCCCC);\n\t\treturn 1;\n\t}\n\n\tf_sync(&fp);\n\tf_write(&fp, buf, size, NULL);\n\tf_close(&fp);\n\n\treturn 0;\n}\n\nbool sd_file_exists(const char* filename)\n{\n    FIL fp;\n\tu32 res = 0;\n\tres = f_open(&fp, filename, FA_READ);\n\tif (res == FR_OK)\n\t{\n        f_close(&fp);\n        return true;\n\t}\n\n    return false;\n}\n\nvoid flipVertically(unsigned char* pixels_buffer, const unsigned int width, const unsigned int height, const int bytes_per_pixel)\n{\n    const unsigned int rows = height / 2; // Iterate only half the buffer to get a full flip\n    const unsigned int row_stride = width * bytes_per_pixel;\n    unsigned char* temp_row = (unsigned char*)malloc(row_stride);\n\n    int source_offset, target_offset;\n\n    for (int rowIndex = 0; rowIndex < rows; rowIndex++)\n    {\n        source_offset = rowIndex * row_stride;\n        target_offset = (height - rowIndex - 1) * row_stride;\n\n        memcpy(temp_row, pixels_buffer + source_offset, row_stride);\n        memcpy(pixels_buffer + source_offset, pixels_buffer + target_offset, row_stride);\n        memcpy(pixels_buffer + target_offset, temp_row, row_stride);\n    }\n\n    free(temp_row);\n    temp_row = NULL;\n}\n\nchar **sout_buf;\n\nstatic void _s_putc(char c)\n{\n\t**sout_buf = c;\n\t*sout_buf += 1;\n}\n\nstatic void _s_puts(const char *s)\n{\n\tfor (; *s; s++)\n\t\t_s_putc(*s);\n}\n\nstatic void _s_putn(u32 v, int base, char fill, int fcnt)\n{\n\tchar buf[65];\n\tstatic const char digits[] = \"0123456789ABCDEFghijklmnopqrstuvwxyz\";\n\tchar *p;\n\tint c = fcnt;\n\n\tif (base > 36)\n\t\treturn;\n\n\tp = buf + 64;\n\t*p = 0;\n\tdo\n\t{\n\t\tc--;\n\t\t*--p = digits[v % base];\n\t\tv /= base;\n\t} while (v);\n\n\tif (fill != 0)\n\t{\n\t\twhile (c > 0)\n\t\t{\n\t\t\t*--p = fill;\n\t\t\tc--;\n\t\t}\n\t}\n\n\t_s_puts(p);\n}\n\nstatic void _s_putp(u32 *v, int base, char fill, int fcnt)\n{\n\t_s_putn(*v, base, fill, fcnt);\n}\n\nvoid s_printf(char *out_buf, const char *fmt, ...)\n{\n\tva_list ap;\n\tint fill, fcnt;\n\n\tsout_buf = &out_buf;\n\n\tva_start(ap, fmt);\n\twhile(*fmt)\n\t{\n\t\tif(*fmt == '%')\n\t\t{\n\t\t\tfmt++;\n\t\t\tfill = 0;\n\t\t\tfcnt = 0;\n\t\t\tif ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ')\n\t\t\t{\n\t\t\t\tfcnt = *fmt;\n\t\t\t\tfmt++;\n\t\t\t\tif (*fmt >= '0' && *fmt <= '9')\n\t\t\t\t{\n\t\t\t\t\tfill = fcnt;\n\t\t\t\t\tfcnt = *fmt - '0';\n\t\t\t\t\tfmt++;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfill = ' ';\n\t\t\t\t\tfcnt -= '0';\n\t\t\t\t}\n\t\t\t}\n\t\t\tswitch(*fmt)\n\t\t\t{\n\t\t\tcase 'c':\n\t\t\t\t_s_putc(va_arg(ap, u32));\n\t\t\t\tbreak;\n\t\t\tcase 's':\n\t\t\t\t_s_puts(va_arg(ap, char *));\n\t\t\t\tbreak;\n\t\t\tcase 'd':\n\t\t\t\t_s_putn(va_arg(ap, u32), 10, fill, fcnt);\n\t\t\t\tbreak;\n\t\t\tcase 'p':\n\t\t\tcase 'P':\n\t\t\t\t_s_putp(va_arg(ap, u32*), 16, fill, fcnt);\n\t\t\t\tbreak;\n\t\t\tcase 'x':\n\t\t\tcase 'X':\n\t\t\t\t_s_putn(va_arg(ap, u32), 16, fill, fcnt);\n\t\t\t\tbreak;\n\t\t\tcase 'k':\n\t\t\t\t//gfx_con.fgcol = va_arg(ap, u32);\n\t\t\t\tbreak;\n\t\t\tcase 'K':\n\t\t\t\t//gfx_con.bgcol = va_arg(ap, u32);\n\t\t\t\t//gfx_con.fillbg = 1;\n\t\t\t\tbreak;\n\t\t\tcase '%':\n\t\t\t\t_s_putc('%');\n\t\t\t\tbreak;\n\t\t\tcase '\\0':\n\t\t\t\tgoto out;\n\t\t\tdefault:\n\t\t\t\t_s_putc('%');\n\t\t\t\t_s_putc(*fmt);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\t_s_putc(*fmt);\n\t\tfmt++;\n\t}\n\nout:\n\t**sout_buf = '\\0';\n\tva_end(ap);\n}"
  },
  {
    "path": "argon-first-stage/src/utils/util.c",
    "content": "/*\n* Copyright (c) 2018 naehrwert\n* Copyright (C) 2018 CTCaer\n* Copyright (C) 2018 Guillem96\n*\n* This program is free software; you can redistribute it and/or modify it\n* under the terms and conditions of the GNU General Public License,\n* version 2, as published by the Free Software Foundation.\n*\n* This program is distributed in the hope it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include \"utils/util.h\"\n#include \"utils/btn.h\"\n#include \"utils/fs_utils.h\"\n\n#include \"soc/t210.h\"\n#include \"soc/bpmp.h\"\n#include \"soc/pmc.h\"\n#include \"soc/i2c.h\"\n\n#include \"power/max77620.h\"\n\n#include \"gfx/di.h\"\n#include \"gfx/gfx.h\"\n\n#include \"mem/heap.h\"\n\n#include <string.h>\n\n\nu32 get_tmr_s()\n{\n    return RTC(APBDEV_RTC_SECONDS);\n}\n\nu32 get_tmr_ms()\n{\n    // The registers must be read with the following order:\n    // -> RTC_MILLI_SECONDS (0x10) -> RTC_SHADOW_SECONDS (0xC)\n    return (RTC(APBDEV_RTC_MILLI_SECONDS) | (RTC(APBDEV_RTC_SHADOW_SECONDS) << 10));\n}\n\nu32 get_tmr_us()\n{\n    return TMR(TIMERUS_CNTR_1US); //TIMERUS_CNTR_1US\n}\n\nvoid msleep(u32 milliseconds)\n{\n    u32 start = RTC(APBDEV_RTC_MILLI_SECONDS) | (RTC(APBDEV_RTC_SHADOW_SECONDS) << 10);\n    while (((RTC(APBDEV_RTC_MILLI_SECONDS) | (RTC(APBDEV_RTC_SHADOW_SECONDS) << 10)) - start) <= milliseconds)\n        ;\n}\n\nvoid usleep(u32 microseconds)\n{\n    u32 start = TMR(TIMERUS_CNTR_1US);\n    // Casting to u32 is important!\n    while ((u32)(TMR(TIMERUS_CNTR_1US) - start) <= microseconds)\n        ;\n}\n\nvoid exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops)\n{\n    for(u32 i = 0; i < num_ops; i++)\n        base[ops[i].off] = ops[i].val;\n}\n\n#define CRC32C_POLY 0x82F63B78\nu32 crc32c(const void *buf, u32 len)\n{\n    const u8 *cbuf = (const u8 *)buf;\n    u32 crc = 0xFFFFFFFF;\n    while (len--)\n    {\n        crc ^= *cbuf++;\n        for (int i = 0; i < 8; i++)\n            crc = crc & 1 ? (crc >> 1) ^ CRC32C_POLY : crc >> 1;\n    }\n    return ~crc;\n}\n\nu32 memcmp32sparse(const u32 *buf1, const u32 *buf2, u32 len)\n{\n    u32 len32 = len / 4;\n\n    if (!(len32 % 32))\n    {\n        while (len32)\n        {\n            len32 -= 32;\n            if(buf1[len32] != buf2[len32])\n                return 1;\n        }\n    }\n    else\n    {\n        while (len32)\n        {\n            len32 -= 32;\n            if(buf1[len32] != buf2[len32])\n                return 1;\n            if (len32 < 32)\n                return 0;\n        }\n    }\n\n    return 0;\n}\n\n__attribute__((noreturn)) void wait_for_button_and_reboot(void) {\n    u32 button;\n    while (true) {\n        button = btn_read();\n        if (button & BTN_POWER) {\n            reboot_rcm();\n        }\n    }\n}\n\nvoid reboot_normal()\n{\n    bpmp_mmu_disable();\n\n    sd_unmount();\n\n    display_end();\n    panic(0x21); // Bypass fuse programming in package1.\n}\n\nvoid reboot_rcm()\n{\n    bpmp_mmu_disable();\n    sd_unmount();\n    display_end();\n\n    PMC(APBDEV_PMC_SCRATCH0) = 2; // Reboot into rcm.\n    PMC(APBDEV_PMC_CNTRL) |= PMC_CNTRL_MAIN_RST;\n    while (true)\n        usleep(1);\n}\n\nvoid power_off()\n{\n    bpmp_mmu_disable();\n    sd_unmount();\n    display_end();\n    //TODO: we should probably make sure all regulators are powered off properly.\n    i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF);\n}\n\n\nchar *str_replace(char *orig, char *rep, char *with) {\n    char *result; // the return string\n    char *ins;    // the next insert point\n    char *tmp;    // varies\n    int len_rep;  // length of rep (the string to remove)\n    int len_with; // length of with (the string to replace rep with)\n    int len_front; // distance between rep and end of last rep\n    int count;    // number of replacements\n\n    // sanity checks and initialization\n    if (!orig || !rep)\n        return NULL;\n    len_rep = strlen(rep);\n    if (len_rep == 0)\n        return NULL; // empty rep causes infinite loop during count\n    if (!with)\n        with = \"\";\n    len_with = strlen(with);\n\n    // count the number of replacements needed\n    ins = orig;\n    for (count = 0; (tmp = strstr(ins, rep)); ++count) {\n        ins = tmp + len_rep;\n    }\n\n    tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);\n\n    if (!result)\n        return NULL;\n\n    // first time through the loop, all the variable are set correctly\n    // from here on,\n    //    tmp points to the end of the result string\n    //    ins points to the next occurrence of rep in orig\n    //    orig points to the remainder of orig after \"end of rep\"\n    while (count--) {\n        ins = strstr(orig, rep);\n        len_front = ins - orig;\n        tmp = strncpy(tmp, orig, len_front) + len_front;\n        tmp = strcpy(tmp, with) + len_with;\n        orig += len_front + len_rep; // move to next \"end of rep\"\n    }\n    strcpy(tmp, orig);\n    return result;\n}\n\nvoid panic(u32 val)\n{\n    // Set panic code.\n    PMC(APBDEV_PMC_SCRATCH200) = val;\n    //PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_DISABLE;\n    TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN;\n    TMR(TIMER_TMR9_TMR_PTV) = TIMER_EN | TIMER_PER_EN;\n    TMR(TIMER_WDT4_CONFIG)  = TIMER_SRC(9) | TIMER_PER(1) | TIMER_PMCRESET_EN;\n    TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT;\n    while (1)\n        ;\n}"
  },
  {
    "path": "argon-nx-gui/Dockerfile",
    "content": "FROM devkitpro/devkitarm\nWORKDIR /argon-nx-gui\nCOPY . .\nENTRYPOINT [\"make\"]"
  },
  {
    "path": "argon-nx-gui/Makefile",
    "content": "ifeq ($(strip $(DEVKITARM)),)\n$(error \"Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM\")\nendif\n\ninclude $(DEVKITARM)/base_rules\n\nTARGET          := argon-nx-gui\nBUILD           := build\nOUTPUT          := ../output\nSOURCEDIR       := src\nSOURCES         := src \\\n\t\t\tsrc/ianos \\\n\t\t\tsrc/libs/fatfs src/libs/elfload src/libs/compr src/libs/lvgl \\\n\t\t\tsrc/libs/lvgl/lv_core src/libs/lvgl/lv_draw src/libs/lvgl/lv_font src/libs/lvgl/lv_hal \\\n\t\t\tsrc/libs/lvgl/lv_misc src/libs/lvgl/lv_objx src/libs/lvgl/lv_themes \\\n\t\t\tsrc/core \\\n\t\t\tsrc/gfx \\\n\t\t\tsrc/mem \\\n\t\t\tsrc/menu/gui \\\n\t\t\tsrc/minerva \\\n\t\t\tsrc/power \\\n\t\t\tsrc/sec \\\n\t\t\tsrc/soc \\\n\t\t\tsrc/storage \\\n\t\t\tsrc/utils\n\nINCLUDES        := include\nVPATH           = $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))\nVPATH \t\t+= $(dir $(wildcard ./$(SOURCEDIR)/*/*/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/*/*/))\nCFILES          := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))\nSFILES          := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))\n\nOFILES_SRC      := $(SFILES:.s=.o) $(CFILES:.c=.o)\nHFILES_BIN      := $(addsuffix .h,$(subst .,_,$(BINFILES)))\n\nOBJS            = $(addprefix $(BUILD)/$(TARGET)/, $(OFILES_SRC))\n\n\nINCLUDE         :=$(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \\\n\t\t  $(foreach dir,$(LIBDIRS),-I$(dir)/include) \\\n\t\t  -I$(BUILD)/$(TARGET)\n\nARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork\nCFLAGS = $(INCLUDE) $(ARCH) -O2 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 -Wall\nLDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections\n\n\n.PHONY: all clean\n\nall: directories $(TARGET).bin\n\t@echo $(HFILES_BIN)\n\t@echo -n \"Payload size is \"\n\t@wc -c < $(OUTPUT)/$(TARGET).bin\n\t@echo \"Max size is 126296 Bytes.\"\n\ndirectories:\n\t@mkdir -p \"$(BUILD)\"\n\t@mkdir -p \"$(BUILD)/$(TARGET)\"\n\t@mkdir -p \"$(OUTPUT)\"\n\t\nclean:\n\t@rm -rf $(OBJS)\n\t@rm -rf $(BUILD)\n\t@rm -rf $(OUTPUT)/$(TARGET).bin\n\n$(MODULEDIRS):\n\t$(MAKE) -C $@ $(MAKECMDGOALS)\n\n$(TARGET).bin: $(BUILD)/$(TARGET)/$(TARGET).elf $(MODULEDIRS)\n\t$(OBJCOPY) -S -O binary $< $(OUTPUT)/$@\n\n$(BUILD)/$(TARGET)/$(TARGET).elf: $(OBJS)\n\t$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@\n\n$(BUILD)/$(TARGET)/%.o: %.c\n\t$(CC) $(CFLAGS) -c $< -o $@\n\n$(BUILD)/$(TARGET)/%.o: %.s\n\t$(CC) $(CFLAGS) -c $< -o $@\n\n$(OFILES_SRC): $(HFILES_BIN)\n\nprint-%  : ; @echo $* = $($*)\n"
  },
  {
    "path": "argon-nx-gui/include/core/argon-ctxt.h",
    "content": "#ifndef _ARGON_CTXT_H_\n#define _ARGON_CTXT_H_\n\n#include \"minerva/minerva.h\"\n#include \"menu/gui/gui_menu_pool.h\"\n\ntypedef struct\n{\n    /* Screen settings */\n    u32* vdb;\n    bool is_display_init;\n\n    /* Keep a reference to all menu objects */\n    gui_menu_pool_t* pool;\n\n    /* Minerva configuration */\n    mtc_config_t* mtc_conf;\n} argon_ctxt_t;\n\nvoid argon_ctxt_init(argon_ctxt_t* argon_ctxt);\nvoid argon_ctxt_destroy(argon_ctxt_t* argon_ctxt);\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/core/argon-resources.h",
    "content": "#ifndef _ARGON_RESOURCES_H_\n#define _ARGON_RESOURCES_H_\n\n#define ARGON_RES_ADDR 0xEE000000\n\n// Montserrat 12 font\n#define MONTSERRAT_12_GLYPH_BMP 0x0\n#define MONTSERRAT_12_KERN_PAIR_GLYPH 0x9FE\n#define MONTSERRAT_12_KERN_PAIR_VALUE 0xFF6\n\n// Montserrat 40 font\n#define MONTSERRAT_40_GLYPH_BMP 0x12F2\n#define MONTSERRAT_40_KERN_PAIR_GLYPH 0xE587\n#define MONTSERRAT_40_KERN_PAIR_VALUE 0xEB7F\n\n// Montserrat Alternate 80 font\n#define MONTSERRAT_ALT_80_GLYPH_BMP 0xEE7B\n#define MONTSERRAT_ALT_80_KERN_PAIR_GLYPH 0x42822\n#define MONTSERRAT_ALT_80_KERN_PAIR_VALUE 0x429C6\n\n// Montserrat Alternate 20 font\n#define MONTSERRAT_ALT_20_GLYPH_BMP 0x42A98\n#define MONTSERRAT_ALT_20_KERN_PAIR_GLYPH 0x46213\n#define MONTSERRAT_ALT_20_KERN_PAIR_VALUE 0x463B7\n\n// Montserrat Alternate 30 font\n#define MONTSERRAT_ALT_30_GLYPH_BMP 0x46489\n#define MONTSERRAT_ALT_30_KERN_PAIR_GLYPH 0x4DE14\n#define MONTSERRAT_ALT_30_KERN_PAIR_VALUE 0x4DFB8\n\n// Montserrat Alternate 110 font\n#define MONTSERRAT_ALT_110_GLYPH_BMP 0x4E08A\n#define MONTSERRAT_ALT_110_KERN_LEFT_MAP 0x7B294\n#define MONTSERRAT_ALT_110_KERN_RIGHT_MAP 0x7B2F6\n#define MONTSERRAT_ALT_110_KERN_CLASS_VALUE 0x7B358\n\nvoid argon_resources_init();\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/core/custom-gui.h",
    "content": "/*\n * Copyright (c) 2018 Guillem96\n * \n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef _CUSTOM_GUI_H_\n#define _CUSTOM_GUI_H_\n\n#include \"utils/types.h\"\n#include \"libs/lvgl/lvgl.h\"\n\n#define CUSTOM_BG_PATH \"argon/background.bmp\"\n\ntypedef struct {\n    lv_img_dsc_t* custom_bg;\n} custom_gui_t;\n\n\ncustom_gui_t* custom_gui_load();\n\nvoid custom_gui_end(custom_gui_t*);\n\n/* Renders custom background, returns false if background.bmp does not exist */\nbool render_custom_background(custom_gui_t*, lv_obj_t* par);\n\nvoid take_screenshot();\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/core/launcher.h",
    "content": "/*\n * Copyright (c) 2018 Guillem96\n * \n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef _LAUNCHER_H_\n#define _LAUNCHER_H_\n\n#include \"argon-ctxt.h\"\n\nint launch_payload(argon_ctxt_t*, char*);\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/core/payloads.h",
    "content": "/*\n * Copyright (c) 2018 Guillem96\n * \n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef _PAYLOADS_H_\n#define _PAYLOADS_H_\n\n#include \"utils/types.h\"\n\n#define PAYLOADS_DIR \"argon/payloads\"\n#define PAYLOADS_LOGOS_DIR \"argon/logos\"\n\n/* Generate full pyload directory */\nvoid payload_full_path(const char*, char*);\n\n/* Get payload's logo from payload's name */\nvoid payload_logo_path(const char*, char*);\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/gfx/di.h",
    "content": "#ifndef _DI_H_\n#define _DI_H_\n\n#include \"utils/types.h\"\n\n#define FB_ADDRESS 0xF0800000\n\n/*! Display registers. */\n#define _DIREG(reg) ((reg) * 4)\n\n#define DC_CMD_GENERAL_INCR_SYNCPT 0x00\n\n#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01\n#define  SYNCPT_CNTRL_NO_STALL   (1 << 8)\n#define  SYNCPT_CNTRL_SOFT_RESET (1 << 0)\n\n#define DC_CMD_CONT_SYNCPT_VSYNC 0x28\n#define  SYNCPT_VSYNC_ENABLE (1 << 8)\n\n#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031\n\n#define DC_CMD_DISPLAY_COMMAND 0x32\n#define  DISP_CTRL_MODE_STOP       (0 << 5)\n#define  DISP_CTRL_MODE_C_DISPLAY  (1 << 5)\n#define  DISP_CTRL_MODE_NC_DISPLAY (2 << 5)\n#define  DISP_CTRL_MODE_MASK       (3 << 5)\n\n#define DC_CMD_DISPLAY_POWER_CONTROL 0x36\n#define  PW0_ENABLE (1 <<  0)\n#define  PW1_ENABLE (1 <<  2)\n#define  PW2_ENABLE (1 <<  4)\n#define  PW3_ENABLE (1 <<  6)\n#define  PW4_ENABLE (1 <<  8)\n#define  PM0_ENABLE (1 << 16)\n#define  PM1_ENABLE (1 << 18)\n\n#define DC_CMD_INT_MASK 0x38\n#define DC_CMD_INT_ENABLE 0x39\n\n#define DC_CMD_STATE_ACCESS 0x40\n#define  READ_MUX  (1 << 0)\n#define  WRITE_MUX (1 << 2)\n\n#define DC_CMD_STATE_CONTROL 0x41\n#define  GENERAL_ACT_REQ (1 <<  0)\n#define  WIN_A_ACT_REQ   (1 <<  1)\n#define  WIN_B_ACT_REQ   (1 <<  2)\n#define  WIN_C_ACT_REQ   (1 <<  3)\n#define  CURSOR_ACT_REQ  (1 <<  7)\n#define  GENERAL_UPDATE  (1 <<  8)\n#define  WIN_A_UPDATE    (1 <<  9)\n#define  WIN_B_UPDATE    (1 << 10)\n#define  WIN_C_UPDATE    (1 << 11)\n#define  CURSOR_UPDATE   (1 << 15)\n#define  NC_HOST_TRIG    (1 << 24)\n\n#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42\n#define  WINDOW_A_SELECT (1 << 4)\n#define  WINDOW_B_SELECT (1 << 5)\n#define  WINDOW_C_SELECT (1 << 6)\n\n#define DC_CMD_REG_ACT_CONTROL 0x043\n\n#define DC_COM_CRC_CONTROL 0x300\n#define DC_COM_PIN_OUTPUT_ENABLE(x) (0x302 + (x))\n#define DC_COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x))\n\n#define DC_COM_DSC_TOP_CTL 0x33E\n\n#define DC_DISP_DISP_WIN_OPTIONS 0x402\n#define  HDMI_ENABLE     (1 << 30)\n#define  DSI_ENABLE      (1 << 29)\n#define  SOR1_TIMING_CYA (1 << 27)\n#define  SOR1_ENABLE     (1 << 26)\n#define  SOR_ENABLE      (1 << 25)\n#define  CURSOR_ENABLE   (1 << 16)\n\n#define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403\n#define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404\n#define DC_DISP_DISP_TIMING_OPTIONS 0x405\n#define DC_DISP_REF_TO_SYNC 0x406\n#define DC_DISP_SYNC_WIDTH 0x407\n#define DC_DISP_BACK_PORCH 0x408\n#define DC_DISP_ACTIVE 0x409\n#define DC_DISP_FRONT_PORCH 0x40A\n\n#define DC_DISP_DISP_CLOCK_CONTROL 0x42E\n#define  PIXEL_CLK_DIVIDER_PCD1  (0 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD1H (1 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD2  (2 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD3  (3 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD4  (4 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD6  (5 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD8  (6 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD9  (7 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD12 (8 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD16 (9 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD18 (10 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD24 (11 << 8)\n#define  PIXEL_CLK_DIVIDER_PCD13 (12 << 8)\n#define  SHIFT_CLK_DIVIDER(x)    ((x) & 0xff)\n\n#define DC_DISP_DISP_INTERFACE_CONTROL 0x42F\n#define  DISP_DATA_FORMAT_DF1P1C    (0 << 0)\n#define  DISP_DATA_FORMAT_DF1P2C24B (1 << 0)\n#define  DISP_DATA_FORMAT_DF1P2C18B (2 << 0)\n#define  DISP_DATA_FORMAT_DF1P2C16B (3 << 0)\n#define  DISP_DATA_FORMAT_DF2S      (4 << 0)\n#define  DISP_DATA_FORMAT_DF3S      (5 << 0)\n#define  DISP_DATA_FORMAT_DFSPI     (6 << 0)\n#define  DISP_DATA_FORMAT_DF1P3C24B (7 << 0)\n#define  DISP_DATA_FORMAT_DF1P3C18B (8 << 0)\n#define  DISP_ALIGNMENT_MSB         (0 << 8)\n#define  DISP_ALIGNMENT_LSB         (1 << 8)\n#define  DISP_ORDER_RED_BLUE        (0 << 9)\n#define  DISP_ORDER_BLUE_RED        (1 << 9)\n\n#define DC_DISP_DISP_COLOR_CONTROL 0x430\n#define  DITHER_CONTROL_MASK    (3 << 8)\n#define  DITHER_CONTROL_DISABLE (0 << 8)\n#define  DITHER_CONTROL_ORDERED (2 << 8)\n#define  DITHER_CONTROL_ERRDIFF (3 << 8)\n#define  BASE_COLOR_SIZE_MASK   (0xf << 0)\n#define  BASE_COLOR_SIZE_666    (0 << 0)\n#define  BASE_COLOR_SIZE_111    (1 << 0)\n#define  BASE_COLOR_SIZE_222    (2 << 0)\n#define  BASE_COLOR_SIZE_333    (3 << 0)\n#define  BASE_COLOR_SIZE_444    (4 << 0)\n#define  BASE_COLOR_SIZE_555    (5 << 0)\n#define  BASE_COLOR_SIZE_565    (6 << 0)\n#define  BASE_COLOR_SIZE_332    (7 << 0)\n#define  BASE_COLOR_SIZE_888    (8 << 0)\n\n#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431\n#define  SC1_H_QUALIFIER_NONE\t(1 << 16)\n#define  SC0_H_QUALIFIER_NONE\t(1 <<  0)\n\n#define DC_DISP_DATA_ENABLE_OPTIONS 0x432\n#define  DE_SELECT_ACTIVE_BLANK  (0 << 0)\n#define  DE_SELECT_ACTIVE        (1 << 0)\n#define  DE_SELECT_ACTIVE_IS     (2 << 0)\n#define  DE_CONTROL_ONECLK       (0 << 2)\n#define  DE_CONTROL_NORMAL       (1 << 2)\n#define  DE_CONTROL_EARLY_EXT    (2 << 2)\n#define  DE_CONTROL_EARLY        (3 << 2)\n#define  DE_CONTROL_ACTIVE_BLANK (4 << 2)\n\n#define DC_DISP_DC_MCCIF_FIFOCTRL 0x480\n#define DC_DISP_SD_BL_PARAMETERS 0x4D7\n#define DC_DISP_SD_BL_CONTROL 0x4DC\n#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4\n\n#define DC_WIN_CSC_YOF 0x611\n#define DC_WIN_CSC_KYRGB 0x612\n#define DC_WIN_CSC_KUR 0x613\n#define DC_WIN_CSC_KVR 0x614\n#define DC_WIN_CSC_KUG 0x615\n#define DC_WIN_CSC_KVG 0x616\n#define DC_WIN_CSC_KUB 0x617\n#define DC_WIN_CSC_KVB 0x618\n#define DC_WIN_AD_WIN_OPTIONS 0xB80\n#define DC_WIN_BD_WIN_OPTIONS 0xD80\n#define DC_WIN_CD_WIN_OPTIONS 0xF80\n\n// The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER).\n#define DC_WIN_WIN_OPTIONS 0x700\n#define  H_DIRECTION  (1 <<  0)\n#define  V_DIRECTION  (1 <<  2)\n#define  SCAN_COLUMN  (1 <<  4)\n#define  COLOR_EXPAND (1 <<  6)\n#define  CSC_ENABLE   (1 << 18)\n#define  WIN_ENABLE   (1 << 30)\n\n#define DC_WIN_COLOR_DEPTH 0x703\n#define  WIN_COLOR_DEPTH_P1             0x0\n#define  WIN_COLOR_DEPTH_P2             0x1\n#define  WIN_COLOR_DEPTH_P4             0x2\n#define  WIN_COLOR_DEPTH_P8             0x3\n#define  WIN_COLOR_DEPTH_B4G4R4A4       0x4\n#define  WIN_COLOR_DEPTH_B5G5R5A        0x5\n#define  WIN_COLOR_DEPTH_B5G6R5         0x6\n#define  WIN_COLOR_DEPTH_AB5G5R5        0x7\n#define  WIN_COLOR_DEPTH_B8G8R8A8       0xC\n#define  WIN_COLOR_DEPTH_R8G8B8A8       0xD\n#define  WIN_COLOR_DEPTH_B6x2G6x2R6x2A8 0xE\n#define  WIN_COLOR_DEPTH_R6x2G6x2B6x2A8 0xF\n#define  WIN_COLOR_DEPTH_YCbCr422       0x10\n#define  WIN_COLOR_DEPTH_YUV422         0x11\n#define  WIN_COLOR_DEPTH_YCbCr420P      0x12\n#define  WIN_COLOR_DEPTH_YUV420P        0x13\n#define  WIN_COLOR_DEPTH_YCbCr422P      0x14\n#define  WIN_COLOR_DEPTH_YUV422P        0x15\n#define  WIN_COLOR_DEPTH_YCbCr422R      0x16\n#define  WIN_COLOR_DEPTH_YUV422R        0x17\n#define  WIN_COLOR_DEPTH_YCbCr422RA     0x18\n#define  WIN_COLOR_DEPTH_YUV422RA       0x19\n\n#define DC_WIN_BUFFER_CONTROL 0x702\n#define DC_WIN_POSITION 0x704\n\n#define DC_WIN_SIZE 0x705\n#define  H_SIZE(x) (((x) & 0x1fff) <<  0)\n#define  V_SIZE(x) (((x) & 0x1fff) << 16)\n\n#define DC_WIN_PRESCALED_SIZE 0x706\n#define  H_PRESCALED_SIZE(x) (((x) & 0x7fff) <<  0)\n#define  V_PRESCALED_SIZE(x) (((x) & 0x1fff) << 16)\n\n#define DC_WIN_H_INITIAL_DDA 0x707\n#define DC_WIN_V_INITIAL_DDA 0x708\n\n#define DC_WIN_DDA_INC 0x709\n#define  H_DDA_INC(x) (((x) & 0xffff) <<  0)\n#define  V_DDA_INC(x) (((x) & 0xffff) << 16)\n\n#define DC_WIN_LINE_STRIDE 0x70A\n#define  LINE_STRIDE(x)\t   (x)\n#define  UV_LINE_STRIDE(x) (((x) & 0xffff) << 16)\n#define DC_WIN_DV_CONTROL 0x70E\n\n// The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER).\n#define DC_WINBUF_START_ADDR 0x800\n#define DC_WINBUF_ADDR_H_OFFSET 0x806\n#define DC_WINBUF_ADDR_V_OFFSET 0x808\n#define DC_WINBUF_SURFACE_KIND 0x80B\n#define  PITCH\t(0 << 0)\n#define  TILED\t(1 << 0)\n#define  BLOCK\t(2 << 0)\n#define  BLOCK_HEIGHT(x) (((x) & 0x7) << 4)\n\n/*! Display serial interface registers. */\n#define _DSIREG(reg) ((reg) * 4)\n\n#define DSI_RD_DATA 0x9\n#define DSI_WR_DATA 0xA\n\n#define DSI_POWER_CONTROL 0xB\n#define  DSI_POWER_CONTROL_ENABLE 1\n\n#define DSI_INT_ENABLE 0xC\n#define DSI_INT_STATUS 0xD\n#define DSI_INT_MASK 0xE\n\n#define DSI_HOST_CONTROL 0xF\n#define  DSI_HOST_CONTROL_FIFO_RESET   (1 << 21)\n#define  DSI_HOST_CONTROL_CRC_RESET    (1 << 20)\n#define  DSI_HOST_CONTROL_TX_TRIG_SOL  (0 << 12)\n#define  DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12)\n#define  DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12)\n#define  DSI_HOST_CONTROL_RAW          (1 << 6)\n#define  DSI_HOST_CONTROL_HS           (1 << 5)\n#define  DSI_HOST_CONTROL_FIFO_SEL     (1 << 4)\n#define  DSI_HOST_CONTROL_IMM_BTA      (1 << 3)\n#define  DSI_HOST_CONTROL_PKT_BTA      (1 << 2)\n#define  DSI_HOST_CONTROL_CS           (1 << 1)\n#define  DSI_HOST_CONTROL_ECC          (1 << 0)\n\n#define DSI_CONTROL 0x10\n#define  DSI_CONTROL_HS_CLK_CTRL  (1 << 20)\n#define  DSI_CONTROL_CHANNEL(c)   (((c) & 0x3) << 16)\n#define  DSI_CONTROL_FORMAT(f)    (((f) & 0x3) << 12)\n#define  DSI_CONTROL_TX_TRIG(x)   (((x) & 0x3) <<  8)\n#define  DSI_CONTROL_LANES(n)     (((n) & 0x3) <<  4)\n#define  DSI_CONTROL_DCS_ENABLE   (1 << 3)\n#define  DSI_CONTROL_SOURCE(s)    (((s) & 0x1) <<  2)\n#define  DSI_CONTROL_VIDEO_ENABLE (1 << 1)\n#define  DSI_CONTROL_HOST_ENABLE  (1 << 0)\n\n#define DSI_SOL_DELAY 0x11\n#define DSI_MAX_THRESHOLD 0x12\n\n#define DSI_TRIGGER 0x13\n#define  DSI_TRIGGER_HOST  (1 << 1)\n#define  DSI_TRIGGER_VIDEO (1 << 0)\n\n#define DSI_TX_CRC 0x14\n#define DSI_STATUS 0x15\n#define DSI_INIT_SEQ_CONTROL 0x1A\n#define DSI_INIT_SEQ_DATA_0 0x1B\n#define DSI_INIT_SEQ_DATA_1 0x1C\n#define DSI_INIT_SEQ_DATA_2 0x1D\n#define DSI_INIT_SEQ_DATA_3 0x1E\n#define DSI_PKT_SEQ_0_LO 0x23\n#define DSI_PKT_SEQ_0_HI 0x24\n#define DSI_PKT_SEQ_1_LO 0x25\n#define DSI_PKT_SEQ_1_HI 0x26\n#define DSI_PKT_SEQ_2_LO 0x27\n#define DSI_PKT_SEQ_2_HI 0x28\n#define DSI_PKT_SEQ_3_LO 0x29\n#define DSI_PKT_SEQ_3_HI 0x2A\n#define DSI_PKT_SEQ_4_LO 0x2B\n#define DSI_PKT_SEQ_4_HI 0x2C\n#define DSI_PKT_SEQ_5_LO 0x2D\n#define DSI_PKT_SEQ_5_HI 0x2E\n#define DSI_DCS_CMDS 0x33\n#define DSI_PKT_LEN_0_1 0x34\n#define DSI_PKT_LEN_2_3 0x35\n#define DSI_PKT_LEN_4_5 0x36\n#define DSI_PKT_LEN_6_7 0x37\n#define DSI_PHY_TIMING_0 0x3C\n#define DSI_PHY_TIMING_1 0x3D\n#define DSI_PHY_TIMING_2 0x3E\n#define DSI_BTA_TIMING 0x3F\n\n#define DSI_TIMEOUT_0 0x44\n#define  DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)\n#define  DSI_TIMEOUT_HTX(x) (((x) & 0xffff) <<  0)\n\n#define DSI_TIMEOUT_1 0x45\n#define  DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)\n#define  DSI_TIMEOUT_TA(x) (((x) & 0xffff) <<  0)\n\n#define DSI_TO_TALLY 0x46\n\n#define DSI_PAD_CONTROL_0 0x4B\n#define  DSI_PAD_CONTROL_VS1_PULLDN_CLK (1 << 24)\n#define  DSI_PAD_CONTROL_VS1_PULLDN(x)  (((x) & 0xf) << 16)\n#define  DSI_PAD_CONTROL_VS1_PDIO_CLK   (1 <<  8)\n#define  DSI_PAD_CONTROL_VS1_PDIO(x)    (((x) & 0xf) <<  0)\n\n#define DSI_PAD_CONTROL_CD 0x4C\n#define DSI_VIDEO_MODE_CONTROL 0x4E\n\n#define DSI_PAD_CONTROL_1 0x4F\n#define DSI_PAD_CONTROL_2 0x50\n\n#define DSI_PAD_CONTROL_3 0x51\n#define  DSI_PAD_PREEMP_PD_CLK(x) (((x) & 0x3) << 12)\n#define  DSI_PAD_PREEMP_PU_CLK(x) (((x) & 0x3) << 8)\n#define  DSI_PAD_PREEMP_PD(x)     (((x) & 0x3) << 4)\n#define  DSI_PAD_PREEMP_PU(x)     (((x) & 0x3) << 0)\n\n#define DSI_PAD_CONTROL_4 0x52\n#define DSI_INIT_SEQ_DATA_15 0x5F\n\n#define MIPI_CAL_MIPI_BIAS_PAD_CFG2 0x60\n\nvoid display_init();\nvoid display_backlight_pwm_init();\nvoid display_end();\n\n/*! Show one single color on the display. */\nvoid display_color_screen(u32 color);\n\n/*! Switches screen backlight ON/OFF. */\nvoid display_backlight(bool enable);\nvoid display_backlight_brightness(u32 brightness, u32 step_delay);\n\n/*! Init display in full 1280x720 resolution (B8G8R8A8, line stride 768, framebuffer size = 1280*768*4 bytes). */\nu32 *display_init_framebuffer();\nu32 *display_init_framebuffer2();\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/gfx/di.inl",
    "content": "/*\n* Copyright (c) 2018 naehrwert\n* Copyright (C) 2018 CTCaer\n*\n* This program is free software; you can redistribute it and/or modify it\n* under the terms and conditions of the GNU General Public License,\n* version 2, as published by the Free Software Foundation.\n*\n* This program is distributed in the hope it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n//Clock config.\nstatic const cfg_op_t _display_config_1[4] = {\n\t{0x4E, 0x40000000}, //CLK_RST_CONTROLLER_CLK_SOURCE_DISP1\n\t{0x34, 0x4830A001}, //CLK_RST_CONTROLLER_PLLD_BASE\n\t{0x36, 0x20},       //CLK_RST_CONTROLLER_PLLD_MISC1\n\t{0x37, 0x2D0AAA}    //CLK_RST_CONTROLLER_PLLD_MISC\n};\n\n//Display A config.\nstatic const cfg_op_t _display_config_2[94] = {\n\t{DC_CMD_STATE_ACCESS, 0},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n\t{DC_CMD_REG_ACT_CONTROL, 0x54},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_DISP_DC_MCCIF_FIFOCTRL, 0},\n\t{DC_DISP_DISP_MEM_HIGH_PRIORITY, 0},\n\t{DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER, 0},\n\t{DC_CMD_DISPLAY_POWER_CONTROL, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE},\n\t{DC_CMD_GENERAL_INCR_SYNCPT_CNTRL, SYNCPT_CNTRL_NO_STALL},\n\t{DC_CMD_CONT_SYNCPT_VSYNC, SYNCPT_VSYNC_ENABLE | 0x9}, // 9: SYNCPT\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},\n\t{DC_CMD_STATE_ACCESS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_DV_CONTROL, 0},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t/* Setup default YUV colorspace conversion coefficients */\n\t{DC_WIN_CSC_YOF,   0xF0},\n\t{DC_WIN_CSC_KYRGB, 0x12A},\n\t{DC_WIN_CSC_KUR,   0},\n\t{DC_WIN_CSC_KVR,   0x198},\n\t{DC_WIN_CSC_KUG,   0x39B},\n\t{DC_WIN_CSC_KVG,   0x32F},\n\t{DC_WIN_CSC_KUB,   0x204},\n\t{DC_WIN_CSC_KVB,   0},\n\t/* End of color coefficients */\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_DV_CONTROL, 0},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t/* Setup default YUV colorspace conversion coefficients */\n\t{DC_WIN_CSC_YOF,   0xF0},\n\t{DC_WIN_CSC_KYRGB, 0x12A},\n\t{DC_WIN_CSC_KUR,   0},\n\t{DC_WIN_CSC_KVR,   0x198},\n\t{DC_WIN_CSC_KUG,   0x39B},\n\t{DC_WIN_CSC_KVG,   0x32F},\n\t{DC_WIN_CSC_KUB,   0x204},\n\t{DC_WIN_CSC_KVB,   0},\n\t/* End of color coefficients */\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_DV_CONTROL, 0},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t/* Setup default YUV colorspace conversion coefficients */\n\t{DC_WIN_CSC_YOF,   0xF0},\n\t{DC_WIN_CSC_KYRGB, 0x12A},\n\t{DC_WIN_CSC_KUR,   0},\n\t{DC_WIN_CSC_KVR,   0x198},\n\t{DC_WIN_CSC_KUG,   0x39B},\n\t{DC_WIN_CSC_KVG,   0x32F},\n\t{DC_WIN_CSC_KUB,   0x204},\n\t{DC_WIN_CSC_KVB,   0},\n\t/* End of color coefficients */\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},\n\t{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},\n\t{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},\n\t{DC_COM_PIN_OUTPUT_POLARITY(3), 0},\n\t{0x4E4, 0},\n\t{DC_COM_CRC_CONTROL, 0},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{0x716, 0x10000FF},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{0x716, 0x10000FF},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{0x716, 0x10000FF},\n\t{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ}\n};\n\n//DSI Init config.\nstatic const cfg_op_t _display_config_3[61] = { \n\t{DSI_WR_DATA, 0},\n\t{DSI_INT_ENABLE, 0},\n\t{DSI_INT_STATUS, 0},\n\t{DSI_INT_MASK, 0},\n\t{DSI_INIT_SEQ_DATA_0, 0},\n\t{DSI_INIT_SEQ_DATA_1, 0},\n\t{DSI_INIT_SEQ_DATA_2, 0},\n\t{DSI_INIT_SEQ_DATA_3, 0},\n\t{DSI_INIT_SEQ_DATA_15, 0},\n\t{DSI_DCS_CMDS, 0},\n\t{DSI_PKT_SEQ_0_LO, 0},\n\t{DSI_PKT_SEQ_1_LO, 0},\n\t{DSI_PKT_SEQ_2_LO, 0},\n\t{DSI_PKT_SEQ_3_LO, 0},\n\t{DSI_PKT_SEQ_4_LO, 0},\n\t{DSI_PKT_SEQ_5_LO, 0},\n\t{DSI_PKT_SEQ_0_HI, 0},\n\t{DSI_PKT_SEQ_1_HI, 0},\n\t{DSI_PKT_SEQ_2_HI, 0},\n\t{DSI_PKT_SEQ_3_HI, 0},\n\t{DSI_PKT_SEQ_4_HI, 0},\n\t{DSI_PKT_SEQ_5_HI, 0},\n\t{DSI_CONTROL, 0},\n\t{DSI_PAD_CONTROL_CD, 0},\n\t{DSI_SOL_DELAY, 0x18},\n\t{DSI_MAX_THRESHOLD, 0x1E0},\n\t{DSI_TRIGGER, 0},\n\t{DSI_INIT_SEQ_CONTROL, 0},\n\t{DSI_PKT_LEN_0_1, 0},\n\t{DSI_PKT_LEN_2_3, 0},\n\t{DSI_PKT_LEN_4_5, 0},\n\t{DSI_PKT_LEN_6_7, 0},\n\t{DSI_PAD_CONTROL_1, 0},\n\t{DSI_PHY_TIMING_0, 0x6070601},\n\t{DSI_PHY_TIMING_1, 0x40A0E05},\n\t{DSI_PHY_TIMING_2, 0x30109},\n\t{DSI_BTA_TIMING, 0x190A14},\n\t{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},\n\t{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},\n\t{DSI_TO_TALLY, 0},\n\t{DSI_PAD_CONTROL_0, DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0)}, // Enable\n\t{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},\n\t{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},\n\t{DSI_POWER_CONTROL, 0},\n\t{DSI_POWER_CONTROL, 0},\n\t{DSI_PAD_CONTROL_1, 0},\n\t{DSI_PHY_TIMING_0, 0x6070601},\n\t{DSI_PHY_TIMING_1, 0x40A0E05},\n\t{DSI_PHY_TIMING_2, 0x30118},\n\t{DSI_BTA_TIMING, 0x190A14},\n\t{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},\n\t{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},\n\t{DSI_TO_TALLY, 0},\n\t{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},\n\t{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},\n\t{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},\n\t{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},\n\t{DSI_MAX_THRESHOLD, 0x40},\n\t{DSI_TRIGGER, 0},\n\t{DSI_TX_CRC, 0},\n\t{DSI_INIT_SEQ_CONTROL, 0}\n};\n\n//DSI config (if ver == 0x10).\nstatic const cfg_op_t _display_config_4[43] = {\n\t{DSI_WR_DATA, 0x439},\n\t{DSI_WR_DATA, 0x9483FFB9},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0xBD15},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0x1939},\n\t{DSI_WR_DATA, 0xAAAAAAD8},\n\t{DSI_WR_DATA, 0xAAAAAAEB},\n\t{DSI_WR_DATA, 0xAAEBAAAA},\n\t{DSI_WR_DATA, 0xAAAAAAAA},\n\t{DSI_WR_DATA, 0xAAAAAAEB},\n\t{DSI_WR_DATA, 0xAAEBAAAA},\n\t{DSI_WR_DATA, 0xAA},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0x1BD15},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0x2739},\n\t{DSI_WR_DATA, 0xFFFFFFD8},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFF},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0x2BD15},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0xF39},\n\t{DSI_WR_DATA, 0xFFFFFFD8},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFFFF},\n\t{DSI_WR_DATA, 0xFFFFFF},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0xBD15},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0x6D915},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0x439},\n\t{DSI_WR_DATA, 0xB9},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST}\n};\n\n//DSI config.\nstatic const cfg_op_t _display_config_5[21] = {\n\t{DSI_PAD_CONTROL_1, 0},\n\t{DSI_PHY_TIMING_0, 0x6070601},\n\t{DSI_PHY_TIMING_1, 0x40A0E05},\n\t{DSI_PHY_TIMING_2, 0x30172},\n\t{DSI_BTA_TIMING, 0x190A14},\n\t{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xA40)},\n\t{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},\n\t{DSI_TO_TALLY, 0},\n\t{DSI_PKT_SEQ_0_LO, 0x40000208},\n\t{DSI_PKT_SEQ_2_LO, 0x40000308},\n\t{DSI_PKT_SEQ_4_LO, 0x40000308},\n\t{DSI_PKT_SEQ_1_LO, 0x40000308},\n\t{DSI_PKT_SEQ_3_LO, 0x3F3B2B08},\n\t{DSI_PKT_SEQ_3_HI, 0x2CC},\n\t{DSI_PKT_SEQ_5_LO, 0x3F3B2B08},\n\t{DSI_PKT_SEQ_5_HI, 0x2CC},\n\t{DSI_PKT_LEN_0_1, 0xCE0000},\n\t{DSI_PKT_LEN_2_3, 0x87001A2},\n\t{DSI_PKT_LEN_4_5, 0x190},\n\t{DSI_PKT_LEN_6_7, 0x190},\n\t{DSI_HOST_CONTROL, 0},\n};\n\n//Clock config.\nstatic const cfg_op_t _display_config_6[3] = {\n\t{0x34, 0x4810C001}, //CLK_RST_CONTROLLER_PLLD_BASE\n\t{0x36, 0x20},       //CLK_RST_CONTROLLER_PLLD_MISC1\n\t{0x37, 0x2DFC00}    //CLK_RST_CONTROLLER_PLLD_MISC\n};\n\n//DSI config.\nstatic const cfg_op_t _display_config_7[10] = {\n\t{DSI_TRIGGER, 0},\n\t{DSI_CONTROL, 0},\n\t{DSI_SOL_DELAY, 6},\n\t{DSI_MAX_THRESHOLD, 0x1E0},\n\t{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},\n\t{DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},\n\t{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_FIFO_SEL| DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},\n\t{DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},\n\t{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},\n\t{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}\n};\n\n//MIPI CAL config.\nstatic const cfg_op_t _display_config_8[6] = {\n\t{0x18, 0},          // MIPI_CAL_MIPI_BIAS_PAD_CFG2\n\t{0x02, 0xF3F10000}, // MIPI_CAL_CIL_MIPI_CAL_STATUS\n\t{0x16, 0},          // MIPI_CAL_MIPI_BIAS_PAD_CFG0\n\t{0x18, 0},          // MIPI_CAL_MIPI_BIAS_PAD_CFG2\n\t{0x18, 0x10010},    // MIPI_CAL_MIPI_BIAS_PAD_CFG2\n\t{0x17, 0x300}       // MIPI_CAL_MIPI_BIAS_PAD_CFG1\n};\n\n//DSI config.\nstatic const cfg_op_t _display_config_9[4] = {\n\t{DSI_PAD_CONTROL_1, 0},\n\t{DSI_PAD_CONTROL_2, 0},\n\t{DSI_PAD_CONTROL_3, DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3)},\n\t{DSI_PAD_CONTROL_4, 0}\n};\n\n//MIPI CAL config.\nstatic const cfg_op_t _display_config_10[16] = {\n\t{0x0E, 0x200200}, // MIPI_CAL_DSIA_MIPI_CAL_CONFIG\n\t{0x0F, 0x200200}, // MIPI_CAL_DSIB_MIPI_CAL_CONFIG\n\t{0x19, 0x200002}, // MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2\n\t{0x1A, 0x200002}, // MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2\n\t{0x05, 0},        // MIPI_CAL_CILA_MIPI_CAL_CONFIG\n\t{0x06, 0},        // MIPI_CAL_CILB_MIPI_CAL_CONFIG\n\t{0x07, 0},        // MIPI_CAL_CILC_MIPI_CAL_CONFIG\n\t{0x08, 0},        // MIPI_CAL_CILD_MIPI_CAL_CONFIG\n\t{0x09, 0},        // MIPI_CAL_CILE_MIPI_CAL_CONFIG\n\t{0x0A, 0},        // MIPI_CAL_CILF_MIPI_CAL_CONFIG\n\t{0x10, 0},        // MIPI_CAL_DSIC_MIPI_CAL_CONFIG\n\t{0x11, 0},        // MIPI_CAL_DSID_MIPI_CAL_CONFIG\n\t{0x1A, 0},        // MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2\n\t{0x1C, 0},        // MIPI_CAL_DSIC_MIPI_CAL_CONFIG_2\n\t{0x1D, 0},        // MIPI_CAL_DSID_MIPI_CAL_CONFIG_2\n\t{0, 0x2A000001}   // MIPI_CAL_DSIA_MIPI_CAL_CONFIG\n};\n\n//Display A config.\nstatic const cfg_op_t _display_config_11[113] = {\n\t{DC_CMD_STATE_ACCESS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_DV_CONTROL, 0},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t/* Setup default YUV colorspace conversion coefficients */\n\t{DC_WIN_CSC_YOF,   0xF0},\n\t{DC_WIN_CSC_KYRGB, 0x12A},\n\t{DC_WIN_CSC_KUR,   0},\n\t{DC_WIN_CSC_KVR,   0x198},\n\t{DC_WIN_CSC_KUG,   0x39B},\n\t{DC_WIN_CSC_KVG,   0x32F},\n\t{DC_WIN_CSC_KUB,   0x204},\n\t{DC_WIN_CSC_KVB,   0},\n\t/* End of color coefficients */\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_DV_CONTROL, 0},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t/* Setup default YUV colorspace conversion coefficients */\n\t{DC_WIN_CSC_YOF,   0xF0},\n\t{DC_WIN_CSC_KYRGB, 0x12A},\n\t{DC_WIN_CSC_KUR,   0},\n\t{DC_WIN_CSC_KVR,   0x198},\n\t{DC_WIN_CSC_KUG,   0x39B},\n\t{DC_WIN_CSC_KVG,   0x32F},\n\t{DC_WIN_CSC_KUB,   0x204},\n\t{DC_WIN_CSC_KVB,   0},\n\t/* End of color coefficients */\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_DV_CONTROL, 0},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t/* Setup default YUV colorspace conversion coefficients */\n\t{DC_WIN_CSC_YOF,   0xF0},\n\t{DC_WIN_CSC_KYRGB, 0x12A},\n\t{DC_WIN_CSC_KUR,   0},\n\t{DC_WIN_CSC_KVR,   0x198},\n\t{DC_WIN_CSC_KUG,   0x39B},\n\t{DC_WIN_CSC_KVG,   0x32F},\n\t{DC_WIN_CSC_KUB,   0x204},\n\t{DC_WIN_CSC_KVB,   0},\n\t/* End of color coefficients */\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},\n\t{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},\n\t{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},\n\t{DC_COM_PIN_OUTPUT_POLARITY(3), 0},\n\t{0x4E4, 0},\n\t{DC_COM_CRC_CONTROL, 0},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{0x716, 0x10000FF},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{0x716, 0x10000FF},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{0x716, 0x10000FF},\n\t{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},\n\t{DC_CMD_STATE_ACCESS, 0},\n\t/* Set Display timings */\n\t{DC_DISP_DISP_TIMING_OPTIONS, 0},\n\t{DC_DISP_REF_TO_SYNC, (1 << 16)}, // h_ref_to_sync = 0, v_ref_to_sync = 1.\n\t{DC_DISP_SYNC_WIDTH,  0x10048},\n\t{DC_DISP_BACK_PORCH,  0x90048},\n\t{DC_DISP_ACTIVE,      0x50002D0},\n\t{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd.\n\t/* End of Display timings */\n\t{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},\n\t{DC_COM_PIN_OUTPUT_ENABLE(1), 0},\n\t{DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},\n\t{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},\n\t{DC_DISP_DISP_CLOCK_CONTROL, 0},\n\t{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n\t{DC_CMD_STATE_ACCESS, READ_MUX | WRITE_MUX},\n\t{DC_DISP_FRONT_PORCH, 0xA0088},\n\t{DC_CMD_STATE_ACCESS, 0},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n\t{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},\n\t{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n\t{DC_CMD_STATE_ACCESS, 0},\n\t{DC_DISP_DISP_CLOCK_CONTROL, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4)},\n\t{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},\n\t{DC_CMD_DISPLAY_COMMAND_OPTION0, 0}\n};\n\n////Display A config.\nstatic const cfg_op_t _display_config_12[17] = {\n\t{DC_DISP_FRONT_PORCH, 0xA0088},\n\t{DC_CMD_INT_MASK, 0},\n\t{DC_CMD_STATE_ACCESS, 0},\n\t{DC_CMD_INT_ENABLE, 0},\n\t{DC_CMD_CONT_SYNCPT_VSYNC, 0},\n\t{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n\t{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},\n\t{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n\t{DC_CMD_DISPLAY_POWER_CONTROL, 0},\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},\n};\n\n//DSI config.\nstatic const cfg_op_t _display_config_13[16] = {\n\t{DSI_POWER_CONTROL, 0},\n\t{DSI_PAD_CONTROL_1, 0},\n\t{DSI_PHY_TIMING_0, 0x6070601},\n\t{DSI_PHY_TIMING_1, 0x40A0E05},\n\t{DSI_PHY_TIMING_2, 0x30118},\n\t{DSI_BTA_TIMING, 0x190A14},\n\t{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF) },\n\t{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},\n\t{DSI_TO_TALLY, 0},\n\t{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},\n\t{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},\n\t{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},\n\t{DSI_MAX_THRESHOLD, 0x40},\n\t{DSI_TRIGGER, 0},\n\t{DSI_TX_CRC, 0},\n\t{DSI_INIT_SEQ_CONTROL, 0}\n};\n\n//DSI config (if ver == 0x10).\nstatic const cfg_op_t _display_config_14[22] = {\n\t{DSI_WR_DATA, 0x439},\n\t{DSI_WR_DATA, 0x9483FFB9},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0x2139},\n\t{DSI_WR_DATA, 0x191919D5},\n\t{DSI_WR_DATA, 0x19191919},\n\t{DSI_WR_DATA, 0x19191919},\n\t{DSI_WR_DATA, 0x19191919},\n\t{DSI_WR_DATA, 0x19191919},\n\t{DSI_WR_DATA, 0x19191919},\n\t{DSI_WR_DATA, 0x19191919},\n\t{DSI_WR_DATA, 0x19191919},\n\t{DSI_WR_DATA, 0x19},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0xB39},\n\t{DSI_WR_DATA, 0x4F0F41B1},\n\t{DSI_WR_DATA, 0xF179A433},\n\t{DSI_WR_DATA, 0x2D81},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST},\n\t{DSI_WR_DATA, 0x439},\n\t{DSI_WR_DATA, 0xB9},\n\t{DSI_TRIGGER, DSI_TRIGGER_HOST}\n};\n\n//Display A config.\nstatic const cfg_op_t cfg_display_one_color[8] = {\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, //Enable window A.\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, //Enable window B.\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, //Enable window C.\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE\n\t{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY} //DISPLAY_CTRL_MODE: continuous display.\n};\n\n//Display A config.\nstatic const cfg_op_t cfg_display_framebuffer[32] = {\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, //Enable window C.\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, //Enable window B.\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, //Enable window A.\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE\n\t{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, //T_A8R8G8B8 //NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_WIN_POSITION, 0}, //(0,0)\n\t{DC_WIN_H_INITIAL_DDA, 0},\n\t{DC_WIN_V_INITIAL_DDA, 0},\n\t{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(2880)}, //Pre-scaled size: 1280x2880 bytes.\n\t{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)},\n\t{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)}, //Window size: 1280 vertical lines x 720 horizontal pixels.\n\t{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.\n\t{DC_WIN_BUFFER_CONTROL, 0},\n\t{DC_WINBUF_SURFACE_KIND, 0}, //Regular surface.\n\t//{DC_WINBUF_SURFACE_KIND, BLOCK_HEIGHT(4) | BLOCK}, //Regular surface.\n\t{DC_WINBUF_START_ADDR, FB_ADDRESS}, //Framebuffer address.\n\t{DC_WINBUF_ADDR_H_OFFSET, 0}, //Linear: 0x383FFC, Block: 0x3813FC\n\t{DC_WINBUF_ADDR_V_OFFSET, 1279}, //Linear: 1279, Block: 0\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE\n\t{DC_WIN_WIN_OPTIONS, WIN_ENABLE | V_DIRECTION}, //Enable window AD.\n\t//{DC_WIN_WIN_OPTIONS, WIN_ENABLE | | SCAN_COLUMN | H_DIRECTION}, //Enable window AD. | SCAN_COLUMN | H_DIRECTION\n\t{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, //DISPLAY_CTRL_MODE: continuous display.\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE}, //General update; window A update.\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ} //General activation request; window A activation request.\n};\n\nstatic const cfg_op_t cfg_display_framebuffer2[32] = {\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, //Enable window C.\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, //Enable window B.\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, //Enable window A.\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE\n\t{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, //T_A8R8G8B8 //NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_WIN_POSITION, 0}, //(0,0)\n\t{DC_WIN_H_INITIAL_DDA, 0},\n\t{DC_WIN_V_INITIAL_DDA, 0},\n\t{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(2880)}, //Pre-scaled size: 1280x2880 bytes.\n\t{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)},\n\t{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)}, //Window size: 1280 vertical lines x 720 horizontal pixels.\n\t{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(1280 * 2) | LINE_STRIDE(1280 * 4)}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.\n\t{DC_WIN_BUFFER_CONTROL, 0},\n\t{DC_WINBUF_SURFACE_KIND, BLOCK_HEIGHT(4) | BLOCK}, //Regular surface.\n\t{DC_WINBUF_START_ADDR, FB_ADDRESS}, //Framebuffer address.\n\t{DC_WINBUF_ADDR_H_OFFSET, 0x3813FC}, //Linear: 0x383FFC, Block: 0x3813FC\n\t{DC_WINBUF_ADDR_V_OFFSET, 0}, //Linear: 1279, Block: 0\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE\n\t{DC_WIN_WIN_OPTIONS, 0},\n\t{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE\n\t{DC_WIN_WIN_OPTIONS, WIN_ENABLE | SCAN_COLUMN | H_DIRECTION}, //Enable window AD. | SCAN_COLUMN | H_DIRECTION\n\t{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, //DISPLAY_CTRL_MODE: continuous display.\n\t{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE}, //General update; window A update.\n\t{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ} //General activation request; window A activation request.\n};\n"
  },
  {
    "path": "argon-nx-gui/include/gfx/gfx.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018 CTCaer\n * Copyright (C) 2018 M4xw\n * Copyright (C) 2018 Guillem96\n * \n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _GFX_H_\n#define _GFX_H_\n\n#include \"utils/types.h\"\n\n#define RED 0xFF0000FF\n#define GREEN 0xFF00FF00\n#define BLUE 0xFFFF0000\n#define YELLOW 0xFF00FFFF\n#define ORANGE 0xFF3891FF\n#define WHITE 0xFFFFFFFF\n#define BLACK 0xFF000000\n\n#define CHAR_WIDTH 8\n#define CHAR_HEIGHT 8\n\ntypedef struct _gfx_ctxt_t\n{\n\tu32 *fb;\n    u32* next;\n\tu32 width;\n\tu32 height;\n\tu32 stride;\n} gfx_ctxt_t;\n\ntypedef struct _gfx_con_t\n{\n\tgfx_ctxt_t *gfx_ctxt;\n    u8 scale;\n\tu32 fntsz;\n\tu32 x;\n\tu32 y;\n\tu32 savedx;\n\tu32 savedy;\n\tu32 fgcol;\n\tint fillbg;\n\tu32 bgcol;\n\tbool mute;\n} gfx_con_t;\n\ntypedef struct \n{\n    u32 size;\n    u32 size_x;\n    u32 size_y;\n    u32 offset;\n    u32 pos_x;\n    u32 pos_y;\n} bmp_data_t;\n\nvoid gfx_init_ctxt(u32 *fb, u32 width, u32 height, u32 stride);\nvoid gfx_clear_grey(u8 color);\nvoid gfx_clear_partial_grey(u8 color, u32 pos_x, u32 height);\nvoid gfx_clear_color(u32 color);\nvoid gfx_con_init();\nvoid gfx_con_setcol(u32 fgcol, int fillbg, u32 bgcol);\nvoid gfx_con_getpos(u32 *x, u32 *y);\nvoid gfx_con_setpos(u32 x, u32 y);\nvoid gfx_putc(char c);\nvoid gfx_puts(const char *s);\nvoid gfx_printf(const char *fmt, ...);\nvoid gfx_hexdump(u32 base, const u8 *buf, u32 len);\n\nvoid gfx_set_pixel(u32 x, u32 y, u32 color);\nvoid gfx_line(int x0, int y0, int x1, int y1, u32 color);\nvoid gfx_put_small_sep();\nvoid gfx_put_big_sep();\nvoid gfx_set_rect_grey(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);\nvoid gfx_set_rect_rgb(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);\nvoid gfx_set_rect_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);\n\nvoid gfx_set_rect_argb_land(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);\nvoid gfx_fill_rect_argb(const u32 color, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);\nvoid gfx_render_bmp_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);\n\nvoid gfx_set_rect_land_pitch(u32 *fb, const u32 *buf, u32 pos_x, u32 pos_y, u32 pos_x2, u32 pos_y2);\nvoid gfx_set_rect_land_block(const u32 *buf, u32 pos_x, u32 pos_y, u32 pos_x2, u32 pos_y2);\n\n// Global gfx console and context.\ngfx_ctxt_t g_gfx_ctxt;\ngfx_con_t g_gfx_con;\n\n#endif\n\n"
  },
  {
    "path": "argon-nx-gui/include/gfx/lvgl_adapter.h",
    "content": "#ifndef _LVGL_ADAPTER_H_\n#define _LVGL_ADAPTER_H_\n\n#include \"core/argon-ctxt.h\"\n\nvoid lvgl_adapter_init(argon_ctxt_t* argon_ctxt);\nlv_img_dsc_t *bmp_to_lvimg_obj(const char *path);\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/ianos/ianos.h",
    "content": "/*\n * Copyright (c) 2018 M4xw\n * Copyright (c) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef IANOS_H\n#define IANOS_H\n\n#include <stdint.h>\n#include \"utils/types.h\"\n\ntypedef enum\n{\n\tDRAM_LIB = 0, // DRAM library.\n\tEXEC_ELF = 1, // Executable elf that does not return.\n\tDR64_LIB = 2, // AARCH64 DRAM library.\n\tAR64_ELF = 3, // Executable elf that does not return.\n\tKEEP_IN_RAM = (1 << 31)  // Shared library mask.\n} elfType_t;\n\nuintptr_t ianos_loader(bool sdmount, char *path, elfType_t type, void* config);\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/libs/compr/blz.h",
    "content": "/*\n * Copyright (c) 2018 rajkosto\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _BLZ_H_\n#define _BLZ_H_\n\n#include \"utils/types.h\"\n\ntypedef struct _blz_footer\n{\n\tu32 cmp_and_hdr_size;\n\tu32 header_size;\n\tu32 addl_size;\n} blz_footer;\n\n// Returns pointer to footer in compData if present, additionally copies it to outFooter if not NULL.\nconst blz_footer *blz_get_footer(const unsigned char *compData, unsigned int compDataLen, blz_footer *outFooter);\n// Returns 0 on failure.\nint blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const blz_footer *footer);\n// Returns 0 on failure.\nint blz_uncompress_srcdest(const unsigned char *compData, unsigned int compDataLen, unsigned char *dstData, unsigned int dstSize);\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/libs/compr/lz.h",
    "content": "/*************************************************************************\n* Name:        lz.h\n* Author:      Marcus Geelnard\n* Description: LZ77 coder/decoder interface.\n* Reentrant:   Yes\n*-------------------------------------------------------------------------\n* Copyright (c) 2003-2006 Marcus Geelnard\n*\n* This software is provided 'as-is', without any express or implied\n* warranty. In no event will the authors be held liable for any damages\n* arising from the use of this software.\n*\n* Permission is granted to anyone to use this software for any purpose,\n* including commercial applications, and to alter it and redistribute it\n* freely, subject to the following restrictions:\n*\n* 1. The origin of this software must not be misrepresented; you must not\n*    claim that you wrote the original software. If you use this software\n*    in a product, an acknowledgment in the product documentation would\n*    be appreciated but is not required.\n*\n* 2. Altered source versions must be plainly marked as such, and must not\n*    be misrepresented as being the original software.\n*\n* 3. This notice may not be removed or altered from any source\n*    distribution.\n*\n* Marcus Geelnard\n* marcus.geelnard at home.se\n*************************************************************************/\n\n#ifndef _lz_h_\n#define _lz_h_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/*************************************************************************\n* Function prototypes\n*************************************************************************/\n\nvoid LZ_Uncompress( const unsigned char *in, unsigned char *out,\n                    unsigned int insize );\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _lz_h_ */\n"
  },
  {
    "path": "argon-nx-gui/include/libs/elfload/elf.h",
    "content": "/*    $OpenBSD: exec_elf.h,v 1.53 2014/01/03 03:00:39 guenther Exp $    */\n/*\n * Copyright (c) 1995, 1996 Erik Theisen.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/* imported sys/exec_elf.h from OpenBSD */\n\n#ifndef ELF_H\n#define ELF_H\n#include <stdint.h>\n\ntypedef uint8_t Elf_Byte;\n\ntypedef uint32_t Elf32_Addr; /* Unsigned program address */\ntypedef uint32_t Elf32_Off;  /* Unsigned file offset */\ntypedef int32_t Elf32_Sword; /* Signed large integer */\ntypedef uint32_t Elf32_Word; /* Unsigned large integer */\ntypedef uint16_t Elf32_Half; /* Unsigned medium integer */\n\ntypedef uint64_t Elf64_Addr;\ntypedef uint64_t Elf64_Off;\ntypedef int32_t Elf64_Shalf;\n\n#ifdef __alpha__\ntypedef int64_t Elf64_Sword;\ntypedef uint64_t Elf64_Word;\n#else\ntypedef int32_t Elf64_Sword;\ntypedef uint32_t Elf64_Word;\n#endif\n\ntypedef int64_t Elf64_Sxword;\ntypedef uint64_t Elf64_Xword;\n\ntypedef uint32_t Elf64_Half;\ntypedef uint16_t Elf64_Quarter;\n\n/*\n * e_ident[] identification indexes\n * See http://www.sco.com/developers/gabi/latest/ch4.eheader.html\n */\n#define EI_MAG0 0       /* file ID */\n#define EI_MAG1 1       /* file ID */\n#define EI_MAG2 2       /* file ID */\n#define EI_MAG3 3       /* file ID */\n#define EI_CLASS 4      /* file class */\n#define EI_DATA 5       /* data encoding */\n#define EI_VERSION 6    /* ELF header version */\n#define EI_OSABI 7      /* OS/ABI ID */\n#define EI_ABIVERSION 8 /* ABI version */\n#define EI_PAD 9        /* start of pad bytes */\n#define EI_NIDENT 16    /* Size of e_ident[] */\n\n/* e_ident[] magic number */\n#define ELFMAG0 0x7f     /* e_ident[EI_MAG0] */\n#define ELFMAG1 'E'      /* e_ident[EI_MAG1] */\n#define ELFMAG2 'L'      /* e_ident[EI_MAG2] */\n#define ELFMAG3 'F'      /* e_ident[EI_MAG3] */\n#define ELFMAG \"\\177ELF\" /* magic */\n#define SELFMAG 4        /* size of magic */\n\n/* e_ident[] file class */\n#define ELFCLASSNONE 0 /* invalid */\n#define ELFCLASS32 1   /* 32-bit objs */\n#define ELFCLASS64 2   /* 64-bit objs */\n#define ELFCLASSNUM 3  /* number of classes */\n\n/* e_ident[] data encoding */\n#define ELFDATANONE 0 /* invalid */\n#define ELFDATA2LSB 1 /* Little-Endian */\n#define ELFDATA2MSB 2 /* Big-Endian */\n#define ELFDATANUM 3  /* number of data encode defines */\n\n/* e_ident[] Operating System/ABI */\n#define ELFOSABI_SYSV 0         /* UNIX System V ABI */\n#define ELFOSABI_HPUX 1         /* HP-UX operating system */\n#define ELFOSABI_NETBSD 2       /* NetBSD */\n#define ELFOSABI_LINUX 3        /* GNU/Linux */\n#define ELFOSABI_HURD 4         /* GNU/Hurd */\n#define ELFOSABI_86OPEN 5       /* 86Open common IA32 ABI */\n#define ELFOSABI_SOLARIS 6      /* Solaris */\n#define ELFOSABI_MONTEREY 7     /* Monterey */\n#define ELFOSABI_IRIX 8         /* IRIX */\n#define ELFOSABI_FREEBSD 9      /* FreeBSD */\n#define ELFOSABI_TRU64 10       /* TRU64 UNIX */\n#define ELFOSABI_MODESTO 11     /* Novell Modesto */\n#define ELFOSABI_OPENBSD 12     /* OpenBSD */\n#define ELFOSABI_ARM 97         /* ARM */\n#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */\n\n/* e_ident */\n#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \\\n                      (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \\\n                      (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \\\n                      (ehdr).e_ident[EI_MAG3] == ELFMAG3)\n\n/* ELF Header */\ntypedef struct\n{\n    unsigned char e_ident[EI_NIDENT]; /* ELF Identification */\n    Elf32_Half e_type;                /* object file type */\n    Elf32_Half e_machine;             /* machine */\n    Elf32_Word e_version;             /* object file version */\n    Elf32_Addr e_entry;               /* virtual entry point */\n    Elf32_Off e_phoff;                /* program header table offset */\n    Elf32_Off e_shoff;                /* section header table offset */\n    Elf32_Word e_flags;               /* processor-specific flags */\n    Elf32_Half e_ehsize;              /* ELF header size */\n    Elf32_Half e_phentsize;           /* program header entry size */\n    Elf32_Half e_phnum;               /* number of program header entries */\n    Elf32_Half e_shentsize;           /* section header entry size */\n    Elf32_Half e_shnum;               /* number of section header entries */\n    Elf32_Half e_shstrndx;            /* section header table's \"section\n                                                header string table\" entry offset */\n} Elf32_Ehdr;\n\ntypedef struct\n{\n    unsigned char e_ident[EI_NIDENT]; /* Id bytes */\n    Elf64_Quarter e_type;             /* file type */\n    Elf64_Quarter e_machine;          /* machine type */\n    Elf64_Half e_version;             /* version number */\n    Elf64_Addr e_entry;               /* entry point */\n    Elf64_Off e_phoff;                /* Program hdr offset */\n    Elf64_Off e_shoff;                /* Section hdr offset */\n    Elf64_Half e_flags;               /* Processor flags */\n    Elf64_Quarter e_ehsize;           /* sizeof ehdr */\n    Elf64_Quarter e_phentsize;        /* Program header entry size */\n    Elf64_Quarter e_phnum;            /* Number of program headers */\n    Elf64_Quarter e_shentsize;        /* Section header entry size */\n    Elf64_Quarter e_shnum;            /* Number of section headers */\n    Elf64_Quarter e_shstrndx;         /* String table index */\n} Elf64_Ehdr;\n\n/* e_type */\n#define ET_NONE 0        /* No file type */\n#define ET_REL 1         /* relocatable file */\n#define ET_EXEC 2        /* executable file */\n#define ET_DYN 3         /* shared object file */\n#define ET_CORE 4        /* core file */\n#define ET_NUM 5         /* number of types */\n#define ET_LOPROC 0xff00 /* reserved range for processor */\n#define ET_HIPROC 0xffff /*  specific e_type */\n\n/* e_machine */\n#define EM_NONE 0  /* No Machine */\n#define EM_M32 1   /* AT&T WE 32100 */\n#define EM_SPARC 2 /* SPARC */\n#define EM_386 3   /* Intel 80386 */\n#define EM_68K 4   /* Motorola 68000 */\n#define EM_88K 5   /* Motorola 88000 */\n#define EM_486 6   /* Intel 80486 - unused? */\n#define EM_860 7   /* Intel 80860 */\n#define EM_MIPS 8  /* MIPS R3000 Big-Endian only */\n/*\n * Don't know if EM_MIPS_RS4_BE,\n * EM_SPARC64, EM_PARISC,\n * or EM_PPC are ABI compliant\n */\n#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */\n#define EM_SPARC64 11     /* SPARC v9 64-bit unofficial */\n#define EM_PARISC 15      /* HPPA */\n#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */\n#define EM_PPC 20         /* PowerPC */\n#define EM_ARM 40         /* ARM AArch32 */\n#define EM_ALPHA 41       /* DEC ALPHA */\n#define EM_SH 42          /* Hitachi/Renesas Super-H */\n#define EM_SPARCV9 43     /* SPARC version 9 */\n#define EM_IA_64 50       /* Intel IA-64 Processor */\n#define EM_AMD64 62       /* AMD64 architecture */\n#define EM_VAX 75         /* DEC VAX */\n#define EM_AARCH64 183    /* ARM AArch64 */\n\n/* Non-standard */\n#define EM_ALPHA_EXP 0x9026 /* DEC ALPHA */\n\n/* Version */\n#define EV_NONE 0    /* Invalid */\n#define EV_CURRENT 1 /* Current */\n#define EV_NUM 2     /* number of versions */\n\n/* Section Header */\ntypedef struct\n{\n    Elf32_Word sh_name;      /* name - index into section header\n                                 * string table section */\n    Elf32_Word sh_type;      /* type */\n    Elf32_Word sh_flags;     /* flags */\n    Elf32_Addr sh_addr;      /* address */\n    Elf32_Off sh_offset;     /* file offset */\n    Elf32_Word sh_size;      /* section size */\n    Elf32_Word sh_link;      /* section header table index link */\n    Elf32_Word sh_info;      /* extra information */\n    Elf32_Word sh_addralign; /* address alignment */\n    Elf32_Word sh_entsize;   /* section entry size */\n} Elf32_Shdr;\n\ntypedef struct\n{\n    Elf64_Half sh_name;       /* section name */\n    Elf64_Half sh_type;       /* section type */\n    Elf64_Xword sh_flags;     /* section flags */\n    Elf64_Addr sh_addr;       /* virtual address */\n    Elf64_Off sh_offset;      /* file offset */\n    Elf64_Xword sh_size;      /* section size */\n    Elf64_Half sh_link;       /* link to another */\n    Elf64_Half sh_info;       /* misc info */\n    Elf64_Xword sh_addralign; /* memory alignment */\n    Elf64_Xword sh_entsize;   /* table entry size */\n} Elf64_Shdr;\n\n/* Special Section Indexes */\n#define SHN_UNDEF 0          /* undefined */\n#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */\n#define SHN_LOPROC 0xff00    /* reserved range for processor */\n#define SHN_HIPROC 0xff1f    /*   specific section indexes */\n#define SHN_ABS 0xfff1       /* absolute value */\n#define SHN_COMMON 0xfff2    /* common symbol */\n#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */\n\n/* sh_type */\n#define SHT_NULL 0            /* inactive */\n#define SHT_PROGBITS 1        /* program defined information */\n#define SHT_SYMTAB 2          /* symbol table section */\n#define SHT_STRTAB 3          /* string table section */\n#define SHT_RELA 4            /* relocation section with addends*/\n#define SHT_HASH 5            /* symbol hash table section */\n#define SHT_DYNAMIC 6         /* dynamic section */\n#define SHT_NOTE 7            /* note section */\n#define SHT_NOBITS 8          /* no space section */\n#define SHT_REL 9             /* relation section without addends */\n#define SHT_SHLIB 10          /* reserved - purpose unknown */\n#define SHT_DYNSYM 11         /* dynamic symbol table section */\n#define SHT_NUM 12            /* number of section types */\n#define SHT_LOPROC 0x70000000 /* reserved range for processor */\n#define SHT_HIPROC 0x7fffffff /*  specific section header types */\n#define SHT_LOUSER 0x80000000 /* reserved range for application */\n#define SHT_HIUSER 0xffffffff /*  specific indexes */\n\n/* Section names */\n#define ELF_BSS \".bss\"               /* uninitialized data */\n#define ELF_DATA \".data\"             /* initialized data */\n#define ELF_DEBUG \".debug\"           /* debug */\n#define ELF_DYNAMIC \".dynamic\"       /* dynamic linking information */\n#define ELF_DYNSTR \".dynstr\"         /* dynamic string table */\n#define ELF_DYNSYM \".dynsym\"         /* dynamic symbol table */\n#define ELF_FINI \".fini\"             /* termination code */\n#define ELF_GOT \".got\"               /* global offset table */\n#define ELF_HASH \".hash\"             /* symbol hash table */\n#define ELF_INIT \".init\"             /* initialization code */\n#define ELF_REL_DATA \".rel.data\"     /* relocation data */\n#define ELF_REL_FINI \".rel.fini\"     /* relocation termination code */\n#define ELF_REL_INIT \".rel.init\"     /* relocation initialization code */\n#define ELF_REL_DYN \".rel.dyn\"       /* relocation dynamic link info */\n#define ELF_REL_RODATA \".rel.rodata\" /* relocation read-only data */\n#define ELF_REL_TEXT \".rel.text\"     /* relocation code */\n#define ELF_RODATA \".rodata\"         /* read-only data */\n#define ELF_SHSTRTAB \".shstrtab\"     /* section header string table */\n#define ELF_STRTAB \".strtab\"         /* string table */\n#define ELF_SYMTAB \".symtab\"         /* symbol table */\n#define ELF_TEXT \".text\"             /* code */\n\n/* Section Attribute Flags - sh_flags */\n#define SHF_WRITE 0x1           /* Writable */\n#define SHF_ALLOC 0x2           /* occupies memory */\n#define SHF_EXECINSTR 0x4       /* executable */\n#define SHF_TLS 0x400           /* thread local storage */\n#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor \\\n                                 *  specific section attributes */\n\n/* Symbol Table Entry */\ntypedef struct elf32_sym\n{\n    Elf32_Word st_name;     /* name - index into string table */\n    Elf32_Addr st_value;    /* symbol value */\n    Elf32_Word st_size;     /* symbol size */\n    unsigned char st_info;  /* type and binding */\n    unsigned char st_other; /* 0 - no defined meaning */\n    Elf32_Half st_shndx;    /* section header index */\n} Elf32_Sym;\n\ntypedef struct\n{\n    Elf64_Half st_name;     /* Symbol name index in str table */\n    Elf_Byte st_info;       /* type / binding attrs */\n    Elf_Byte st_other;      /* unused */\n    Elf64_Quarter st_shndx; /* section index of symbol */\n    Elf64_Xword st_value;   /* value of symbol */\n    Elf64_Xword st_size;    /* size of symbol */\n} Elf64_Sym;\n\n/* Symbol table index */\n#define STN_UNDEF 0 /* undefined */\n\n/* Extract symbol info - st_info */\n#define ELF32_ST_BIND(x) ((x) >> 4)\n#define ELF32_ST_TYPE(x) (((unsigned int)x) & 0xf)\n#define ELF32_ST_INFO(b, t) (((b) << 4) + ((t)&0xf))\n\n#define ELF64_ST_BIND(x) ((x) >> 4)\n#define ELF64_ST_TYPE(x) (((unsigned int)x) & 0xf)\n#define ELF64_ST_INFO(b, t) (((b) << 4) + ((t)&0xf))\n\n/* Symbol Binding - ELF32_ST_BIND - st_info */\n#define STB_LOCAL 0   /* Local symbol */\n#define STB_GLOBAL 1  /* Global symbol */\n#define STB_WEAK 2    /* like global - lower precedence */\n#define STB_NUM 3     /* number of symbol bindings */\n#define STB_LOPROC 13 /* reserved range for processor */\n#define STB_HIPROC 15 /*  specific symbol bindings */\n\n/* Symbol type - ELF32_ST_TYPE - st_info */\n#define STT_NOTYPE 0  /* not specified */\n#define STT_OBJECT 1  /* data object */\n#define STT_FUNC 2    /* function */\n#define STT_SECTION 3 /* section */\n#define STT_FILE 4    /* file */\n#define STT_TLS 6     /* thread local storage */\n#define STT_LOPROC 13 /* reserved range for processor */\n#define STT_HIPROC 15 /*  specific symbol types */\n\n/* Relocation entry with implicit addend */\ntypedef struct\n{\n    Elf32_Addr r_offset; /* offset of relocation */\n    Elf32_Word r_info;   /* symbol table index and type */\n} Elf32_Rel;\n\n/* Relocation entry with explicit addend */\ntypedef struct\n{\n    Elf32_Addr r_offset; /* offset of relocation */\n    Elf32_Word r_info;   /* symbol table index and type */\n    Elf32_Sword r_addend;\n} Elf32_Rela;\n\n/* Extract relocation info - r_info */\n#define ELF32_R_SYM(i) ((i) >> 8)\n#define ELF32_R_TYPE(i) ((unsigned char)(i))\n#define ELF32_R_INFO(s, t) (((s) << 8) + (unsigned char)(t))\n\ntypedef struct\n{\n    Elf64_Xword r_offset; /* where to do it */\n    Elf64_Xword r_info;   /* index & type of relocation */\n} Elf64_Rel;\n\ntypedef struct\n{\n    Elf64_Xword r_offset;  /* where to do it */\n    Elf64_Xword r_info;    /* index & type of relocation */\n    Elf64_Sxword r_addend; /* adjustment value */\n} Elf64_Rela;\n\n#define ELF64_R_SYM(info) ((info) >> 32)\n#define ELF64_R_TYPE(info) ((info)&0xFFFFFFFF)\n#define ELF64_R_INFO(s, t) (((s) << 32) + (__uint32_t)(t))\n\n#if defined(__mips64__) && defined(__MIPSEL__)\n/*\n * The 64-bit MIPS ELF ABI uses a slightly different relocation format\n * than the regular ELF ABI: the r_info field is split into several\n * pieces (see gnu/usr.bin/binutils/include/elf/mips.h for details).\n */\n#undef ELF64_R_SYM\n#undef ELF64_R_TYPE\n#undef ELF64_R_INFO\n#define ELF64_R_TYPE(info) (swap32((info) >> 32))\n#define ELF64_R_SYM(info) ((info)&0xFFFFFFFF)\n#define ELF64_R_INFO(s, t) (((__uint64_t)swap32(t) << 32) + (__uint32_t)(s))\n#endif /* __mips64__ && __MIPSEL__ */\n\n/* Program Header */\ntypedef struct\n{\n    Elf32_Word p_type;   /* segment type */\n    Elf32_Off p_offset;  /* segment offset */\n    Elf32_Addr p_vaddr;  /* virtual address of segment */\n    Elf32_Addr p_paddr;  /* physical address - ignored? */\n    Elf32_Word p_filesz; /* number of bytes in file for seg. */\n    Elf32_Word p_memsz;  /* number of bytes in mem. for seg. */\n    Elf32_Word p_flags;  /* flags */\n    Elf32_Word p_align;  /* memory alignment */\n} Elf32_Phdr;\n\ntypedef struct\n{\n    Elf64_Half p_type;    /* entry type */\n    Elf64_Half p_flags;   /* flags */\n    Elf64_Off p_offset;   /* offset */\n    Elf64_Addr p_vaddr;   /* virtual address */\n    Elf64_Addr p_paddr;   /* physical address */\n    Elf64_Xword p_filesz; /* file size */\n    Elf64_Xword p_memsz;  /* memory size */\n    Elf64_Xword p_align;  /* memory & file alignment */\n} Elf64_Phdr;\n\n/* Segment types - p_type */\n#define PT_NULL 0            /* unused */\n#define PT_LOAD 1            /* loadable segment */\n#define PT_DYNAMIC 2         /* dynamic linking section */\n#define PT_INTERP 3          /* the RTLD */\n#define PT_NOTE 4            /* auxiliary information */\n#define PT_SHLIB 5           /* reserved - purpose undefined */\n#define PT_PHDR 6            /* program header */\n#define PT_TLS 7             /* thread local storage */\n#define PT_LOOS 0x60000000   /* reserved range for OS */\n#define PT_HIOS 0x6fffffff   /*  specific segment types */\n#define PT_LOPROC 0x70000000 /* reserved range for processor */\n#define PT_HIPROC 0x7fffffff /*  specific segment types */\n\n#define PT_OPENBSD_RANDOMIZE 0x65a3dbe6 /* fill with random data */\n#define PT_GANDR_KERNEL 0x67646b6c      /* gdkl */\n\n/* Segment flags - p_flags */\n#define PF_X 0x1               /* Executable */\n#define PF_W 0x2               /* Writable */\n#define PF_R 0x4               /* Readable */\n#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */\n                               /*  specific segment flags */\n\n/* Dynamic structure */\ntypedef struct\n{\n    Elf32_Sword d_tag; /* controls meaning of d_val */\n    union {\n        Elf32_Word d_val; /* Multiple meanings - see d_tag */\n        Elf32_Addr d_ptr; /* program virtual address */\n    } d_un;\n} Elf32_Dyn;\n\ntypedef struct\n{\n    Elf64_Xword d_tag; /* controls meaning of d_val */\n    union {\n        Elf64_Addr d_ptr;\n        Elf64_Xword d_val;\n    } d_un;\n} Elf64_Dyn;\n\n/* Dynamic Array Tags - d_tag */\n#define DT_NULL 0            /* marks end of _DYNAMIC array */\n#define DT_NEEDED 1          /* string table offset of needed lib */\n#define DT_PLTRELSZ 2        /* size of relocation entries in PLT */\n#define DT_PLTGOT 3          /* address PLT/GOT */\n#define DT_HASH 4            /* address of symbol hash table */\n#define DT_STRTAB 5          /* address of string table */\n#define DT_SYMTAB 6          /* address of symbol table */\n#define DT_RELA 7            /* address of relocation table */\n#define DT_RELASZ 8          /* size of relocation table */\n#define DT_RELAENT 9         /* size of relocation entry */\n#define DT_STRSZ 10          /* size of string table */\n#define DT_SYMENT 11         /* size of symbol table entry */\n#define DT_INIT 12           /* address of initialization func. */\n#define DT_FINI 13           /* address of termination function */\n#define DT_SONAME 14         /* string table offset of shared obj */\n#define DT_RPATH 15          /* string table offset of library \\\n                              * search path */\n#define DT_SYMBOLIC 16       /* start sym search in shared obj. */\n#define DT_REL 17            /* address of rel. tbl. w addends */\n#define DT_RELSZ 18          /* size of DT_REL relocation table */\n#define DT_RELENT 19         /* size of DT_REL relocation entry */\n#define DT_PLTREL 20         /* PLT referenced relocation entry */\n#define DT_DEBUG 21          /* bugger */\n#define DT_TEXTREL 22        /* Allow rel. mod. to unwritable seg */\n#define DT_JMPREL 23         /* add. of PLT's relocation entries */\n#define DT_BIND_NOW 24       /* Bind now regardless of env setting */\n#define DT_LOOS 0x6000000d   /* reserved range for OS */\n#define DT_HIOS 0x6ffff000   /*  specific dynamic array tags */\n#define DT_LOPROC 0x70000000 /* reserved range for processor */\n#define DT_HIPROC 0x7fffffff /*  specific dynamic array tags */\n\n/* some other useful tags */\n#define DT_RELACOUNT 0x6ffffff9 /* if present, number of RELATIVE */\n#define DT_RELCOUNT 0x6ffffffa  /* relocs, which must come first */\n#define DT_FLAGS_1 0x6ffffffb\n\n/* Dynamic Flags - DT_FLAGS_1 .dynamic entry */\n#define DF_1_NOW 0x00000001\n#define DF_1_GLOBAL 0x00000002\n#define DF_1_GROUP 0x00000004\n#define DF_1_NODELETE 0x00000008\n#define DF_1_LOADFLTR 0x00000010\n#define DF_1_INITFIRST 0x00000020\n#define DF_1_NOOPEN 0x00000040\n#define DF_1_ORIGIN 0x00000080\n#define DF_1_DIRECT 0x00000100\n#define DF_1_TRANS 0x00000200\n#define DF_1_INTERPOSE 0x00000400\n#define DF_1_NODEFLIB 0x00000800\n#define DF_1_NODUMP 0x00001000\n#define DF_1_CONLFAT 0x00002000\n\n/* ld.so: number of low tags that are used saved internally (0 .. DT_NUM-1) */\n#define DT_NUM (DT_JMPREL + 1)\n\n/*\n * Note Definitions\n */\ntypedef struct\n{\n    Elf32_Word namesz;\n    Elf32_Word descsz;\n    Elf32_Word type;\n} Elf32_Note;\n\ntypedef struct\n{\n    Elf64_Half namesz;\n    Elf64_Half descsz;\n    Elf64_Half type;\n} Elf64_Note;\n\n#if defined(ELFSIZE) && (ELFSIZE == 32)\n#define Elf_Ehdr Elf32_Ehdr\n#define Elf_Phdr Elf32_Phdr\n#define Elf_Shdr Elf32_Shdr\n#define Elf_Sym Elf32_Sym\n#define Elf_Rel Elf32_Rel\n#define Elf_RelA Elf32_Rela\n#define Elf_Dyn Elf32_Dyn\n#define Elf_Half Elf32_Half\n#define Elf_Word Elf32_Word\n#define Elf_Sword Elf32_Sword\n#define Elf_Addr Elf32_Addr\n#define Elf_Off Elf32_Off\n#define Elf_Nhdr Elf32_Nhdr\n#define Elf_Note Elf32_Note\n\n#define ELF_R_SYM ELF32_R_SYM\n#define ELF_R_TYPE ELF32_R_TYPE\n#define ELF_R_INFO ELF32_R_INFO\n#define ELFCLASS ELFCLASS32\n\n#define ELF_ST_BIND ELF32_ST_BIND\n#define ELF_ST_TYPE ELF32_ST_TYPE\n#define ELF_ST_INFO ELF32_ST_INFO\n\n#elif defined(ELFSIZE) && (ELFSIZE == 64)\n\n#define Elf_Ehdr Elf64_Ehdr\n#define Elf_Phdr Elf64_Phdr\n#define Elf_Shdr Elf64_Shdr\n#define Elf_Sym Elf64_Sym\n#define Elf_Rel Elf64_Rel\n#define Elf_RelA Elf64_Rela\n#define Elf_Dyn Elf64_Dyn\n#define Elf_Half Elf64_Half\n#define Elf_Word Elf64_Word\n#define Elf_Sword Elf64_Sword\n#define Elf_Addr Elf64_Addr\n#define Elf_Off Elf64_Off\n#define Elf_Nhdr Elf64_Nhdr\n#define Elf_Note Elf64_Note\n\n#define ELF_R_SYM ELF64_R_SYM\n#define ELF_R_TYPE ELF64_R_TYPE\n#define ELF_R_INFO ELF64_R_INFO\n#define ELFCLASS ELFCLASS64\n\n#define ELF_ST_BIND ELF64_ST_BIND\n#define ELF_ST_TYPE ELF64_ST_TYPE\n#define ELF_ST_INFO ELF64_ST_INFO\n\n#endif\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/libs/elfload/elfarch.h",
    "content": "/*\n * Copyright © 2014, Owen Shepherd\n *\n * Permission to use, copy, modify, and/or distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\n * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\n * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n * PERFORMANCE OF THIS SOFTWARE.\n */\n\n#ifndef ELFARCH_H\n#define ELFARCH_H\n\n#if defined(__i386__)\n#define EM_THIS EM_386\n#define EL_ARCH_USES_REL\n#elif defined(__amd64__)\n#define EM_THIS EM_AMD64\n#define EL_ARCH_USES_RELA\n#elif defined(__arm__)\n#define EM_THIS EM_ARM\n#define EL_ARCH_USES_REL\n#elif defined(__aarch64__)\n#define EM_THIS EM_AARCH64\n#define EL_ARCH_USES_RELA\n#define EL_ARCH_USES_REL\n#else\n#error specify your ELF architecture\n#endif\n\n#if defined(__LP64__) || defined(__LLP64__)\n#define ELFSIZE 64\n#else\n#define ELFSIZE 32\n#endif\n\n#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\n#define ELFDATATHIS ELFDATA2LSB\n#else\n#define ELFDATATHIS ELFDATA2MSB\n#endif\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/libs/elfload/elfload.h",
    "content": "/*\n * Copyright © 2018, M4xw\n * Copyright © 2014, Owen Shepherd\n *\n * Permission to use, copy, modify, and/or distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\n * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\n * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n * PERFORMANCE OF THIS SOFTWARE.\n */\n\n#ifndef ELFLOAD_H\n#define ELFLOAD_H\n#include <stddef.h>\n\n#include \"elfarch.h\"\n#include \"elf.h\"\n\n#include \"utils/types.h\"\n\n#ifdef DEBUG\n#include \"gfx/gfx.h\"\nextern gfx_con_t g_gfx_con;\n#define EL_DEBUG(format, ...) \\\n\tgfx_printf(format __VA_OPT__(, ) __VA_ARGS__)\n#else\n#define EL_DEBUG(...) \\\n\tdo                \\\n\t{                 \\\n\t} while (0)\n#endif\n\ntypedef enum\n{\n\tEL_OK = 0,\n\n\tEL_EIO,\n\tEL_ENOMEM,\n\n\tEL_NOTELF,\n\tEL_WRONGBITS,\n\tEL_WRONGENDIAN,\n\tEL_WRONGARCH,\n\tEL_WRONGOS,\n\tEL_NOTEXEC,\n\tEL_NODYN,\n\tEL_BADREL,\n\n} el_status;\n\ntypedef struct el_ctx\n{\n\tbool (*pread)(struct el_ctx *ctx, void *dest, size_t nb, size_t offset);\n\n\t/* base_load_* -> address we are actually going to load at\n\t */\n\tElf_Addr\n\t\tbase_load_paddr,\n\t\tbase_load_vaddr;\n\n\t/* size in memory of binary */\n\tElf_Addr memsz;\n\n\t/* required alignment */\n\tElf_Addr align;\n\n\t/* ELF header */\n\tElf_Ehdr ehdr;\n\n\t// Section Header Str Table\n\tElf_Shdr shstr;\n\tElf_Shdr symtab;\n\t\n\t/* Offset of dynamic table (0 if not ET_DYN) */\n\tElf_Off dynoff;\n\t/* Size of dynamic table (0 if not ET_DYN) */\n\tElf_Addr dynsize;\n} el_ctx;\n\nel_status el_pread(el_ctx *ctx, void *def, size_t nb, size_t offset);\n\nel_status el_init(el_ctx *ctx);\ntypedef void *(*el_alloc_cb)(\n\tel_ctx *ctx,\n\tElf_Addr phys,\n\tElf_Addr virt,\n\tElf_Addr size);\n\nel_status el_load(el_ctx *ctx, el_alloc_cb alloccb);\n\n/* find the next phdr of type \\p type, starting at \\p *i.\n * On success, returns EL_OK with *i set to the phdr number, and the phdr loaded\n * in *phdr.\n *\n * If the end of the phdrs table was reached, *i is set to -1 and the contents\n * of *phdr are undefined\n */\nel_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, uint32_t type, unsigned *i);\n\n/* Relocate the loaded executable */\nel_status el_relocate(el_ctx *ctx);\n\n/* find a dynamic table entry\n * returns the entry on success, dyn->d_tag = DT_NULL on failure\n */\nel_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, uint32_t type);\n\ntypedef struct\n{\n\tElf_Off tableoff;\n\tElf_Addr tablesize;\n\tElf_Addr entrysize;\n} el_relocinfo;\n\n/* find all information regarding relocations of a specific type.\n *\n * pass DT_REL or DT_RELA for type\n * sets ri->entrysize = 0 if not found\n */\nel_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, uint32_t type);\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/libs/fatfs/diskio.h",
    "content": "/*-----------------------------------------------------------------------/\n/  Low level disk interface modlue include file   (C)ChaN, 2014          /\n/-----------------------------------------------------------------------*/\n\n#ifndef _DISKIO_DEFINED\n#define _DISKIO_DEFINED\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"../../utils/types.h\"\n\n/* Status of Disk Functions */\ntypedef BYTE\tDSTATUS;\n\n/* Results of Disk Functions */\ntypedef enum {\n\tRES_OK = 0,\t\t/* 0: Successful */\n\tRES_ERROR,\t\t/* 1: R/W Error */\n\tRES_WRPRT,\t\t/* 2: Write Protected */\n\tRES_NOTRDY,\t\t/* 3: Not Ready */\n\tRES_PARERR\t\t/* 4: Invalid Parameter */\n} DRESULT;\n\n\n/*---------------------------------------*/\n/* Prototypes for disk control functions */\n\n\nDSTATUS disk_initialize (BYTE pdrv);\nDSTATUS disk_status (BYTE pdrv);\nDRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);\nDRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);\nDRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);\n\n\n/* Disk Status Bits (DSTATUS) */\n\n#define STA_NOINIT\t\t0x01\t/* Drive not initialized */\n#define STA_NODISK\t\t0x02\t/* No medium in the drive */\n#define STA_PROTECT\t\t0x04\t/* Write protected */\n\n\n/* Command code for disk_ioctrl fucntion */\n\n/* Generic command (Used by FatFs) */\n#define CTRL_SYNC\t\t\t0\t/* Complete pending write process (needed at FF_FS_READONLY == 0) */\n#define GET_SECTOR_COUNT\t1\t/* Get media size (needed at FF_USE_MKFS == 1) */\n#define GET_SECTOR_SIZE\t\t2\t/* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */\n#define GET_BLOCK_SIZE\t\t3\t/* Get erase block size (needed at FF_USE_MKFS == 1) */\n#define CTRL_TRIM\t\t\t4\t/* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */\n\n/* Generic command (Not used by FatFs) */\n#define CTRL_POWER\t\t\t5\t/* Get/Set power status */\n#define CTRL_LOCK\t\t\t6\t/* Lock/Unlock media removal */\n#define CTRL_EJECT\t\t\t7\t/* Eject media */\n#define CTRL_FORMAT\t\t\t8\t/* Create physical format on the media */\n\n/* MMC/SDC specific ioctl command */\n#define MMC_GET_TYPE\t\t10\t/* Get card type */\n#define MMC_GET_CSD\t\t\t11\t/* Get CSD */\n#define MMC_GET_CID\t\t\t12\t/* Get CID */\n#define MMC_GET_OCR\t\t\t13\t/* Get OCR */\n#define MMC_GET_SDSTAT\t\t14\t/* Get SD status */\n#define ISDIO_READ\t\t\t55\t/* Read data form SD iSDIO register */\n#define ISDIO_WRITE\t\t\t56\t/* Write data to SD iSDIO register */\n#define ISDIO_MRITE\t\t\t57\t/* Masked write data to SD iSDIO register */\n\n/* ATA/CF specific ioctl command */\n#define ATA_GET_REV\t\t\t20\t/* Get F/W revision */\n#define ATA_GET_MODEL\t\t21\t/* Get model name */\n#define ATA_GET_SN\t\t\t22\t/* Get serial number */\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/libs/fatfs/ff.h",
    "content": "/*----------------------------------------------------------------------------/\n/  FatFs - Generic FAT Filesystem module  R0.13c                              /\n/-----------------------------------------------------------------------------/\n/\n/ Copyright (C) 2018, ChaN, all right reserved.\n/\n/ FatFs module is an open source software. Redistribution and use of FatFs in\n/ source and binary forms, with or without modification, are permitted provided\n/ that the following condition is met:\n/ 1. Redistributions of source code must retain the above copyright notice,\n/    this condition and the following disclaimer.\n/\n/ This software is provided by the copyright holder and contributors \"AS IS\"\n/ and any warranties related to this software are DISCLAIMED.\n/ The copyright owner or contributors be NOT LIABLE for any damages caused\n/ by use of this software.\n/\n/----------------------------------------------------------------------------*/\n\n\n#ifndef FF_DEFINED\n#define FF_DEFINED\t86604\t/* Revision ID */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"../../utils/types.h\"\t/* Basic integer types */\n#include \"ffconf.h\"\t\t/* FatFs configuration options */\n\n#if FF_DEFINED != FFCONF_DEF\n#error Wrong configuration file (ffconf.h).\n#endif\n\n\n\n/* Definitions of volume management */\n\n#if FF_MULTI_PARTITION\t\t/* Multiple partition configuration */\ntypedef struct {\n\tBYTE pd;\t/* Physical drive number */\n\tBYTE pt;\t/* Partition: 0:Auto detect, 1-4:Forced partition) */\n} PARTITION;\nextern PARTITION VolToPart[];\t/* Volume - Partition resolution table */\n#endif\n\n#if FF_STR_VOLUME_ID\n#ifndef FF_VOLUME_STRS\nextern const char* VolumeStr[FF_VOLUMES];\t/* User defied volume ID */\n#endif\n#endif\n\n\n\n/* Type of path name strings on FatFs API */\n\n#ifndef _INC_TCHAR\n#define _INC_TCHAR\n\n#if FF_USE_LFN && FF_LFN_UNICODE == 1 \t/* Unicode in UTF-16 encoding */\ntypedef WCHAR TCHAR;\n#define _T(x) L ## x\n#define _TEXT(x) L ## x\n#elif FF_USE_LFN && FF_LFN_UNICODE == 2\t/* Unicode in UTF-8 encoding */\ntypedef char TCHAR;\n#define _T(x) u8 ## x\n#define _TEXT(x) u8 ## x\n#elif FF_USE_LFN && FF_LFN_UNICODE == 3\t/* Unicode in UTF-32 encoding */\ntypedef DWORD TCHAR;\n#define _T(x) U ## x\n#define _TEXT(x) U ## x\n#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3)\n#error Wrong FF_LFN_UNICODE setting\n#else\t\t\t\t\t\t\t\t\t/* ANSI/OEM code in SBCS/DBCS */\ntypedef char TCHAR;\n#define _T(x) x\n#define _TEXT(x) x\n#endif\n\n#endif\n\n\n\n/* Type of file size variables */\n\n#if FF_FS_EXFAT\ntypedef QWORD FSIZE_t;\n#else\ntypedef DWORD FSIZE_t;\n#endif\n\n\n\n/* Filesystem object structure (FATFS) */\n\ntypedef struct {\n\tBYTE\tfs_type;\t\t/* Filesystem type (0:not mounted) */\n\tBYTE\tpdrv;\t\t\t/* Associated physical drive */\n\tBYTE\tn_fats;\t\t\t/* Number of FATs (1 or 2) */\n\tBYTE\twflag;\t\t\t/* win[] flag (b0:dirty) */\n\tBYTE\tfsi_flag;\t\t/* FSINFO flags (b7:disabled, b0:dirty) */\n\tWORD\tid;\t\t\t\t/* Volume mount ID */\n\tWORD\tn_rootdir;\t\t/* Number of root directory entries (FAT12/16) */\n\tWORD\tcsize;\t\t\t/* Cluster size [sectors] */\n#if FF_MAX_SS != FF_MIN_SS\n\tWORD\tssize;\t\t\t/* Sector size (512, 1024, 2048 or 4096) */\n#endif\n#if FF_USE_LFN\n\tWCHAR*\tlfnbuf;\t\t\t/* LFN working buffer */\n#endif\n#if FF_FS_EXFAT\n\tBYTE*\tdirbuf;\t\t\t/* Directory entry block scratchpad buffer for exFAT */\n#endif\n#if FF_FS_REENTRANT\n\tFF_SYNC_t\tsobj;\t\t/* Identifier of sync object */\n#endif\n#if !FF_FS_READONLY\n\tDWORD\tlast_clst;\t\t/* Last allocated cluster */\n\tDWORD\tfree_clst;\t\t/* Number of free clusters */\n#endif\n#if FF_FS_RPATH\n\tDWORD\tcdir;\t\t\t/* Current directory start cluster (0:root) */\n#if FF_FS_EXFAT\n\tDWORD\tcdc_scl;\t\t/* Containing directory start cluster (invalid when cdir is 0) */\n\tDWORD\tcdc_size;\t\t/* b31-b8:Size of containing directory, b7-b0: Chain status */\n\tDWORD\tcdc_ofs;\t\t/* Offset in the containing directory (invalid when cdir is 0) */\n#endif\n#endif\n\tDWORD\tn_fatent;\t\t/* Number of FAT entries (number of clusters + 2) */\n\tDWORD\tfsize;\t\t\t/* Size of an FAT [sectors] */\n\tDWORD\tvolbase;\t\t/* Volume base sector */\n\tDWORD\tfatbase;\t\t/* FAT base sector */\n\tDWORD\tdirbase;\t\t/* Root directory base sector/cluster */\n\tDWORD\tdatabase;\t\t/* Data base sector */\n#if FF_FS_EXFAT\n\tDWORD\tbitbase;\t\t/* Allocation bitmap base sector */\n#endif\n\tDWORD\twinsect;\t\t/* Current sector appearing in the win[] */\n\tBYTE\twin[FF_MAX_SS];\t/* Disk access window for Directory, FAT (and file data at tiny cfg) */\n} FATFS;\n\n\n\n/* Object ID and allocation information (FFOBJID) */\n\ntypedef struct {\n\tFATFS*\tfs;\t\t\t\t/* Pointer to the hosting volume of this object */\n\tWORD\tid;\t\t\t\t/* Hosting volume mount ID */\n\tBYTE\tattr;\t\t\t/* Object attribute */\n\tBYTE\tstat;\t\t\t/* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */\n\tDWORD\tsclust;\t\t\t/* Object data start cluster (0:no cluster or root directory) */\n\tFSIZE_t\tobjsize;\t\t/* Object size (valid when sclust != 0) */\n#if FF_FS_EXFAT\n\tDWORD\tn_cont;\t\t\t/* Size of first fragment - 1 (valid when stat == 3) */\n\tDWORD\tn_frag;\t\t\t/* Size of last fragment needs to be written to FAT (valid when not zero) */\n\tDWORD\tc_scl;\t\t\t/* Containing directory start cluster (valid when sclust != 0) */\n\tDWORD\tc_size;\t\t\t/* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */\n\tDWORD\tc_ofs;\t\t\t/* Offset in the containing directory (valid when file object and sclust != 0) */\n#endif\n#if FF_FS_LOCK\n\tUINT\tlockid;\t\t\t/* File lock ID origin from 1 (index of file semaphore table Files[]) */\n#endif\n} FFOBJID;\n\n\n\n/* File object structure (FIL) */\n\ntypedef struct {\n\tFFOBJID\tobj;\t\t\t/* Object identifier (must be the 1st member to detect invalid object pointer) */\n\tBYTE\tflag;\t\t\t/* File status flags */\n\tBYTE\terr;\t\t\t/* Abort flag (error code) */\n\tFSIZE_t\tfptr;\t\t\t/* File read/write pointer (Zeroed on file open) */\n\tDWORD\tclust;\t\t\t/* Current cluster of fpter (invalid when fptr is 0) */\n\tDWORD\tsect;\t\t\t/* Sector number appearing in buf[] (0:invalid) */\n#if !FF_FS_READONLY\n\tDWORD\tdir_sect;\t\t/* Sector number containing the directory entry (not used at exFAT) */\n\tBYTE*\tdir_ptr;\t\t/* Pointer to the directory entry in the win[] (not used at exFAT) */\n#endif\n#if !FF_FS_TINY\n\tBYTE\tbuf[FF_MAX_SS];\t/* File private data read/write window */\n#endif\n#if FF_USE_FASTSEEK\n\tDWORD*\tcltbl;\t\t\t/* Pointer to the cluster link map table (nulled on open, set by application) */\n#endif\n} FIL;\n\n\n\n/* Directory object structure (DIR) */\n\ntypedef struct {\n\tFFOBJID\tobj;\t\t\t/* Object identifier */\n\tDWORD\tdptr;\t\t\t/* Current read/write offset */\n\tDWORD\tclust;\t\t\t/* Current cluster */\n\tDWORD\tsect;\t\t\t/* Current sector (0:Read operation has terminated) */\n\tBYTE*\tdir;\t\t\t/* Pointer to the directory item in the win[] */\n\tBYTE\tfn[12];\t\t\t/* SFN (in/out) {body[8],ext[3],status[1]} */\n#if FF_USE_LFN\n\tDWORD\tblk_ofs;\t\t/* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */\n#endif\n#if FF_USE_FIND\n\tconst TCHAR* pat;\t\t/* Pointer to the name matching pattern */\n#endif\n} DIR;\n\n\n\n/* File information structure (FILINFO) */\n\ntypedef struct {\n\tFSIZE_t\tfsize;\t\t\t/* File size */\n\tWORD\tfdate;\t\t\t/* Modified date */\n\tWORD\tftime;\t\t\t/* Modified time */\n\tBYTE\tfattrib;\t\t/* File attribute */\n#if FF_USE_LFN\n\tTCHAR\taltname[FF_SFN_BUF + 1];/* Altenative file name */\n\tTCHAR\tfname[FF_LFN_BUF + 1];\t/* Primary file name */\n#else\n\tTCHAR\tfname[12 + 1];\t/* File name */\n#endif\n} FILINFO;\n\n\n\n/* File function return code (FRESULT) */\n\ntypedef enum {\n\tFR_OK = 0,\t\t\t\t/* (0) Succeeded */\n\tFR_DISK_ERR,\t\t\t/* (1) A hard error occurred in the low level disk I/O layer */\n\tFR_INT_ERR,\t\t\t\t/* (2) Assertion failed */\n\tFR_NOT_READY,\t\t\t/* (3) The physical drive cannot work */\n\tFR_NO_FILE,\t\t\t\t/* (4) Could not find the file */\n\tFR_NO_PATH,\t\t\t\t/* (5) Could not find the path */\n\tFR_INVALID_NAME,\t\t/* (6) The path name format is invalid */\n\tFR_DENIED,\t\t\t\t/* (7) Access denied due to prohibited access or directory full */\n\tFR_EXIST,\t\t\t\t/* (8) Access denied due to prohibited access */\n\tFR_INVALID_OBJECT,\t\t/* (9) The file/directory object is invalid */\n\tFR_WRITE_PROTECTED,\t\t/* (10) The physical drive is write protected */\n\tFR_INVALID_DRIVE,\t\t/* (11) The logical drive number is invalid */\n\tFR_NOT_ENABLED,\t\t\t/* (12) The volume has no work area */\n\tFR_NO_FILESYSTEM,\t\t/* (13) There is no valid FAT volume */\n\tFR_MKFS_ABORTED,\t\t/* (14) The f_mkfs() aborted due to any problem */\n\tFR_TIMEOUT,\t\t\t\t/* (15) Could not get a grant to access the volume within defined period */\n\tFR_LOCKED,\t\t\t\t/* (16) The operation is rejected according to the file sharing policy */\n\tFR_NOT_ENOUGH_CORE,\t\t/* (17) LFN working buffer could not be allocated */\n\tFR_TOO_MANY_OPEN_FILES,\t/* (18) Number of open files > FF_FS_LOCK */\n#ifdef FF_FASTFS\n\tFR_INVALID_PARAMETER,\t/* (19) Given parameter is invalid */\n\tFR_CLTBL_NO_INIT\t    /* (20) The cluster table for fast seek/read/write was not created */\n#else\n\tFR_INVALID_PARAMETER\t/* (19) Given parameter is invalid */\n#endif\n} FRESULT;\n\n\n\n/*--------------------------------------------------------------*/\n/* FatFs module application interface                           */\n\nFRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode);\t\t\t\t/* Open or create a file */\nFRESULT f_close (FIL* fp);\t\t\t\t\t\t\t\t\t\t\t/* Close an open file object */\nFRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br);\t\t\t/* Read data from the file */\nFRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw);\t/* Write data to the file */\n#ifdef FF_FASTFS\nFRESULT f_read_fast (FIL* fp, const void* buff, UINT btr);\t\t\t/* Fast read data from the file */\nFRESULT f_write_fast (FIL* fp, const void* buff, UINT btw);         /* Fast write data to the file */\n#endif\nFRESULT f_lseek (FIL* fp, FSIZE_t ofs);\t\t\t\t\t\t\t\t/* Move file pointer of the file object */\nFRESULT f_truncate (FIL* fp);\t\t\t\t\t\t\t\t\t\t/* Truncate the file */\nFRESULT f_sync (FIL* fp);\t\t\t\t\t\t\t\t\t\t\t/* Flush cached data of the writing file */\nFRESULT f_opendir (DIR* dp, const TCHAR* path);\t\t\t\t\t\t/* Open a directory */\nFRESULT f_closedir (DIR* dp);\t\t\t\t\t\t\t\t\t\t/* Close an open directory */\nFRESULT f_readdir (DIR* dp, FILINFO* fno);\t\t\t\t\t\t\t/* Read a directory item */\nFRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern);\t/* Find first file */\nFRESULT f_findnext (DIR* dp, FILINFO* fno);\t\t\t\t\t\t\t/* Find next file */\nFRESULT f_mkdir (const TCHAR* path);\t\t\t\t\t\t\t\t/* Create a sub directory */\nFRESULT f_unlink (const TCHAR* path);\t\t\t\t\t\t\t\t/* Delete an existing file or directory */\nFRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new);\t/* Rename/Move a file or directory */\nFRESULT f_stat (const TCHAR* path, FILINFO* fno);\t\t\t\t\t/* Get file status */\nFRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask);\t\t\t/* Change attribute of a file/dir */\nFRESULT f_utime (const TCHAR* path, const FILINFO* fno);\t\t\t/* Change timestamp of a file/dir */\nFRESULT f_chdir (const TCHAR* path);\t\t\t\t\t\t\t\t/* Change current directory */\nFRESULT f_chdrive (const TCHAR* path);\t\t\t\t\t\t\t\t/* Change current drive */\nFRESULT f_getcwd (TCHAR* buff, UINT len);\t\t\t\t\t\t\t/* Get current directory */\nFRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs);\t/* Get number of free clusters on the drive */\nFRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn);\t/* Get volume label */\nFRESULT f_setlabel (const TCHAR* label);\t\t\t\t\t\t\t/* Set volume label */\nFRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf);\t/* Forward data to the stream */\n#ifdef FF_FASTFS\nDWORD  *f_expand_cltbl (FIL* fp, UINT tblsz, FSIZE_t ofs);\t\t\t/* Expand file and populate cluster table */\n#endif\nFRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt);\t\t\t\t\t/* Allocate a contiguous block to the file */\nFRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt);\t\t\t/* Mount/Unmount a logical drive */\nFRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len);\t/* Create a FAT volume */\nFRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work);\t\t\t/* Divide a physical drive into some partitions */\nFRESULT f_setcp (WORD cp);\t\t\t\t\t\t\t\t\t\t\t/* Set current code page */\nint f_putc (TCHAR c, FIL* fp);\t\t\t\t\t\t\t\t\t\t/* Put a character to the file */\nint f_puts (const TCHAR* str, FIL* cp);\t\t\t\t\t\t\t\t/* Put a string to the file */\nint f_printf (FIL* fp, const TCHAR* str, ...);\t\t\t\t\t\t/* Put a formatted string to the file */\nTCHAR* f_gets (TCHAR* buff, int len, FIL* fp);\t\t\t\t\t\t/* Get a string from the file */\n\n#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))\n#define f_error(fp) ((fp)->err)\n#define f_tell(fp) ((fp)->fptr)\n#define f_size(fp) ((fp)->obj.objsize)\n#define f_rewind(fp) f_lseek((fp), 0)\n#define f_rewinddir(dp) f_readdir((dp), 0)\n#define f_rmdir(path) f_unlink(path)\n#define f_unmount(path) f_mount(0, path, 0)\n\n#ifndef EOF\n#define EOF (-1)\n#endif\n\n\n\n\n/*--------------------------------------------------------------*/\n/* Additional user defined functions                            */\n\n/* RTC function */\n#if !FF_FS_READONLY && !FF_FS_NORTC\nDWORD get_fattime (void);\n#endif\n\n/* LFN support functions */\n#if FF_USE_LFN >= 1\t\t\t\t\t\t/* Code conversion (defined in unicode.c) */\nWCHAR ff_oem2uni (WCHAR oem, WORD cp);\t/* OEM code to Unicode conversion */\nWCHAR ff_uni2oem (DWORD uni, WORD cp);\t/* Unicode to OEM code conversion */\nDWORD ff_wtoupper (DWORD uni);\t\t\t/* Unicode upper-case conversion */\n#endif\n#if FF_USE_LFN == 3\t\t\t\t\t\t/* Dynamic memory allocation */\nvoid* ff_memalloc (UINT msize);\t\t\t/* Allocate memory block */\nvoid ff_memfree (void* mblock);\t\t\t/* Free memory block */\n#endif\n\n/* Sync functions */\n#if FF_FS_REENTRANT\nint ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj);\t/* Create a sync object */\nint ff_req_grant (FF_SYNC_t sobj);\t\t/* Lock sync object */\nvoid ff_rel_grant (FF_SYNC_t sobj);\t\t/* Unlock sync object */\nint ff_del_syncobj (FF_SYNC_t sobj);\t/* Delete a sync object */\n#endif\n\n\n\n\n/*--------------------------------------------------------------*/\n/* Flags and offset address                                     */\n\n\n/* File access mode and open method flags (3rd argument of f_open) */\n#define\tFA_READ\t\t\t\t0x01\n#define\tFA_WRITE\t\t\t0x02\n#define\tFA_OPEN_EXISTING\t0x00\n#define\tFA_CREATE_NEW\t\t0x04\n#define\tFA_CREATE_ALWAYS\t0x08\n#define\tFA_OPEN_ALWAYS\t\t0x10\n#define\tFA_OPEN_APPEND\t\t0x30\n\n/* Fast seek controls (2nd argument of f_lseek) */\n#define CREATE_LINKMAP\t((FSIZE_t)0 - 1)\n\n/* Format options (2nd argument of f_mkfs) */\n#define FM_FAT\t\t0x01\n#define FM_FAT32\t0x02\n#define FM_EXFAT\t0x04\n#define FM_ANY\t\t0x07\n#define FM_SFD\t\t0x08\n\n/* Filesystem type (FATFS.fs_type) */\n#define FS_FAT12\t1\n#define FS_FAT16\t2\n#define FS_FAT32\t3\n#define FS_EXFAT\t4\n\n/* File attribute bits for directory entry (FILINFO.fattrib) */\n#define\tAM_RDO\t0x01\t/* Read only */\n#define\tAM_HID\t0x02\t/* Hidden */\n#define\tAM_SYS\t0x04\t/* System */\n#define AM_DIR\t0x10\t/* Directory */\n#define AM_ARC\t0x20\t/* Archive */\n\n\n#ifdef __cplusplus\n}\n#endif\n#endif /* FF_DEFINED */"
  },
  {
    "path": "argon-nx-gui/include/libs/fatfs/ffconf.h",
    "content": "/*---------------------------------------------------------------------------/\n/  FatFs Functional Configurations\n/---------------------------------------------------------------------------*/\n\n#define FFCONF_DEF\t86604\t/* Revision ID */\n\n/*---------------------------------------------------------------------------/\n/ Function Configurations\n/---------------------------------------------------------------------------*/\n\n#define FF_FS_READONLY\t0\n/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)\n/  Read-only configuration removes writing API functions, f_write(), f_sync(),\n/  f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()\n/  and optional writing functions as well. */\n\n\n#define FF_FS_MINIMIZE\t0\n/* This option defines minimization level to remove some basic API functions.\n/\n/   0: Basic functions are fully enabled.\n/   1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()\n/      are removed.\n/   2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.\n/   3: f_lseek() function is removed in addition to 2. */\n\n\n#define FF_USE_STRFUNC\t2\n/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().\n/\n/  0: Disable string functions.\n/  1: Enable without LF-CRLF conversion.\n/  2: Enable with LF-CRLF conversion. */\n\n\n#define FF_USE_FIND\t\t1\n/* This option switches filtered directory read functions, f_findfirst() and\n/  f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */\n\n\n#define FF_USE_MKFS\t\t0\n/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */\n\n#define FF_FASTFS 1\n\n#ifdef FF_FASTFS\n#define FF_USE_FASTSEEK\t1\n#else\n#define FF_USE_FASTSEEK\t0\n#endif\n/* This option switches fast seek function. (0:Disable or 1:Enable) */\n\n\n#define FF_USE_EXPAND\t0\n/* This option switches f_expand function. (0:Disable or 1:Enable) */\n\n\n#define FF_USE_CHMOD\t1\n/* This option switches attribute manipulation functions, f_chmod() and f_utime().\n/  (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */\n\n\n#define FF_USE_LABEL\t0\n/* This option switches volume label functions, f_getlabel() and f_setlabel().\n/  (0:Disable or 1:Enable) */\n\n\n#define FF_USE_FORWARD\t0\n/* This option switches f_forward() function. (0:Disable or 1:Enable) */\n\n\n/*---------------------------------------------------------------------------/\n/ Locale and Namespace Configurations\n/---------------------------------------------------------------------------*/\n\n#define FF_CODE_PAGE\t850\n/* This option specifies the OEM code page to be used on the target system.\n/  Incorrect code page setting can cause a file open failure.\n/\n/   437 - U.S.\n/   720 - Arabic\n/   737 - Greek\n/   771 - KBL\n/   775 - Baltic\n/   850 - Latin 1\n/   852 - Latin 2\n/   855 - Cyrillic\n/   857 - Turkish\n/   860 - Portuguese\n/   861 - Icelandic\n/   862 - Hebrew\n/   863 - Canadian French\n/   864 - Arabic\n/   865 - Nordic\n/   866 - Russian\n/   869 - Greek 2\n/   932 - Japanese (DBCS)\n/   936 - Simplified Chinese (DBCS)\n/   949 - Korean (DBCS)\n/   950 - Traditional Chinese (DBCS)\n/     0 - Include all code pages above and configured by f_setcp()\n*/\n\n\n#define FF_USE_LFN\t\t3\n#define FF_MAX_LFN\t\t255\n/* The FF_USE_LFN switches the support for LFN (long file name).\n/\n/   0: Disable LFN. FF_MAX_LFN has no effect.\n/   1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.\n/   2: Enable LFN with dynamic working buffer on the STACK.\n/   3: Enable LFN with dynamic working buffer on the HEAP.\n/\n/  To enable the LFN, ffunicode.c needs to be added to the project. The LFN function\n/  requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and\n/  additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.\n/  The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can\n/  be in range of 12 to 255. It is recommended to be set 255 to fully support LFN\n/  specification.\n/  When use stack for the working buffer, take care on stack overflow. When use heap\n/  memory for the working buffer, memory management functions, ff_memalloc() and\n/  ff_memfree() in ffsystem.c, need to be added to the project. */\n\n\n#define FF_LFN_UNICODE\t0\n/* This option switches the character encoding on the API when LFN is enabled.\n/\n/   0: ANSI/OEM in current CP (TCHAR = char)\n/   1: Unicode in UTF-16 (TCHAR = WCHAR)\n/   2: Unicode in UTF-8 (TCHAR = char)\n/   3: Unicode in UTF-32 (TCHAR = DWORD)\n/\n/  Also behavior of string I/O functions will be affected by this option.\n/  When LFN is not enabled, this option has no effect. */\n\n\n#define FF_LFN_BUF\t\t255\n#define FF_SFN_BUF\t\t12\n/* This set of options defines size of file name members in the FILINFO structure\n/  which is used to read out directory items. These values should be suffcient for\n/  the file names to read. The maximum possible length of the read file name depends\n/  on character encoding. When LFN is not enabled, these options have no effect. */\n\n\n#define FF_STRF_ENCODE\t0\n/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),\n/  f_putc(), f_puts and f_printf() convert the character encoding in it.\n/  This option selects assumption of character encoding ON THE FILE to be\n/  read/written via those functions.\n/\n/   0: ANSI/OEM in current CP\n/   1: Unicode in UTF-16LE\n/   2: Unicode in UTF-16BE\n/   3: Unicode in UTF-8\n*/\n\n\n#define FF_FS_RPATH\t\t0\n/* This option configures support for relative path.\n/\n/   0: Disable relative path and remove related functions.\n/   1: Enable relative path. f_chdir() and f_chdrive() are available.\n/   2: f_getcwd() function is available in addition to 1.\n*/\n\n\n/*---------------------------------------------------------------------------/\n/ Drive/Volume Configurations\n/---------------------------------------------------------------------------*/\n\n#define FF_VOLUMES\t\t1\n/* Number of volumes (logical drives) to be used. (1-10) */\n\n\n#define FF_STR_VOLUME_ID\t0\n#define FF_VOLUME_STRS\t\t\"sd\"\n/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.\n/  When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive\n/  number in the path name. FF_VOLUME_STRS defines the volume ID strings for each\n/  logical drives. Number of items must not be less than FF_VOLUMES. Valid\n/  characters for the volume ID strings are A-Z, a-z and 0-9, however, they are\n/  compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is\n/  not defined, a user defined volume string table needs to be defined as:\n/\n/  const char* VolumeStr[FF_VOLUMES] = {\"ram\",\"flash\",\"sd\",\"usb\",...\n*/\n\n\n#define FF_MULTI_PARTITION\t0\n/* This option switches support for multiple volumes on the physical drive.\n/  By default (0), each logical drive number is bound to the same physical drive\n/  number and only an FAT volume found on the physical drive will be mounted.\n/  When this function is enabled (1), each logical drive number can be bound to\n/  arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()\n/  funciton will be available. */\n\n\n#define FF_MIN_SS\t\t512\n#define FF_MAX_SS\t\t512\n/* This set of options configures the range of sector size to be supported. (512,\n/  1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and\n/  harddisk. But a larger value may be required for on-board flash memory and some\n/  type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured\n/  for variable sector size mode and disk_ioctl() function needs to implement\n/  GET_SECTOR_SIZE command. */\n\n\n#define FF_USE_TRIM\t\t0\n/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)\n/  To enable Trim function, also CTRL_TRIM command should be implemented to the\n/  disk_ioctl() function. */\n\n\n#define FF_FS_NOFSINFO\t1\n/* If you need to know correct free space on the FAT32 volume, set bit 0 of this\n/  option, and f_getfree() function at first time after volume mount will force\n/  a full FAT scan. Bit 1 controls the use of last allocated cluster number.\n/\n/  bit0=0: Use free cluster count in the FSINFO if available.\n/  bit0=1: Do not trust free cluster count in the FSINFO.\n/  bit1=0: Use last allocated cluster number in the FSINFO if available.\n/  bit1=1: Do not trust last allocated cluster number in the FSINFO.\n*/\n\n\n\n/*---------------------------------------------------------------------------/\n/ System Configurations\n/---------------------------------------------------------------------------*/\n\n#define FF_FS_TINY\t\t0\n/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)\n/  At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.\n/  Instead of private sector buffer eliminated from the file object, common sector\n/  buffer in the filesystem object (FATFS) is used for the file data transfer. */\n\n\n#define FF_FS_EXFAT\t\t1\n/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)\n/  To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)\n/  Note that enabling exFAT discards ANSI C (C89) compatibility. */\n\n\n#define FF_FS_NORTC\t\t1\n#define FF_NORTC_MON\t1\n#define FF_NORTC_MDAY\t1\n#define FF_NORTC_YEAR\t2019\n/* The option FF_FS_NORTC switches timestamp function. If the system does not have\n/  any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable\n/  the timestamp function. Every object modified by FatFs will have a fixed timestamp\n/  defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.\n/  To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be\n/  added to the project to read current time form real-time clock. FF_NORTC_MON,\n/  FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.\n/  These options have no effect at read-only configuration (FF_FS_READONLY = 1). */\n\n\n#define FF_FS_LOCK\t\t0\n/* The option FF_FS_LOCK switches file lock function to control duplicated file open\n/  and illegal operation to open objects. This option must be 0 when FF_FS_READONLY\n/  is 1.\n/\n/  0:  Disable file lock function. To avoid volume corruption, application program\n/      should avoid illegal open, remove and rename to the open objects.\n/  >0: Enable file lock function. The value defines how many files/sub-directories\n/      can be opened simultaneously under file lock control. Note that the file\n/      lock control is independent of re-entrancy. */\n\n\n/* #include <somertos.h>\t// O/S definitions */\n#define FF_FS_REENTRANT\t0\n#define FF_FS_TIMEOUT\t1000\n#define FF_SYNC_t\t\tHANDLE\n/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs\n/  module itself. Note that regardless of this option, file access to different\n/  volume is always re-entrant and volume control functions, f_mount(), f_mkfs()\n/  and f_fdisk() function, are always not re-entrant. Only file/directory access\n/  to the same volume is under control of this function.\n/\n/   0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.\n/   1: Enable re-entrancy. Also user provided synchronization handlers,\n/      ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()\n/      function, must be added to the project. Samples are available in\n/      option/syscall.c.\n/\n/  The FF_FS_TIMEOUT defines timeout period in unit of time tick.\n/  The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,\n/  SemaphoreHandle_t and etc. A header file for O/S definitions needs to be\n/  included somewhere in the scope of ff.h. */\n\n\n\n/*--- End of configuration options ---*/"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_conf.h",
    "content": "#ifndef LV_CONF_H\n#define LV_CONF_H\n/* clang-format off */\n\n#include <stdint.h>\n\n/*====================\n   Graphical settings\n *====================*/\n\n/* Maximal horizontal and vertical resolution to support by the library.*/\n#define LV_HOR_RES_MAX          (1280)\n#define LV_VER_RES_MAX          (720)\n\n/* Color depth:\n * - 1:  1 byte per pixel\n * - 8:  RGB233\n * - 16: RGB565\n * - 32: ARGB8888\n */\n#define LV_COLOR_DEPTH     32\n\n/* Swap the 2 bytes of RGB565 color.\n * Useful if the display has a 8 bit interface (e.g. SPI)*/\n#define LV_COLOR_16_SWAP   0\n\n/* 1: Enable screen transparency.\n * Useful for OSD or other overlapping GUIs.\n * Requires `LV_COLOR_DEPTH = 32` colors and the screen's style should be modified: `style.body.opa = ...`*/\n#define LV_COLOR_SCREEN_TRANSP    0\n\n/*Images pixels with this color will not be drawn (with chroma keying)*/\n#define LV_COLOR_TRANSP    LV_COLOR_LIME         /*LV_COLOR_LIME: pure green*/\n\n/* Enable anti-aliasing (lines, and radiuses will be smoothed) */\n#define LV_ANTIALIAS        1\n\n/* Default display refresh period.\n * Can be changed in the display driver (`lv_disp_drv_t`).*/\n#define LV_DISP_DEF_REFR_PERIOD      30      /*[ms]*/\n\n/* Dot Per Inch: used to initialize default sizes.\n * E.g. a button with width = LV_DPI / 2 -> half inch wide\n * (Not so important, you can adjust it to modify default sizes and spaces)*/\n#define LV_DPI              100     /*[px]*/\n\n/* Type of coordinates. Should be `int16_t` (or `int32_t` for extreme cases) */\ntypedef int16_t lv_coord_t;\n\n/*=========================\n   Memory manager settings\n *=========================*/\n\n/* LittelvGL's internal memory manager's settings.\n * The graphical objects and other related data are stored here. */\n\n/* 1: use custom malloc/free, 0: use the built-in `lv_mem_alloc` and `lv_mem_free` */\n#define LV_MEM_CUSTOM      0\n#if LV_MEM_CUSTOM == 0\n/* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/\n#  define LV_MEM_SIZE    (32U * 1024U)\n\n/* Complier prefix for a big array declaration */\n#  define LV_MEM_ATTR\n\n/* Set an address for the memory pool instead of allocating it as an array.\n * Can be in external SRAM too. */\n#  define LV_MEM_ADR          0xF1000000\n\n/* Automatically defrag. on free. Defrag. means joining the adjacent free cells. */\n#  define LV_MEM_AUTO_DEFRAG  1\n#else       /*LV_MEM_CUSTOM*/\n#  define LV_MEM_CUSTOM_INCLUDE \"mem/heap.h\"   /*Header for the dynamic memory function*/\n#  define LV_MEM_CUSTOM_ALLOC   malloc       /*Wrapper to malloc*/\n#  define LV_MEM_CUSTOM_FREE    free         /*Wrapper to free*/\n#endif     /*LV_MEM_CUSTOM*/\n\n/* Garbage Collector settings\n * Used if lvgl is binded to higher level language and the memory is managed by that language */\n#define LV_ENABLE_GC 0\n#if LV_ENABLE_GC != 0\n#  define LV_GC_INCLUDE \"gc.h\"                           /*Include Garbage Collector related things*/\n#  define LV_MEM_CUSTOM_REALLOC   your_realloc           /*Wrapper to realloc*/\n#  define LV_MEM_CUSTOM_GET_SIZE  your_mem_get_size      /*Wrapper to lv_mem_get_size*/\n#endif /* LV_ENABLE_GC */\n\n/*=======================\n   Input device settings\n *=======================*/\n\n/* Input device default settings.\n * Can be changed in the Input device driver (`lv_indev_drv_t`)*/\n\n/* Input device read period in milliseconds */\n#define LV_INDEV_DEF_READ_PERIOD          50\n\n/* Drag threshold in pixels */\n#define LV_INDEV_DEF_DRAG_LIMIT           30\n\n/* Drag throw slow-down in [%]. Greater value -> faster slow-down */\n#define LV_INDEV_DEF_DRAG_THROW           20\n\n/* Long press time in milliseconds.\n * Time to send `LV_EVENT_LONG_PRESSSED`) */\n#define LV_INDEV_DEF_LONG_PRESS_TIME      400\n\n/* Repeated trigger period in long press [ms]\n * Time between `LV_EVENT_LONG_PRESSED_REPEAT */\n#define LV_INDEV_DEF_LONG_PRESS_REP_TIME  100\n\n/*==================\n * Feature usage\n *==================*/\n\n/*1: Enable the Animations */\n#define LV_USE_ANIMATION        1\n#if LV_USE_ANIMATION\n\n/*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/\ntypedef void * lv_anim_user_data_t;\n\n#endif\n\n/* 1: Enable shadow drawing*/\n#define LV_USE_SHADOW           1\n\n/* 1: Enable object groups (for keyboard/encoder navigation) */\n#define LV_USE_GROUP            0\n#if LV_USE_GROUP\ntypedef void * lv_group_user_data_t;\n#endif  /*LV_USE_GROUP*/\n\n/* 1: Enable GPU interface*/\n#define LV_USE_GPU              0\n\n/* 1: Enable file system (might be required for images */\n#define LV_USE_FILESYSTEM       0\n#if LV_USE_FILESYSTEM\n/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/\ntypedef void * lv_fs_drv_user_data_t;\n#endif\n\n/*1: Add a `user_data` to drivers and objects*/\n#define LV_USE_USER_DATA        0\n\n/*========================\n * Image decoder and cache\n *========================*/\n\n/* 1: Enable indexed (palette) images */\n#define LV_IMG_CF_INDEXED       0\n\n/* 1: Enable alpha indexed images */\n#define LV_IMG_CF_ALPHA         0\n\n/* Default image cache size. Image caching keeps the images opened.\n * If only the built-in image formats are used there is no real advantage of caching.\n * (I.e. no new image decoder is added)\n * With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images.\n * However the opened images might consume additional RAM.\n * LV_IMG_CACHE_DEF_SIZE must be >= 1 */\n#define LV_IMG_CACHE_DEF_SIZE       1\n\n/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/\ntypedef void * lv_img_decoder_user_data_t;\n\n/*=====================\n *  Compiler settings\n *====================*/\n/* Define a custom attribute to `lv_tick_inc` function */\n#define LV_ATTRIBUTE_TICK_INC\n\n/* Define a custom attribute to `lv_task_handler` function */\n#define LV_ATTRIBUTE_TASK_HANDLER\n\n/* With size optimization (-Os) the compiler might not align data to\n * 4 or 8 byte boundary. This alignment will be explicitly applied where needed.\n * E.g. __attribute__((aligned(4))) */\n#define LV_ATTRIBUTE_MEM_ALIGN\n\n/* Attribute to mark large constant arrays for example\n * font's bitmaps */\n#define LV_ATTRIBUTE_LARGE_CONST\n\n/*===================\n *  HAL settings\n *==================*/\n\n/* 1: use a custom tick source.\n * It removes the need to manually update the tick with `lv_tick_inc`) */\n#define LV_TICK_CUSTOM     1\n#if LV_TICK_CUSTOM == 1\n#define LV_TICK_CUSTOM_INCLUDE  \"utils/util.h\"       /*Header for the sys time function*/\n#define LV_TICK_CUSTOM_SYS_TIME_EXPR (get_tmr_ms())     /*Expression evaluating to current systime in ms*/\n#endif   /*LV_TICK_CUSTOM*/\n\ntypedef void * lv_disp_drv_user_data_t;             /*Type of user data in the display driver*/\ntypedef void * lv_indev_drv_user_data_t;            /*Type of user data in the input device driver*/\n\n/*================\n * Log settings\n *===============*/\n\n/*1: Enable the log module*/\n#define LV_USE_LOG      0\n#if LV_USE_LOG\n/* How important log should be added:\n * LV_LOG_LEVEL_TRACE       A lot of logs to give detailed information\n * LV_LOG_LEVEL_INFO        Log important events\n * LV_LOG_LEVEL_WARN        Log if something unwanted happened but didn't cause a problem\n * LV_LOG_LEVEL_ERROR       Only critical issue, when the system may fail\n * LV_LOG_LEVEL_NONE        Do not log anything\n */\n#  define LV_LOG_LEVEL    LV_LOG_LEVEL_WARN\n\n/* 1: Print the log with 'printf';\n * 0: user need to register a callback with `lv_log_register_print`*/\n#  define LV_LOG_PRINTF   0\n#endif  /*LV_USE_LOG*/\n\n/*================\n *  THEME USAGE\n *================*/\n#define LV_THEME_LIVE_UPDATE    0   /*1: Allow theme switching at run time. Uses 8..10 kB of RAM*/\n\n#define LV_USE_THEME_DEFAULT    0   /*Built mainly from the built-in styles. Consumes very few RAM*/\n#define LV_USE_THEME_ARGON      1\n\n/*==================\n *    FONT USAGE\n *===================*/\n\n/* The built-in fonts contains the ASCII range and some Symbols with  4 bit-per-pixel.\n * The symbols are available via `LV_SYMBOL_...` defines\n * More info about fonts: https://docs.littlevgl.com/#Fonts\n * To create a new font go to: https://littlevgl.com/ttf-font-to-c-array\n */\n\n/* Robot fonts with bpp = 4\n * https://fonts.google.com/specimen/Roboto  */\n#define LV_FONT_MONTSERRAT_12 0\n#define LV_FONT_MONTSERRAT_40 0\n\n#define LV_FONT_MA_20 1\n#define LV_FONT_MA_30 1\n#define LV_FONT_MA_80 0\n#define LV_FONT_MA_110 1\n\n/*Pixel perfect monospace font\n * http://pelulamu.net/unscii/ */\n#define LV_FONT_UNSCII_8     0\n\n/* Optionally declare your custom fonts here.\n * You can use these fonts as default font too\n * and they will be available globally. E.g.\n * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \\\n *                                LV_FONT_DECLARE(my_font_2)\n */\n#define LV_FONT_CUSTOM_DECLARE\n\n/*Always set a default font from the built-in fonts*/\n#define LV_FONT_DEFAULT        &lv_font_montserrat_alternate_30\n\n/* Enable it if you have fonts with a lot of characters.\n * The limit depends on the font size, font face and bpp\n * but with > 10,000 characters if you see issues probably you need to enable it.*/\n#define LV_FONT_FMT_TXT_LARGE   0\n\n/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/\ntypedef void * lv_font_user_data_t;\n\n/*=================\n *  Text settings\n *=================*/\n\n/* Select a character encoding for strings.\n * Your IDE or editor should have the same character encoding\n * - LV_TXT_ENC_UTF8\n * - LV_TXT_ENC_ASCII\n * */\n#define LV_TXT_ENC LV_TXT_ENC_UTF8\n\n /*Can break (wrap) texts on these chars*/\n#define LV_TXT_BREAK_CHARS                  \" ,.;:-_\"\n\n/*===================\n *  LV_OBJ SETTINGS\n *==================*/\n\n/*Declare the type of the user data of object (can be e.g. `void *`, `int`, `struct`)*/\ntypedef void * lv_obj_user_data_t;\n\n/*1: enable `lv_obj_realaign()` based on `lv_obj_align()` parameters*/\n#define LV_USE_OBJ_REALIGN          1\n\n/* Enable to make the object clickable on a larger area.\n * LV_EXT_CLICK_AREA_OFF or 0: Disable this feature\n * LV_EXT_CLICK_AREA_TINY: The extra area can be adjusted horizontally and vertically (0..255 px)\n * LV_EXT_CLICK_AREA_FULL: The extra area can be adjusted in all 4 directions (-32k..+32k px)\n */\n#define LV_USE_EXT_CLICK_AREA  LV_EXT_CLICK_AREA_OFF\n\n/*==================\n *  LV OBJ X USAGE\n *================*/\n/*\n * Documentation of the object types: https://docs.littlevgl.com/#Object-types\n */\n\n/*Arc (dependencies: -)*/\n#define LV_USE_ARC      0\n\n/*Bar (dependencies: -)*/\n#define LV_USE_BAR      0\n\n/*Button (dependencies: lv_cont*/\n#define LV_USE_BTN      1\n#if LV_USE_BTN != 0\n/*Enable button-state animations - draw a circle on click (dependencies: LV_USE_ANIMATION)*/\n#  define LV_BTN_INK_EFFECT   0\n#endif\n\n/*Button matrix (dependencies: -)*/\n#define LV_USE_BTNM     1\n\n/*Calendar (dependencies: -)*/\n#define LV_USE_CALENDAR 0\n\n/*Canvas (dependencies: lv_img)*/\n#define LV_USE_CANVAS   0\n\n/*Check box (dependencies: lv_btn, lv_label)*/\n#define LV_USE_CB       0\n\n/*Chart (dependencies: -)*/\n#define LV_USE_CHART    0\n#if LV_USE_CHART\n#  define LV_CHART_AXIS_TICK_LABEL_MAX_LEN    20\n#endif\n\n/*Container (dependencies: -*/\n#define LV_USE_CONT     1\n\n/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/\n#define LV_USE_DDLIST    0\n#if LV_USE_DDLIST != 0\n/*Open and close default animation time [ms] (0: no animation)*/\n#  define LV_DDLIST_DEF_ANIM_TIME     200\n#endif\n\n/*Gauge (dependencies:lv_bar, lv_lmeter)*/\n#define LV_USE_GAUGE    0\n\n/*Image (dependencies: lv_label*/\n#define LV_USE_IMG      1\n\n/*Image Button (dependencies: lv_btn*/\n#define LV_USE_IMGBTN   1\n#if LV_USE_IMGBTN\n/*1: The imgbtn requires left, mid and right parts and the width can be set freely*/\n#  define LV_IMGBTN_TILED 0\n#endif\n\n/*Keyboard (dependencies: lv_btnm)*/\n#define LV_USE_KB       0\n\n/*Label (dependencies: -*/\n#define LV_USE_LABEL    1\n#if LV_USE_LABEL != 0\n/*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_ROLL/ROLL_CIRC' mode*/\n#  define LV_LABEL_DEF_SCROLL_SPEED       100\n\n/* Waiting period at beginning/end of animation cycle */\n#  define LV_LABEL_WAIT_CHAR_COUNT        3\n\n/*Enable selecting text of the label */\n#  define LV_LABEL_TEXT_SEL               0\n\n/*Store extra some info in labels (12 bytes) to speed up drawing of very long texts*/\n#  define LV_LABEL_LONG_TXT_HINT          0\n#endif\n\n/*LED (dependencies: -)*/\n#define LV_USE_LED      0\n\n/*Line (dependencies: -*/\n#define LV_USE_LINE     1\n\n/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/\n#define LV_USE_LIST     0\n#if LV_USE_LIST != 0\n/*Default animation time of focusing to a list element [ms] (0: no animation)  */\n#  define LV_LIST_DEF_ANIM_TIME  100\n#endif\n\n/*Line meter (dependencies: *;)*/\n#define LV_USE_LMETER   0\n\n/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/\n#define LV_USE_MBOX     1\n\n/*Page (dependencies: lv_cont)*/\n#define LV_USE_PAGE     1\n#if LV_USE_PAGE != 0\n/*Focus default animation time [ms] (0: no animation)*/\n#  define LV_PAGE_DEF_ANIM_TIME     400\n#endif\n\n/*Preload (dependencies: lv_arc, lv_anim)*/\n#define LV_USE_PRELOAD      0\n#if LV_USE_PRELOAD != 0\n#  define LV_PRELOAD_DEF_ARC_LENGTH   60      /*[deg]*/\n#  define LV_PRELOAD_DEF_SPIN_TIME    1000    /*[ms]*/\n#  define LV_PRELOAD_DEF_ANIM         LV_PRELOAD_TYPE_SPINNING_ARC\n#endif\n\n/*Roller (dependencies: lv_ddlist)*/\n#define LV_USE_ROLLER    0\n#if LV_USE_ROLLER != 0\n/*Focus animation time [ms] (0: no animation)*/\n#  define LV_ROLLER_DEF_ANIM_TIME     200\n\n/*Number of extra \"pages\" when the roller is infinite*/\n#  define LV_ROLLER_INF_PAGES         7\n#endif\n\n/*Slider (dependencies: lv_bar)*/\n#define LV_USE_SLIDER    0\n\n/*Spinbox (dependencies: lv_ta)*/\n#define LV_USE_SPINBOX       0\n\n/*Switch (dependencies: lv_slider)*/\n#define LV_USE_SW       0\n\n/*Text area (dependencies: lv_label, lv_page)*/\n#define LV_USE_TA       0\n#if LV_USE_TA != 0\n#  define LV_TA_DEF_CURSOR_BLINK_TIME 400     /*ms*/\n#  define LV_TA_DEF_PWD_SHOW_TIME     1500    /*ms*/\n#endif\n\n/*Table (dependencies: lv_label)*/\n#define LV_USE_TABLE    0\n#if LV_USE_TABLE\n#  define LV_TABLE_COL_MAX    12\n#endif\n\n/*Tab (dependencies: lv_page, lv_btnm)*/\n#define LV_USE_TABVIEW      1\n#  if LV_USE_TABVIEW != 0\n/*Time of slide animation [ms] (0: no animation)*/\n#  define LV_TABVIEW_DEF_ANIM_TIME    300\n#endif\n\n/*Tileview (dependencies: lv_page) */\n#define LV_USE_TILEVIEW     0\n#if LV_USE_TILEVIEW\n/*Time of slide animation [ms] (0: no animation)*/\n#  define LV_TILEVIEW_DEF_ANIM_TIME   300\n#endif\n\n/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/\n#define LV_USE_WIN      0\n\n/*==================\n * Non-user section\n *==================*/\n\n#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)    /* Disable warnings for Visual Studio*/\n#  define _CRT_SECURE_NO_WARNINGS\n#endif\n\n/*--END OF LV_CONF_H--*/\n\n/*Be sure every define has a default value*/\n#include \"libs/lvgl/lv_conf_checker.h\"\n\n#endif /*LV_CONF_H*/"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_conf_checker.h",
    "content": "/**\n * GENERATED FILE, DO NOT EDIT IT!\n * @file lv_conf_checker.h\n * Make sure all the defines of lv_conf.h have a default value\n**/\n\n#ifndef LV_CONF_CHECKER_H\n#define LV_CONF_CHECKER_H\n/* clang-format off */\n\n#include <stdint.h>\n\n/*====================\n   Graphical settings\n *====================*/\n\n/* Maximal horizontal and vertical resolution to support by the library.*/\n#ifndef LV_HOR_RES_MAX\n#define LV_HOR_RES_MAX          (480)\n#endif\n#ifndef LV_VER_RES_MAX\n#define LV_VER_RES_MAX          (320)\n#endif\n\n/* Color depth:\n * - 1:  1 byte per pixel\n * - 8:  RGB233\n * - 16: RGB565\n * - 32: ARGB8888\n */\n#ifndef LV_COLOR_DEPTH\n#define LV_COLOR_DEPTH     16\n#endif\n\n/* Swap the 2 bytes of RGB565 color.\n * Useful if the display has a 8 bit interface (e.g. SPI)*/\n#ifndef LV_COLOR_16_SWAP\n#define LV_COLOR_16_SWAP   0\n#endif\n\n/* 1: Enable screen transparency.\n * Useful for OSD or other overlapping GUIs.\n * Requires `LV_COLOR_DEPTH = 32` colors and the screen's style should be modified: `style.body.opa = ...`*/\n#ifndef LV_COLOR_SCREEN_TRANSP\n#define LV_COLOR_SCREEN_TRANSP    0\n#endif\n\n/*Images pixels with this color will not be drawn (with chroma keying)*/\n#ifndef LV_COLOR_TRANSP\n#define LV_COLOR_TRANSP    LV_COLOR_LIME         /*LV_COLOR_LIME: pure green*/\n#endif\n\n/* Enable anti-aliasing (lines, and radiuses will be smoothed) */\n#ifndef LV_ANTIALIAS\n#define LV_ANTIALIAS        1\n#endif\n\n/* Default display refresh period.\n * Can be changed in the display driver (`lv_disp_drv_t`).*/\n#ifndef LV_DISP_DEF_REFR_PERIOD\n#define LV_DISP_DEF_REFR_PERIOD      30      /*[ms]*/\n#endif\n\n/* Dot Per Inch: used to initialize default sizes.\n * E.g. a button with width = LV_DPI / 2 -> half inch wide\n * (Not so important, you can adjust it to modify default sizes and spaces)*/\n#ifndef LV_DPI\n#define LV_DPI              100     /*[px]*/\n#endif\n\n/* Type of coordinates. Should be `int16_t` (or `int32_t` for extreme cases) */\n\n/*=========================\n   Memory manager settings\n *=========================*/\n\n/* LittelvGL's internal memory manager's settings.\n * The graphical objects and other related data are stored here. */\n\n/* 1: use custom malloc/free, 0: use the built-in `lv_mem_alloc` and `lv_mem_free` */\n#ifndef LV_MEM_CUSTOM\n#define LV_MEM_CUSTOM      0\n#endif\n#if LV_MEM_CUSTOM == 0\n/* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/\n#ifndef LV_MEM_SIZE\n#  define LV_MEM_SIZE    (32U * 1024U)\n#endif\n\n/* Complier prefix for a big array declaration */\n#ifndef LV_MEM_ATTR\n#  define LV_MEM_ATTR\n#endif\n\n/* Set an address for the memory pool instead of allocating it as an array.\n * Can be in external SRAM too. */\n#ifndef LV_MEM_ADR\n#  define LV_MEM_ADR          0\n#endif\n\n/* Automatically defrag. on free. Defrag. means joining the adjacent free cells. */\n#ifndef LV_MEM_AUTO_DEFRAG\n#  define LV_MEM_AUTO_DEFRAG  1\n#endif\n#else       /*LV_MEM_CUSTOM*/\n#ifndef LV_MEM_CUSTOM_INCLUDE\n#  define LV_MEM_CUSTOM_INCLUDE <stdlib.h>   /*Header for the dynamic memory function*/\n#endif\n#ifndef LV_MEM_CUSTOM_ALLOC\n#  define LV_MEM_CUSTOM_ALLOC   malloc       /*Wrapper to malloc*/\n#endif\n#ifndef LV_MEM_CUSTOM_FREE\n#  define LV_MEM_CUSTOM_FREE    free         /*Wrapper to free*/\n#endif\n#endif     /*LV_MEM_CUSTOM*/\n\n/* Garbage Collector settings\n * Used if lvgl is binded to higher level language and the memory is managed by that language */\n#ifndef LV_ENABLE_GC\n#define LV_ENABLE_GC 0\n#endif\n#if LV_ENABLE_GC != 0\n#ifndef LV_GC_INCLUDE\n#  define LV_GC_INCLUDE \"gc.h\"                           /*Include Garbage Collector related things*/\n#endif\n#ifndef LV_MEM_CUSTOM_REALLOC\n#  define LV_MEM_CUSTOM_REALLOC   your_realloc           /*Wrapper to realloc*/\n#endif\n#ifndef LV_MEM_CUSTOM_GET_SIZE\n#  define LV_MEM_CUSTOM_GET_SIZE  your_mem_get_size      /*Wrapper to lv_mem_get_size*/\n#endif\n#endif /* LV_ENABLE_GC */\n\n/*=======================\n   Input device settings\n *=======================*/\n\n/* Input device default settings.\n * Can be changed in the Input device driver (`lv_indev_drv_t`)*/\n\n/* Input device read period in milliseconds */\n#ifndef LV_INDEV_DEF_READ_PERIOD\n#define LV_INDEV_DEF_READ_PERIOD          30\n#endif\n\n/* Drag threshold in pixels */\n#ifndef LV_INDEV_DEF_DRAG_LIMIT\n#define LV_INDEV_DEF_DRAG_LIMIT           10\n#endif\n\n/* Drag throw slow-down in [%]. Greater value -> faster slow-down */\n#ifndef LV_INDEV_DEF_DRAG_THROW\n#define LV_INDEV_DEF_DRAG_THROW           20\n#endif\n\n/* Long press time in milliseconds.\n * Time to send `LV_EVENT_LONG_PRESSSED`) */\n#ifndef LV_INDEV_DEF_LONG_PRESS_TIME\n#define LV_INDEV_DEF_LONG_PRESS_TIME      400\n#endif\n\n/* Repeated trigger period in long press [ms]\n * Time between `LV_EVENT_LONG_PRESSED_REPEAT */\n#ifndef LV_INDEV_DEF_LONG_PRESS_REP_TIME\n#define LV_INDEV_DEF_LONG_PRESS_REP_TIME  100\n#endif\n\n/*==================\n * Feature usage\n *==================*/\n\n/*1: Enable the Animations */\n#ifndef LV_USE_ANIMATION\n#define LV_USE_ANIMATION        1\n#endif\n#if LV_USE_ANIMATION\n\n/*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/\n\n#endif\n\n/* 1: Enable shadow drawing*/\n#ifndef LV_USE_SHADOW\n#define LV_USE_SHADOW           1\n#endif\n\n/* 1: Enable object groups (for keyboard/encoder navigation) */\n#ifndef LV_USE_GROUP\n#define LV_USE_GROUP            1\n#endif\n#if LV_USE_GROUP\n#endif  /*LV_USE_GROUP*/\n\n/* 1: Enable GPU interface*/\n#ifndef LV_USE_GPU\n#define LV_USE_GPU              1\n#endif\n\n/* 1: Enable file system (might be required for images */\n#ifndef LV_USE_FILESYSTEM\n#define LV_USE_FILESYSTEM       1\n#endif\n#if LV_USE_FILESYSTEM\n/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/\n#endif\n\n/*1: Add a `user_data` to drivers and objects*/\n#ifndef LV_USE_USER_DATA\n#define LV_USE_USER_DATA        0\n#endif\n\n/*========================\n * Image decoder and cache\n *========================*/\n\n/* 1: Enable indexed (palette) images */\n#ifndef LV_IMG_CF_INDEXED\n#define LV_IMG_CF_INDEXED       1\n#endif\n\n/* 1: Enable alpha indexed images */\n#ifndef LV_IMG_CF_ALPHA\n#define LV_IMG_CF_ALPHA         1\n#endif\n\n/* Default image cache size. Image caching keeps the images opened.\n * If only the built-in image formats are used there is no real advantage of caching.\n * (I.e. no new image decoder is added)\n * With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images.\n * However the opened images might consume additional RAM.\n * LV_IMG_CACHE_DEF_SIZE must be >= 1 */\n#ifndef LV_IMG_CACHE_DEF_SIZE\n#define LV_IMG_CACHE_DEF_SIZE       1\n#endif\n\n/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/\n\n/*=====================\n *  Compiler settings\n *====================*/\n/* Define a custom attribute to `lv_tick_inc` function */\n#ifndef LV_ATTRIBUTE_TICK_INC\n#define LV_ATTRIBUTE_TICK_INC\n#endif\n\n/* Define a custom attribute to `lv_task_handler` function */\n#ifndef LV_ATTRIBUTE_TASK_HANDLER\n#define LV_ATTRIBUTE_TASK_HANDLER\n#endif\n\n/* With size optimization (-Os) the compiler might not align data to\n * 4 or 8 byte boundary. This alignment will be explicitly applied where needed.\n * E.g. __attribute__((aligned(4))) */\n#ifndef LV_ATTRIBUTE_MEM_ALIGN\n#define LV_ATTRIBUTE_MEM_ALIGN\n#endif\n\n/* Attribute to mark large constant arrays for example\n * font's bitmaps */\n#ifndef LV_ATTRIBUTE_LARGE_CONST\n#define LV_ATTRIBUTE_LARGE_CONST\n#endif\n\n/*===================\n *  HAL settings\n *==================*/\n\n/* 1: use a custom tick source.\n * It removes the need to manually update the tick with `lv_tick_inc`) */\n#ifndef LV_TICK_CUSTOM\n#define LV_TICK_CUSTOM     0\n#endif\n#if LV_TICK_CUSTOM == 1\n#ifndef LV_TICK_CUSTOM_INCLUDE\n#define LV_TICK_CUSTOM_INCLUDE  \"something.h\"       /*Header for the sys time function*/\n#endif\n#ifndef LV_TICK_CUSTOM_SYS_TIME_EXPR\n#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis())     /*Expression evaluating to current systime in ms*/\n#endif\n#endif   /*LV_TICK_CUSTOM*/\n\n\n/*================\n * Log settings\n *===============*/\n\n/*1: Enable the log module*/\n#ifndef LV_USE_LOG\n#define LV_USE_LOG      0\n#endif\n#if LV_USE_LOG\n/* How important log should be added:\n * LV_LOG_LEVEL_TRACE       A lot of logs to give detailed information\n * LV_LOG_LEVEL_INFO        Log important events\n * LV_LOG_LEVEL_WARN        Log if something unwanted happened but didn't cause a problem\n * LV_LOG_LEVEL_ERROR       Only critical issue, when the system may fail\n * LV_LOG_LEVEL_NONE        Do not log anything\n */\n#ifndef LV_LOG_LEVEL\n#  define LV_LOG_LEVEL    LV_LOG_LEVEL_WARN\n#endif\n\n/* 1: Print the log with 'printf';\n * 0: user need to register a callback with `lv_log_register_print`*/\n#ifndef LV_LOG_PRINTF\n#  define LV_LOG_PRINTF   0\n#endif\n#endif  /*LV_USE_LOG*/\n\n/*================\n *  THEME USAGE\n *================*/\n#ifndef LV_THEME_LIVE_UPDATE\n#define LV_THEME_LIVE_UPDATE    0   /*1: Allow theme switching at run time. Uses 8..10 kB of RAM*/\n#endif\n\n#ifndef LV_USE_THEME_TEMPL\n#define LV_USE_THEME_TEMPL      0   /*Just for test*/\n#endif\n#ifndef LV_USE_THEME_DEFAULT\n#define LV_USE_THEME_DEFAULT    0   /*Built mainly from the built-in styles. Consumes very few RAM*/\n#endif\n\n\n/*==================\n *    FONT USAGE\n *===================*/\n\n/* The built-in fonts contains the ASCII range and some Symbols with  4 bit-per-pixel.\n * The symbols are available via `LV_SYMBOL_...` defines\n * More info about fonts: https://docs.littlevgl.com/#Fonts\n * To create a new font go to: https://littlevgl.com/ttf-font-to-c-array\n */\n\n/* Robot fonts with bpp = 4\n * https://fonts.google.com/specimen/Roboto  */\n\n#ifndef LV_FONT_MONTSERRAT_12\n#define LV_FONT_MONTSERRAT_12    0\n#endif\n#ifndef LV_FONT_MA_20\n#define LV_FONT_MA_20    0\n#endif\n#ifndef LV_FONT_MA_20\n#define LV_FONT_MA_20    0\n#endif\n#ifndef LV_FONT_MA_30\n#define LV_FONT_MA_30    0\n#endif\n#ifndef LV_FONT_MA_80\n#define LV_FONT_MA_80    0\n#endif\n#ifndef LV_FONT_MA_110\n#define LV_FONT_MA_110    0\n#endif\n/*Pixel perfect monospace font\n * http://pelulamu.net/unscii/ */\n#ifndef LV_FONT_UNSCII_8\n#define LV_FONT_UNSCII_8     0\n#endif\n\n/* Optionally declare your custom fonts here.\n * You can use these fonts as default font too\n * and they will be available globally. E.g.\n * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \\\n *                                LV_FONT_DECLARE(my_font_2)\n */\n#ifndef LV_FONT_CUSTOM_DECLARE\n#define LV_FONT_CUSTOM_DECLARE\n#endif\n\n/*Always set a default font from the built-in fonts*/\n#ifndef LV_FONT_DEFAULT\n#define LV_FONT_DEFAULT        &lv_font_roboto_16\n#endif\n\n/* Enable it if you have fonts with a lot of characters.\n * The limit depends on the font size, font face and bpp\n * but with > 10,000 characters if you see issues probably you need to enable it.*/\n#ifndef LV_FONT_FMT_TXT_LARGE\n#define LV_FONT_FMT_TXT_LARGE   0\n#endif\n\n/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/\n\n/*=================\n *  Text settings\n *=================*/\n\n/* Select a character encoding for strings.\n * Your IDE or editor should have the same character encoding\n * - LV_TXT_ENC_UTF8\n * - LV_TXT_ENC_ASCII\n * */\n#ifndef LV_TXT_ENC\n#define LV_TXT_ENC LV_TXT_ENC_UTF8\n#endif\n\n /*Can break (wrap) texts on these chars*/\n#ifndef LV_TXT_BREAK_CHARS\n#define LV_TXT_BREAK_CHARS                  \" ,.;:-_\"\n#endif\n\n/*===================\n *  LV_OBJ SETTINGS\n *==================*/\n\n/*Declare the type of the user data of object (can be e.g. `void *`, `int`, `struct`)*/\n\n/*1: enable `lv_obj_realaign()` based on `lv_obj_align()` parameters*/\n#ifndef LV_USE_OBJ_REALIGN\n#define LV_USE_OBJ_REALIGN          1\n#endif\n\n/* Enable to make the object clickable on a larger area.\n * LV_EXT_CLICK_AREA_OFF or 0: Disable this feature\n * LV_EXT_CLICK_AREA_TINY: The extra area can be adjusted horizontally and vertically (0..255 px)\n * LV_EXT_CLICK_AREA_FULL: The extra area can be adjusted in all 4 directions (-32k..+32k px)\n */\n#ifndef LV_USE_EXT_CLICK_AREA\n#define LV_USE_EXT_CLICK_AREA  LV_EXT_CLICK_AREA_OFF\n#endif\n\n/*==================\n *  LV OBJ X USAGE\n *================*/\n/*\n * Documentation of the object types: https://docs.littlevgl.com/#Object-types\n */\n\n/*Arc (dependencies: -)*/\n#ifndef LV_USE_ARC\n#define LV_USE_ARC      1\n#endif\n\n/*Bar (dependencies: -)*/\n#ifndef LV_USE_BAR\n#define LV_USE_BAR      1\n#endif\n\n/*Button (dependencies: lv_cont*/\n#ifndef LV_USE_BTN\n#define LV_USE_BTN      1\n#endif\n#if LV_USE_BTN != 0\n/*Enable button-state animations - draw a circle on click (dependencies: LV_USE_ANIMATION)*/\n#ifndef LV_BTN_INK_EFFECT\n#  define LV_BTN_INK_EFFECT   0\n#endif\n#endif\n\n/*Button matrix (dependencies: -)*/\n#ifndef LV_USE_BTNM\n#define LV_USE_BTNM     1\n#endif\n\n/*Calendar (dependencies: -)*/\n#ifndef LV_USE_CALENDAR\n#define LV_USE_CALENDAR 1\n#endif\n\n/*Canvas (dependencies: lv_img)*/\n#ifndef LV_USE_CANVAS\n#define LV_USE_CANVAS   1\n#endif\n\n/*Check box (dependencies: lv_btn, lv_label)*/\n#ifndef LV_USE_CB\n#define LV_USE_CB       1\n#endif\n\n/*Chart (dependencies: -)*/\n#ifndef LV_USE_CHART\n#define LV_USE_CHART    1\n#endif\n#if LV_USE_CHART\n#ifndef LV_CHART_AXIS_TICK_LABEL_MAX_LEN\n#  define LV_CHART_AXIS_TICK_LABEL_MAX_LEN    20\n#endif\n#endif\n\n/*Container (dependencies: -*/\n#ifndef LV_USE_CONT\n#define LV_USE_CONT     1\n#endif\n\n/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/\n#ifndef LV_USE_DDLIST\n#define LV_USE_DDLIST    1\n#endif\n#if LV_USE_DDLIST != 0\n/*Open and close default animation time [ms] (0: no animation)*/\n#ifndef LV_DDLIST_DEF_ANIM_TIME\n#  define LV_DDLIST_DEF_ANIM_TIME     200\n#endif\n#endif\n\n/*Gauge (dependencies:lv_bar, lv_lmeter)*/\n#ifndef LV_USE_GAUGE\n#define LV_USE_GAUGE    1\n#endif\n\n/*Image (dependencies: lv_label*/\n#ifndef LV_USE_IMG\n#define LV_USE_IMG      1\n#endif\n\n/*Image Button (dependencies: lv_btn*/\n#ifndef LV_USE_IMGBTN\n#define LV_USE_IMGBTN   1\n#endif\n#if LV_USE_IMGBTN\n/*1: The imgbtn requires left, mid and right parts and the width can be set freely*/\n#ifndef LV_IMGBTN_TILED\n#  define LV_IMGBTN_TILED 0\n#endif\n#endif\n\n/*Keyboard (dependencies: lv_btnm)*/\n#ifndef LV_USE_KB\n#define LV_USE_KB       1\n#endif\n\n/*Label (dependencies: -*/\n#ifndef LV_USE_LABEL\n#define LV_USE_LABEL    1\n#endif\n#if LV_USE_LABEL != 0\n/*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_ROLL/ROLL_CIRC' mode*/\n#ifndef LV_LABEL_DEF_SCROLL_SPEED\n#  define LV_LABEL_DEF_SCROLL_SPEED       25\n#endif\n\n/* Waiting period at beginning/end of animation cycle */\n#ifndef LV_LABEL_WAIT_CHAR_COUNT\n#  define LV_LABEL_WAIT_CHAR_COUNT        3\n#endif\n\n/*Enable selecting text of the label */\n#ifndef LV_LABEL_TEXT_SEL\n#  define LV_LABEL_TEXT_SEL               0\n#endif\n\n/*Store extra some info in labels (12 bytes) to speed up drawing of very long texts*/\n#ifndef LV_LABEL_LONG_TXT_HINT\n#  define LV_LABEL_LONG_TXT_HINT          0\n#endif\n#endif\n\n/*LED (dependencies: -)*/\n#ifndef LV_USE_LED\n#define LV_USE_LED      1\n#endif\n\n/*Line (dependencies: -*/\n#ifndef LV_USE_LINE\n#define LV_USE_LINE     1\n#endif\n\n/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/\n#ifndef LV_USE_LIST\n#define LV_USE_LIST     1\n#endif\n#if LV_USE_LIST != 0\n/*Default animation time of focusing to a list element [ms] (0: no animation)  */\n#ifndef LV_LIST_DEF_ANIM_TIME\n#  define LV_LIST_DEF_ANIM_TIME  100\n#endif\n#endif\n\n/*Line meter (dependencies: *;)*/\n#ifndef LV_USE_LMETER\n#define LV_USE_LMETER   1\n#endif\n\n/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/\n#ifndef LV_USE_MBOX\n#define LV_USE_MBOX     1\n#endif\n\n/*Page (dependencies: lv_cont)*/\n#ifndef LV_USE_PAGE\n#define LV_USE_PAGE     1\n#endif\n#if LV_USE_PAGE != 0\n/*Focus default animation time [ms] (0: no animation)*/\n#ifndef LV_PAGE_DEF_ANIM_TIME\n#  define LV_PAGE_DEF_ANIM_TIME     400\n#endif\n#endif\n\n/*Preload (dependencies: lv_arc, lv_anim)*/\n#ifndef LV_USE_PRELOAD\n#define LV_USE_PRELOAD      1\n#endif\n#if LV_USE_PRELOAD != 0\n#ifndef LV_PRELOAD_DEF_ARC_LENGTH\n#  define LV_PRELOAD_DEF_ARC_LENGTH   60      /*[deg]*/\n#endif\n#ifndef LV_PRELOAD_DEF_SPIN_TIME\n#  define LV_PRELOAD_DEF_SPIN_TIME    1000    /*[ms]*/\n#endif\n#ifndef LV_PRELOAD_DEF_ANIM\n#  define LV_PRELOAD_DEF_ANIM         LV_PRELOAD_TYPE_SPINNING_ARC\n#endif\n#endif\n\n/*Roller (dependencies: lv_ddlist)*/\n#ifndef LV_USE_ROLLER\n#define LV_USE_ROLLER    1\n#endif\n#if LV_USE_ROLLER != 0\n/*Focus animation time [ms] (0: no animation)*/\n#ifndef LV_ROLLER_DEF_ANIM_TIME\n#  define LV_ROLLER_DEF_ANIM_TIME     200\n#endif\n\n/*Number of extra \"pages\" when the roller is infinite*/\n#ifndef LV_ROLLER_INF_PAGES\n#  define LV_ROLLER_INF_PAGES         7\n#endif\n#endif\n\n/*Slider (dependencies: lv_bar)*/\n#ifndef LV_USE_SLIDER\n#define LV_USE_SLIDER    1\n#endif\n\n/*Spinbox (dependencies: lv_ta)*/\n#ifndef LV_USE_SPINBOX\n#define LV_USE_SPINBOX       1\n#endif\n\n/*Switch (dependencies: lv_slider)*/\n#ifndef LV_USE_SW\n#define LV_USE_SW       1\n#endif\n\n/*Text area (dependencies: lv_label, lv_page)*/\n#ifndef LV_USE_TA\n#define LV_USE_TA       1\n#endif\n#if LV_USE_TA != 0\n#ifndef LV_TA_DEF_CURSOR_BLINK_TIME\n#  define LV_TA_DEF_CURSOR_BLINK_TIME 400     /*ms*/\n#endif\n#ifndef LV_TA_DEF_PWD_SHOW_TIME\n#  define LV_TA_DEF_PWD_SHOW_TIME     1500    /*ms*/\n#endif\n#endif\n\n/*Table (dependencies: lv_label)*/\n#ifndef LV_USE_TABLE\n#define LV_USE_TABLE    1\n#endif\n#if LV_USE_TABLE\n#ifndef LV_TABLE_COL_MAX\n#  define LV_TABLE_COL_MAX    12\n#endif\n#endif\n\n/*Tab (dependencies: lv_page, lv_btnm)*/\n#ifndef LV_USE_TABVIEW\n#define LV_USE_TABVIEW      1\n#endif\n#  if LV_USE_TABVIEW != 0\n/*Time of slide animation [ms] (0: no animation)*/\n#ifndef LV_TABVIEW_DEF_ANIM_TIME\n#  define LV_TABVIEW_DEF_ANIM_TIME    300\n#endif\n#endif\n\n/*Tileview (dependencies: lv_page) */\n#ifndef LV_USE_TILEVIEW\n#define LV_USE_TILEVIEW     1\n#endif\n#if LV_USE_TILEVIEW\n/*Time of slide animation [ms] (0: no animation)*/\n#ifndef LV_TILEVIEW_DEF_ANIM_TIME\n#  define LV_TILEVIEW_DEF_ANIM_TIME   300\n#endif\n#endif\n\n/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/\n#ifndef LV_USE_WIN\n#define LV_USE_WIN      1\n#endif\n\n/*==================\n * Non-user section\n *==================*/\n\n#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)    /* Disable warnings for Visual Studio*/\n#ifndef _CRT_SECURE_NO_WARNINGS\n#  define _CRT_SECURE_NO_WARNINGS\n#endif\n#endif\n\n\n#endif  /*LV_CONF_CHECKER_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_core/lv_core.mk",
    "content": "CSRCS += lv_group.c\nCSRCS += lv_indev.c\nCSRCS += lv_disp.c\nCSRCS += lv_obj.c\nCSRCS += lv_refr.c\nCSRCS += lv_style.c\n\nDEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_core\nVPATH += :$(LVGL_DIR)/lvgl/src/lv_core\n\nCFLAGS += \"-I$(LVGL_DIR)/lvgl/src/lv_core\"\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_core/lv_disp.h",
    "content": "/**\n * @file lv_disp.h\n *\n */\n\n#ifndef LV_DISP_H\n#define LV_DISP_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"../lv_hal/lv_hal.h\"\n#include \"lv_obj.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Return with a pointer to the active screen\n * @param disp pointer to display which active screen should be get. (NULL to use the default\n * screen)\n * @return pointer to the active screen object (loaded by 'lv_scr_load()')\n */\nlv_obj_t * lv_disp_get_scr_act(lv_disp_t * disp);\n\n/**\n * Make a screen active\n * @param scr pointer to a screen\n */\nvoid lv_disp_load_scr(lv_obj_t * scr);\n\n/**\n * Return with the top layer. (Same on every screen and it is above the normal screen layer)\n * @param disp pointer to display which top layer should be get. (NULL to use the default screen)\n * @return pointer to the top layer object  (transparent screen sized lv_obj)\n */\nlv_obj_t * lv_disp_get_layer_top(lv_disp_t * disp);\n\n/**\n * Return with the sys. layer. (Same on every screen and it is above the normal screen and the top\n * layer)\n * @param disp pointer to display which sys. layer  should be get. (NULL to use the default screen)\n * @return pointer to the sys layer object  (transparent screen sized lv_obj)\n */\nlv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp);\n\n/**\n * Assign a screen to a display.\n * @param disp pointer to a display where to assign the screen\n * @param scr pointer to a screen object to assign\n */\nvoid lv_disp_assign_screen(lv_disp_t * disp, lv_obj_t * scr);\n\n/**\n * Get a pointer to the screen refresher task to\n * modify its parameters with `lv_task_...` functions.\n * @param disp pointer to a display\n * @return pointer to the display refresher task. (NULL on error)\n */\nlv_task_t * lv_disp_get_refr_task(lv_disp_t * disp);\n\n/**\n * Get elapsed time since last user activity on a display (e.g. click)\n * @param disp pointer to an display (NULL to get the overall smallest inactivity)\n * @return elapsed ticks (milliseconds) since the last activity\n */\nuint32_t lv_disp_get_inactive_time(const lv_disp_t * disp);\n\n/**\n * Manually trigger an activity on a display\n * @param disp pointer to an display (NULL to use the default display)\n */\nvoid lv_disp_trig_activity(lv_disp_t * disp);\n\n/*------------------------------------------------\n * To improve backward compatibility\n * Recommended only if you have one display\n *------------------------------------------------*/\n\n/**\n * Get the active screen of the default display\n * @return pointer to the active screen\n */\nstatic inline lv_obj_t * lv_scr_act(void)\n{\n    return lv_disp_get_scr_act(lv_disp_get_default());\n}\n\n/**\n * Get the top layer  of the default display\n * @return pointer to the top layer\n */\nstatic inline lv_obj_t * lv_layer_top(void)\n{\n    return lv_disp_get_layer_top(lv_disp_get_default());\n}\n\n/**\n * Get the active screen of the deafult display\n * @return  pointer to the sys layer\n */\nstatic inline lv_obj_t * lv_layer_sys(void)\n{\n    return lv_disp_get_layer_sys(lv_disp_get_default());\n}\n\nstatic inline void lv_scr_load(lv_obj_t * scr)\n{\n    lv_disp_load_scr(scr);\n}\n\n/**********************\n *      MACROS\n **********************/\n\n/*------------------------------------------------\n * To improve backward compatibility\n * Recommended only if you have one display\n *------------------------------------------------*/\n\n#ifndef LV_HOR_RES\n/**\n * The horizontal resolution of the currently active display.\n */\n#define LV_HOR_RES lv_disp_get_hor_res(lv_disp_get_default())\n#endif\n\n#ifndef LV_VER_RES\n/**\n * The vertical resolution of the currently active display.\n */\n#define LV_VER_RES lv_disp_get_ver_res(lv_disp_get_default())\n#endif\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_TEMPL_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_core/lv_group.h",
    "content": "/**\n * @file lv_group.h\n *\n */\n\n#ifndef LV_GROUP_H\n#define LV_GROUP_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#include \"lv_obj.h\"\n\n/*********************\n *      DEFINES\n *********************/\n/*Predefined keys to control the focused object via lv_group_send(group, c)*/\n/*For compatibility in signal function define the keys regardless to `LV_USE_GROUP`*/\n\nenum {\n    LV_KEY_UP        = 17,  /*0x11*/\n    LV_KEY_DOWN      = 18,  /*0x12*/\n    LV_KEY_RIGHT     = 19,  /*0x13*/\n    LV_KEY_LEFT      = 20,  /*0x14*/\n    LV_KEY_ESC       = 27,  /*0x1B*/\n    LV_KEY_DEL       = 127, /*0x7F*/\n    LV_KEY_BACKSPACE = 8,   /*0x08*/\n    LV_KEY_ENTER     = 10,  /*0x0A, '\\n'*/\n    LV_KEY_NEXT      = 9,   /*0x09, '\\t'*/\n    LV_KEY_PREV      = 11,  /*0x0B, '*/\n    LV_KEY_HOME      = 2,   /*0x02, STX*/\n    LV_KEY_END       = 3,   /*0x03, ETX*/\n};\ntypedef uint8_t lv_key_t;\n\n#if LV_USE_GROUP != 0\n/**********************\n *      TYPEDEFS\n **********************/\nstruct _lv_group_t;\n\ntypedef void (*lv_group_style_mod_cb_t)(struct _lv_group_t *, lv_style_t *);\ntypedef void (*lv_group_focus_cb_t)(struct _lv_group_t *);\n\n/**\n * Groups can be used to logically hold objects so that they can be individually focused.\n * They are NOT for laying out objects on a screen (try `lv_cont` for that).\n */\ntypedef struct _lv_group_t\n{\n    lv_ll_t obj_ll;        /**< Linked list to store the objects in the group */\n    lv_obj_t ** obj_focus; /**< The object in focus*/\n\n    lv_group_style_mod_cb_t style_mod_cb;      /**< A function to modifies the style of the focused object*/\n    lv_group_style_mod_cb_t style_mod_edit_cb; /**< A function which modifies the style of the edited object*/\n    lv_group_focus_cb_t focus_cb;              /**< A function to call when a new object is focused (optional)*/\n    lv_style_t style_tmp;                      /**< Stores the modified style of the focused object */\n#if LV_USE_USER_DATA\n    lv_group_user_data_t user_data;\n#endif\n\n    uint8_t frozen : 1;         /**< 1: can't focus to new object*/\n    uint8_t editing : 1;        /**< 1: Edit mode, 0: Navigate mode*/\n    uint8_t click_focus : 1;    /**< 1: If an object in a group is clicked by an indev then it will be\n                                   focused */\n    uint8_t refocus_policy : 1; /**< 1: Focus prev if focused on deletion. 0: Focus next if focused on\n                                   deletion.*/\n    uint8_t wrap : 1;           /**< 1: Focus next/prev can wrap at end of list. 0: Focus next/prev stops at end\n                                   of list.*/\n} lv_group_t;\n\nenum { LV_GROUP_REFOCUS_POLICY_NEXT = 0, LV_GROUP_REFOCUS_POLICY_PREV = 1 };\ntypedef uint8_t lv_group_refocus_policy_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Init. the group module\n * @remarks Internal function, do not call directly.\n */\nvoid lv_group_init(void);\n\n/**\n * Create a new object group\n * @return pointer to the new object group\n */\nlv_group_t * lv_group_create(void);\n\n/**\n * Delete a group object\n * @param group pointer to a group\n */\nvoid lv_group_del(lv_group_t * group);\n\n/**\n * Add an object to a group\n * @param group pointer to a group\n * @param obj pointer to an object to add\n */\nvoid lv_group_add_obj(lv_group_t * group, lv_obj_t * obj);\n\n/**\n * Remove an object from its group\n * @param obj pointer to an object to remove\n */\nvoid lv_group_remove_obj(lv_obj_t * obj);\n\n/**\n * Remove all objects from a group\n * @param group pointer to a group\n */\nvoid lv_group_remove_all_objs(lv_group_t * group);\n\n/**\n * Focus on an object (defocus the current)\n * @param obj pointer to an object to focus on\n */\nvoid lv_group_focus_obj(lv_obj_t * obj);\n\n/**\n * Focus the next object in a group (defocus the current)\n * @param group pointer to a group\n */\nvoid lv_group_focus_next(lv_group_t * group);\n\n/**\n * Focus the previous object in a group (defocus the current)\n * @param group pointer to a group\n */\nvoid lv_group_focus_prev(lv_group_t * group);\n\n/**\n * Do not let to change the focus from the current object\n * @param group pointer to a group\n * @param en true: freeze, false: release freezing (normal mode)\n */\nvoid lv_group_focus_freeze(lv_group_t * group, bool en);\n\n/**\n * Send a control character to the focuses object of a group\n * @param group pointer to a group\n * @param c a character (use LV_KEY_.. to navigate)\n * @return result of focused object in group.\n */\nlv_res_t lv_group_send_data(lv_group_t * group, uint32_t c);\n\n/**\n * Set a function for a group which will modify the object's style if it is in focus\n * @param group pointer to a group\n * @param style_mod_cb the style modifier function pointer\n */\nvoid lv_group_set_style_mod_cb(lv_group_t * group, lv_group_style_mod_cb_t style_mod_cb);\n\n/**\n * Set a function for a group which will modify the object's style if it is in focus in edit mode\n * @param group pointer to a group\n * @param style_mod_edit_cb the style modifier function pointer\n */\nvoid lv_group_set_style_mod_edit_cb(lv_group_t * group, lv_group_style_mod_cb_t style_mod_edit_cb);\n\n/**\n * Set a function for a group which will be called when a new object is focused\n * @param group pointer to a group\n * @param focus_cb the call back function or NULL if unused\n */\nvoid lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb);\n\n/**\n * Set whether the next or previous item in a group is focused if the currently focussed obj is\n * deleted.\n * @param group pointer to a group\n * @param new refocus policy enum\n */\nvoid lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t policy);\n\n/**\n * Manually set the current mode (edit or navigate).\n * @param group pointer to group\n * @param edit: true: edit mode; false: navigate mode\n */\nvoid lv_group_set_editing(lv_group_t * group, bool edit);\n\n/**\n * Set the `click_focus` attribute. If enabled then the object will be focused then it is clicked.\n * @param group pointer to group\n * @param en: true: enable `click_focus`\n */\nvoid lv_group_set_click_focus(lv_group_t * group, bool en);\n\n/**\n * Set whether focus next/prev will allow wrapping from first->last or last->first object.\n * @param group pointer to group\n * @param en: true: wrapping enabled; false: wrapping disabled\n */\nvoid lv_group_set_wrap(lv_group_t * group, bool en);\n\n/**\n * Modify a style with the set 'style_mod' function. The input style remains unchanged.\n * @param group pointer to group\n * @param style pointer to a style to modify\n * @return a copy of the input style but modified with the 'style_mod' function\n */\nlv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style);\n\n/**\n * Get the focused object or NULL if there isn't one\n * @param group pointer to a group\n * @return pointer to the focused object\n */\nlv_obj_t * lv_group_get_focused(const lv_group_t * group);\n\n#if LV_USE_USER_DATA\n/**\n * Get a pointer to the group's user data\n * @param group pointer to an group\n * @return pointer to the user data\n */\nlv_group_user_data_t * lv_group_get_user_data(lv_group_t * group);\n\n#endif\n\n/**\n * Get a the style modifier function of a group\n * @param group pointer to a group\n * @return pointer to the style modifier function\n */\nlv_group_style_mod_cb_t lv_group_get_style_mod_cb(const lv_group_t * group);\n\n/**\n * Get a the style modifier function of a group in edit mode\n * @param group pointer to a group\n * @return pointer to the style modifier function\n */\nlv_group_style_mod_cb_t lv_group_get_style_mod_edit_cb(const lv_group_t * group);\n\n/**\n * Get the focus callback function of a group\n * @param group pointer to a group\n * @return the call back function or NULL if not set\n */\nlv_group_focus_cb_t lv_group_get_focus_cb(const lv_group_t * group);\n\n/**\n * Get the current mode (edit or navigate).\n * @param group pointer to group\n * @return true: edit mode; false: navigate mode\n */\nbool lv_group_get_editing(const lv_group_t * group);\n\n/**\n * Get the `click_focus` attribute.\n * @param group pointer to group\n * @return true: `click_focus` is enabled; false: disabled\n */\nbool lv_group_get_click_focus(const lv_group_t * group);\n\n/**\n * Get whether focus next/prev will allow wrapping from first->last or last->first object.\n * @param group pointer to group\n * @param en: true: wrapping enabled; false: wrapping disabled\n */\nbool lv_group_get_wrap(lv_group_t * group);\n\n/**\n * Notify the group that current theme changed and style modification callbacks need to be\n * refreshed.\n * @param group pointer to group. If NULL then all groups are notified.\n */\nvoid lv_group_report_style_mod(lv_group_t * group);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_GROUP != 0*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_GROUP_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_core/lv_indev.h",
    "content": "/**\n * @file lv_indev.h\n *\n */\n\n#ifndef LV_INDEV_H\n#define LV_INDEV_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"lv_obj.h\"\n#include \"../lv_hal/lv_hal_indev.h\"\n#include \"../lv_core/lv_group.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Initialize the display input device subsystem\n */\nvoid lv_indev_init(void);\n\n/**\n * Called periodically to read the input devices\n * @param task pointer to the task itself\n */\nvoid lv_indev_read_task(lv_task_t * task);\n\n/**\n * Get the currently processed input device. Can be used in action functions too.\n * @return pointer to the currently processed input device or NULL if no input device processing\n * right now\n */\nlv_indev_t * lv_indev_get_act(void);\n\n/**\n * Get the type of an input device\n * @param indev pointer to an input device\n * @return the type of the input device from `lv_hal_indev_type_t` (`LV_INDEV_TYPE_...`)\n */\nlv_indev_type_t lv_indev_get_type(const lv_indev_t * indev);\n\n/**\n * Reset one or all input devices\n * @param indev pointer to an input device to reset or NULL to reset all of them\n */\nvoid lv_indev_reset(lv_indev_t * indev);\n\n/**\n * Reset the long press state of an input device\n * @param indev_proc pointer to an input device\n */\nvoid lv_indev_reset_long_press(lv_indev_t * indev);\n\n/**\n * Enable or disable an input devices\n * @param indev pointer to an input device\n * @param en true: enable; false: disable\n */\nvoid lv_indev_enable(lv_indev_t * indev, bool en);\n\n/**\n * Set a cursor for a pointer input device (for LV_INPUT_TYPE_POINTER and LV_INPUT_TYPE_BUTTON)\n * @param indev pointer to an input device\n * @param cur_obj pointer to an object to be used as cursor\n */\nvoid lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj);\n\n#if LV_USE_GROUP\n/**\n * Set a destination group for a keypad input device (for LV_INDEV_TYPE_KEYPAD)\n * @param indev pointer to an input device\n * @param group point to a group\n */\nvoid lv_indev_set_group(lv_indev_t * indev, lv_group_t * group);\n#endif\n\n/**\n * Set the an array of points for LV_INDEV_TYPE_BUTTON.\n * These points will be assigned to the buttons to press a specific point on the screen\n * @param indev pointer to an input device\n * @param group point to a group\n */\nvoid lv_indev_set_button_points(lv_indev_t * indev, const lv_point_t * points);\n\n/**\n * Get the last point of an input device (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)\n * @param indev pointer to an input device\n * @param point pointer to a point to store the result\n */\nvoid lv_indev_get_point(const lv_indev_t * indev, lv_point_t * point);\n\n/**\n * Get the last pressed key of an input device (for LV_INDEV_TYPE_KEYPAD)\n * @param indev pointer to an input device\n * @return the last pressed key (0 on error)\n */\nuint32_t lv_indev_get_key(const lv_indev_t * indev);\n\n/**\n * Check if there is dragging with an input device or not (for LV_INDEV_TYPE_POINTER and\n * LV_INDEV_TYPE_BUTTON)\n * @param indev pointer to an input device\n * @return true: drag is in progress\n */\nbool lv_indev_is_dragging(const lv_indev_t * indev);\n\n/**\n * Get the vector of dragging of an input device (for LV_INDEV_TYPE_POINTER and\n * LV_INDEV_TYPE_BUTTON)\n * @param indev pointer to an input device\n * @param point pointer to a point to store the vector\n */\nvoid lv_indev_get_vect(const lv_indev_t * indev, lv_point_t * point);\n\n/**\n * Do nothing until the next release\n * @param indev pointer to an input device\n */\nvoid lv_indev_wait_release(lv_indev_t * indev);\n\n/**\n * Get a pointer to the indev read task to\n * modify its parameters with `lv_task_...` functions.\n * @param indev pointer to an inout device\n * @return pointer to the indev read refresher task. (NULL on error)\n */\nlv_task_t * lv_indev_get_read_task(lv_disp_t * indev);\n\n/**\n * Gets a pointer to the currently active object in indev proc functions.\n * NULL if no object is currently being handled or if groups aren't used.\n * @return pointer to currently active object\n */\nlv_obj_t * lv_indev_get_obj_act(void);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_INDEV_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_core/lv_obj.h",
    "content": "/**\n * @file lv_obj.h\n *\n */\n\n#ifndef LV_OBJ_H\n#define LV_OBJ_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#include <stddef.h>\n#include \"utils/types.h\"\n#include \"lv_style.h\"\n#include \"../lv_misc/lv_types.h\"\n#include \"../lv_misc/lv_area.h\"\n#include \"../lv_misc/lv_mem.h\"\n#include \"../lv_misc/lv_ll.h\"\n#include \"../lv_misc/lv_color.h\"\n#include \"../lv_misc/lv_log.h\"\n#include \"../lv_hal/lv_hal.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/*Error check of lv_conf.h*/\n#if LV_HOR_RES_MAX == 0 || LV_VER_RES_MAX == 0\n#error \"LittlevGL: LV_HOR_RES_MAX and LV_VER_RES_MAX must be greater than 0\"\n#endif\n\n#if LV_ANTIALIAS > 1\n#error \"LittlevGL: LV_ANTIALIAS can be only 0 or 1\"\n#endif\n\n#define LV_MAX_ANCESTOR_NUM 8\n\n#define LV_EXT_CLICK_AREA_OFF 0\n#define LV_EXT_CLICK_AREA_TINY 1\n#define LV_EXT_CLICK_AREA_FULL 2\n\n/**********************\n *      TYPEDEFS\n **********************/\n\nstruct _lv_obj_t;\n\n\n/** Design modes */\nenum {\n    LV_DESIGN_DRAW_MAIN, /**< Draw the main portion of the object */\n    LV_DESIGN_DRAW_POST, /**< Draw extras on the object */\n    LV_DESIGN_COVER_CHK, /**< Check if the object fully covers the 'mask_p' area */\n};\ntypedef uint8_t lv_design_mode_t;\n\n/**\n * The design callback is used to draw the object on the screen.\n * It accepts the object, a mask area, and the mode in which to draw the object.\n */\ntypedef bool (*lv_design_cb_t)(struct _lv_obj_t * obj, const lv_area_t * mask_p, lv_design_mode_t mode);\n\nenum {\n    LV_EVENT_PRESSED,             /**< The object has been pressed*/\n    LV_EVENT_PRESSING,            /**< The object is being pressed (called continuously while pressing)*/\n    LV_EVENT_PRESS_LOST,          /**< User is still pressing but slid cursor/finger off of the object */\n    LV_EVENT_SHORT_CLICKED,       /**< User pressed object for a short period of time, then released it. Not called if dragged. */\n    LV_EVENT_LONG_PRESSED,        /**< Object has been pressed for at least `LV_INDEV_LONG_PRESS_TIME`.  Not called if dragged.*/\n    LV_EVENT_LONG_PRESSED_REPEAT, /**< Called after `LV_INDEV_LONG_PRESS_TIME` in every\n                                       `LV_INDEV_LONG_PRESS_REP_TIME` ms.  Not called if dragged.*/\n    LV_EVENT_CLICKED,             /**< Called on release if not dragged (regardless to long press)*/\n    LV_EVENT_RELEASED,            /**< Called in every cases when the object has been released*/                                    \n    LV_EVENT_DRAG_BEGIN,\t\t  \n    LV_EVENT_DRAG_END,\n    LV_EVENT_DRAG_THROW_BEGIN,\n    LV_EVENT_KEY,\n    LV_EVENT_FOCUSED,\n    LV_EVENT_DEFOCUSED,\n    LV_EVENT_VALUE_CHANGED,\t\t /**< The object's value has changed (i.e. slider moved) */\n    LV_EVENT_INSERT,\n    LV_EVENT_REFRESH,\n    LV_EVENT_APPLY,  /**< \"Ok\", \"Apply\" or similar specific button has clicked*/\n    LV_EVENT_CANCEL, /**< \"Close\", \"Cancel\" or similar specific button has clicked*/\n    LV_EVENT_DELETE, /**< Object is being deleted */\n};\ntypedef uint8_t lv_event_t; /**< Type of event being sent to the object. */\n\n/**\n * @brief Event callback.\n * Events are used to notify the user of some action being taken on the object.\n * For details, see ::lv_event_t.\n */\ntypedef void (*lv_event_cb_t)(struct _lv_obj_t * obj, lv_event_t event);\n\n/** Signals are for use by the object itself or to extend the object's functionality.\n  * Applications should use ::lv_obj_set_event_cb to be notified of events that occur\n  * on the object. */\nenum {\n    /*General signals*/\n    LV_SIGNAL_CLEANUP, /**< Object is being deleted */\n    LV_SIGNAL_CHILD_CHG, /**< Child was removed/added */\n    LV_SIGNAL_CORD_CHG, /**< Object coordinates/size have changed */\n    LV_SIGNAL_PARENT_SIZE_CHG, /**< Parent's size has changed */\n    LV_SIGNAL_STYLE_CHG, /**< Object's style has changed */\n    LV_SIGNAL_REFR_EXT_DRAW_PAD, /**< Object's extra padding has changed */\n    LV_SIGNAL_GET_TYPE, /**< LittlevGL needs to retrieve the object's type */\n\n    /*Input device related*/\n    LV_SIGNAL_PRESSED,           /**< The object has been pressed*/\n    LV_SIGNAL_PRESSING,          /**< The object is being pressed (called continuously while pressing)*/\n    LV_SIGNAL_PRESS_LOST,        /**< User is still pressing but slid cursor/finger off of the object */\n    LV_SIGNAL_RELEASED,          /**< User pressed object for a short period of time, then released it. Not called if dragged. */\n    LV_SIGNAL_LONG_PRESS,        /**< Object has been pressed for at least `LV_INDEV_LONG_PRESS_TIME`.  Not called if dragged.*/\n    LV_SIGNAL_LONG_PRESS_REP,    /**< Called after `LV_INDEV_LONG_PRESS_TIME` in every `LV_INDEV_LONG_PRESS_REP_TIME` ms.  Not called if dragged.*/\n    LV_SIGNAL_DRAG_BEGIN,\t\n    LV_SIGNAL_DRAG_END,                                   \n    /*Group related*/\n    LV_SIGNAL_FOCUS,\n    LV_SIGNAL_DEFOCUS,\n    LV_SIGNAL_CONTROL,\n    LV_SIGNAL_GET_EDITABLE,\n};\ntypedef uint8_t lv_signal_t;\n\ntypedef lv_res_t (*lv_signal_cb_t)(struct _lv_obj_t * obj, lv_signal_t sign, void * param);\n\n/** Object alignment. */\nenum {\n    LV_ALIGN_CENTER = 0,\n    LV_ALIGN_IN_TOP_LEFT,\n    LV_ALIGN_IN_TOP_MID,\n    LV_ALIGN_IN_TOP_RIGHT,\n    LV_ALIGN_IN_BOTTOM_LEFT,\n    LV_ALIGN_IN_BOTTOM_MID,\n    LV_ALIGN_IN_BOTTOM_RIGHT,\n    LV_ALIGN_IN_LEFT_MID,\n    LV_ALIGN_IN_RIGHT_MID,\n    LV_ALIGN_OUT_TOP_LEFT,\n    LV_ALIGN_OUT_TOP_MID,\n    LV_ALIGN_OUT_TOP_RIGHT,\n    LV_ALIGN_OUT_BOTTOM_LEFT,\n    LV_ALIGN_OUT_BOTTOM_MID,\n    LV_ALIGN_OUT_BOTTOM_RIGHT,\n    LV_ALIGN_OUT_LEFT_TOP,\n    LV_ALIGN_OUT_LEFT_MID,\n    LV_ALIGN_OUT_LEFT_BOTTOM,\n    LV_ALIGN_OUT_RIGHT_TOP,\n    LV_ALIGN_OUT_RIGHT_MID,\n    LV_ALIGN_OUT_RIGHT_BOTTOM,\n};\ntypedef uint8_t lv_align_t;\n\n#if LV_USE_OBJ_REALIGN\ntypedef struct\n{\n    const struct _lv_obj_t * base;\n    lv_coord_t xofs;\n    lv_coord_t yofs;\n    lv_align_t align;\n    uint8_t auto_realign : 1;\n    uint8_t origo_align : 1; /**< 1: the origo (center of the object) was aligned with\n                                `lv_obj_align_origo`*/\n} lv_reailgn_t;\n#endif\n\nenum {\n    LV_DRAG_DIR_HOR = 0x1, /**< Object can be dragged horizontally. */\n    LV_DRAG_DIR_VER = 0x2, /**< Object can be dragged vertically. */\n    LV_DRAG_DIR_ALL = 0x3, /**< Object can be dragged in all directions. */\n};\n\ntypedef uint8_t lv_drag_dir_t;\n\ntypedef struct _lv_obj_t\n{\n    struct _lv_obj_t * par; /**< Pointer to the parent object*/\n    lv_ll_t child_ll;       /**< Linked list to store the children objects*/\n\n    lv_area_t coords; /**< Coordinates of the object (x1, y1, x2, y2)*/\n\n    lv_event_cb_t event_cb; /**< Event callback function */\n    lv_signal_cb_t signal_cb; /**< Object type specific signal function*/\n    lv_design_cb_t design_cb; /**< Object type specific design function*/\n\n    void * ext_attr;            /**< Object type specific extended data*/\n    const lv_style_t * style_p; /**< Pointer to the object's style*/\n\n#if LV_USE_GROUP != 0\n    void * group_p; /**< Pointer to the group of the object*/\n#endif\n\n#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY\n    uint8_t ext_click_pad_hor; /**< Extra click padding in horizontal direction */\n    uint8_t ext_click_pad_ver; /**< Extra click padding in vertical direction */\n#endif\n\n#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL\n    lv_area_t ext_click_pad;   /**< Extra click padding area. */\n#endif\n\n    /*Attributes and states*/\n    uint8_t click : 1;          /**< 1: Can be pressed by an input device*/\n    uint8_t drag : 1;           /**< 1: Enable the dragging*/\n    uint8_t drag_throw : 1;     /**< 1: Enable throwing with drag*/\n    uint8_t drag_parent : 1;    /**< 1: Parent will be dragged instead*/\n    uint8_t hidden : 1;         /**< 1: Object is hidden*/\n    uint8_t top : 1;            /**< 1: If the object or its children is clicked it goes to the foreground*/\n    uint8_t opa_scale_en : 1;   /**< 1: opa_scale is set*/\n    uint8_t parent_event : 1;   /**< 1: Send the object's events to the parent too. */\n    lv_drag_dir_t drag_dir : 2; /**<  Which directions the object can be dragged in */\n    uint8_t reserved : 6;       /**<  Reserved for future use*/\n    uint8_t protect;            /**< Automatically happening actions can be prevented. 'OR'ed values from\n                                   `lv_protect_t`*/\n    lv_opa_t opa_scale;         /**< Scale down the opacity by this factor. Effects all children as well*/\n\n    lv_coord_t ext_draw_pad; /**< EXTtend the size in every direction for drawing. */\n\n#if LV_USE_OBJ_REALIGN\n    lv_reailgn_t realign;       /**< Information about the last call to ::lv_obj_align. */\n#endif\n\n#if LV_USE_USER_DATA\n    lv_obj_user_data_t user_data; /**< Custom user data for object. */\n#endif\n\n} lv_obj_t;\n\n/*Protect some attributes (max. 8 bit)*/\nenum {\n    LV_PROTECT_NONE      = 0x00,\n    LV_PROTECT_CHILD_CHG = 0x01,   /**< Disable the child change signal. Used by the library*/\n    LV_PROTECT_PARENT    = 0x02,   /**< Prevent automatic parent change (e.g. in lv_page)*/\n    LV_PROTECT_POS       = 0x04,   /**< Prevent automatic positioning (e.g. in lv_cont layout)*/\n    LV_PROTECT_FOLLOW    = 0x08,   /**< Prevent the object be followed in automatic ordering (e.g. in\n                                      lv_cont PRETTY layout)*/\n    LV_PROTECT_PRESS_LOST = 0x10,  /**< If the `indev` was pressing this object but swiped out while\n                                      pressing do not search other object.*/\n    LV_PROTECT_CLICK_FOCUS = 0x20, /**< Prevent focusing the object by clicking on it*/\n};\ntypedef uint8_t lv_protect_t;\n\n/** Used by `lv_obj_get_type()`. The object's and its ancestor types are stored here*/\ntypedef struct\n{\n    const char * type[LV_MAX_ANCESTOR_NUM]; /**< [0]: the actual type, [1]: ancestor, [2] #1's ancestor\n                                               ... [x]: \"lv_obj\" */\n} lv_obj_type_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Init. the 'lv' library.\n */\nvoid lv_init(void);\n\n/*--------------------\n * Create and delete\n *-------------------*/\n\n/**\n * Create a basic object\n * @param parent pointer to a parent object.\n *                  If NULL then a screen will be created\n * @param copy pointer to a base object, if not NULL then the new object will be copied from it\n * @return pointer to the new object\n */\nlv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy);\n\n/**\n * Delete 'obj' and all of its children\n * @param obj pointer to an object to delete\n * @return LV_RES_INV because the object is deleted\n */\nlv_res_t lv_obj_del(lv_obj_t * obj);\n\n/**\n * Helper function for asynchronously deleting objects.\n * Useful for cases where you can't delete an object directly in an `LV_EVENT_DELETE` handler (i.e. parent).\n * @param obj object to delete\n * @see lv_async_call\n */\nvoid lv_obj_del_async(struct _lv_obj_t *obj);\n\n/**\n * Delete all children of an object\n * @param obj pointer to an object\n */\nvoid lv_obj_clean(lv_obj_t * obj);\n\n/**\n * Mark the object as invalid therefore its current position will be redrawn by 'lv_refr_task'\n * @param obj pointer to an object\n */\nvoid lv_obj_invalidate(const lv_obj_t * obj);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/*--------------------\n * Parent/children set\n *--------------------*/\n\n/**\n * Set a new parent for an object. Its relative position will be the same.\n * @param obj pointer to an object. Can't be a screen.\n * @param parent pointer to the new parent object. (Can't be NULL)\n */\nvoid lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent);\n\n/**\n * Move and object to the foreground\n * @param obj pointer to an object\n */\nvoid lv_obj_move_foreground(lv_obj_t * obj);\n\n/**\n * Move and object to the background\n * @param obj pointer to an object\n */\nvoid lv_obj_move_background(lv_obj_t * obj);\n\n/*--------------------\n * Coordinate set\n * ------------------*/\n\n/**\n * Set relative the position of an object (relative to the parent)\n * @param obj pointer to an object\n * @param x new distance from the left side of the parent\n * @param y new distance from the top of the parent\n */\nvoid lv_obj_set_pos(lv_obj_t * obj, lv_coord_t x, lv_coord_t y);\n\n/**\n * Set the x coordinate of a object\n * @param obj pointer to an object\n * @param x new distance from the left side from the parent\n */\nvoid lv_obj_set_x(lv_obj_t * obj, lv_coord_t x);\n\n/**\n * Set the y coordinate of a object\n * @param obj pointer to an object\n * @param y new distance from the top of the parent\n */\nvoid lv_obj_set_y(lv_obj_t * obj, lv_coord_t y);\n\n/**\n * Set the size of an object\n * @param obj pointer to an object\n * @param w new width\n * @param h new height\n */\nvoid lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h);\n\n/**\n * Set the width of an object\n * @param obj pointer to an object\n * @param w new width\n */\nvoid lv_obj_set_width(lv_obj_t * obj, lv_coord_t w);\n\n/**\n * Set the height of an object\n * @param obj pointer to an object\n * @param h new height\n */\nvoid lv_obj_set_height(lv_obj_t * obj, lv_coord_t h);\n\n/**\n * Align an object to an other object.\n * @param obj pointer to an object to align\n * @param base pointer to an object (if NULL the parent is used). 'obj' will be aligned to it.\n * @param align type of alignment (see 'lv_align_t' enum)\n * @param x_mod x coordinate shift after alignment\n * @param y_mod y coordinate shift after alignment\n */\nvoid lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_mod, lv_coord_t y_mod);\n\n/**\n * Align an object to an other object.\n * @param obj pointer to an object to align\n * @param base pointer to an object (if NULL the parent is used). 'obj' will be aligned to it.\n * @param align type of alignment (see 'lv_align_t' enum)\n * @param x_mod x coordinate shift after alignment\n * @param y_mod y coordinate shift after alignment\n */\nvoid lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_mod, lv_coord_t y_mod);\n\n/**\n * Realign the object based on the last `lv_obj_align` parameters.\n * @param obj pointer to an object\n */\nvoid lv_obj_realign(lv_obj_t * obj);\n\n/**\n * Enable the automatic realign of the object when its size has changed based on the last\n * `lv_obj_align` parameters.\n * @param obj pointer to an object\n * @param en true: enable auto realign; false: disable auto realign\n */\nvoid lv_obj_set_auto_realign(lv_obj_t * obj, bool en);\n\n/**\n * Set the size of an extended clickable area\n * @param obj pointer to an object\n * @param left extended clickable are on the left [px]\n * @param right extended clickable are on the right [px]\n * @param top extended clickable are on the top [px]\n * @param bottom extended clickable are on the bottom [px]\n */\nvoid lv_obj_set_ext_click_area(lv_obj_t * obj, lv_coord_t left, lv_coord_t right, lv_coord_t top, lv_coord_t bottom);\n\n/*---------------------\n * Appearance set\n *--------------------*/\n\n/**\n * Set a new style for an object\n * @param obj pointer to an object\n * @param style_p pointer to the new style\n */\nvoid lv_obj_set_style(lv_obj_t * obj, const lv_style_t * style);\n\n/**\n * Notify an object about its style is modified\n * @param obj pointer to an object\n */\nvoid lv_obj_refresh_style(lv_obj_t * obj);\n\n/**\n * Notify all object if a style is modified\n * @param style pointer to a style. Only the objects with this style will be notified\n *               (NULL to notify all objects)\n */\nvoid lv_obj_report_style_mod(lv_style_t * style);\n\n/*-----------------\n * Attribute set\n *----------------*/\n\n/**\n * Hide an object. It won't be visible and clickable.\n * @param obj pointer to an object\n * @param en true: hide the object\n */\nvoid lv_obj_set_hidden(lv_obj_t * obj, bool en);\n\n/**\n * Enable or disable the clicking of an object\n * @param obj pointer to an object\n * @param en true: make the object clickable\n */\nvoid lv_obj_set_click(lv_obj_t * obj, bool en);\n\n/**\n * Enable to bring this object to the foreground if it\n * or any of its children is clicked\n * @param obj pointer to an object\n * @param en true: enable the auto top feature\n */\nvoid lv_obj_set_top(lv_obj_t * obj, bool en);\n\n/**\n * Enable the dragging of an object\n * @param obj pointer to an object\n * @param en true: make the object dragable\n */\nvoid lv_obj_set_drag(lv_obj_t * obj, bool en);\n\n/**\n * Set the directions an object can be dragged in\n * @param obj pointer to an object\n * @param drag_dir bitwise OR of allowed drag directions\n */\nvoid lv_obj_set_drag_dir(lv_obj_t * obj, lv_drag_dir_t drag_dir);\n\n/**\n * Enable the throwing of an object after is is dragged\n * @param obj pointer to an object\n * @param en true: enable the drag throw\n */\nvoid lv_obj_set_drag_throw(lv_obj_t * obj, bool en);\n\n/**\n * Enable to use parent for drag related operations.\n * If trying to drag the object the parent will be moved instead\n * @param obj pointer to an object\n * @param en true: enable the 'drag parent' for the object\n */\nvoid lv_obj_set_drag_parent(lv_obj_t * obj, bool en);\n\n/**\n * Propagate the events to the parent too\n * @param obj pointer to an object\n * @param en true: enable the event propagation\n */\nvoid lv_obj_set_parent_event(lv_obj_t * obj, bool en);\n\n/**\n * Set the opa scale enable parameter (required to set opa_scale with `lv_obj_set_opa_scale()`)\n * @param obj pointer to an object\n * @param en true: opa scaling is enabled for this object and all children; false: no opa scaling\n */\nvoid lv_obj_set_opa_scale_enable(lv_obj_t * obj, bool en);\n\n/**\n * Set the opa scale of an object.\n * The opacity of this object and all it's children will be scaled down with this factor.\n * `lv_obj_set_opa_scale_enable(obj, true)` needs to be called to enable it.\n * (not for all children just for the parent where to start the opa scaling)\n * @param obj pointer to an object\n * @param opa_scale a factor to scale down opacity [0..255]\n */\nvoid lv_obj_set_opa_scale(lv_obj_t * obj, lv_opa_t opa_scale);\n\n/**\n * Set a bit or bits in the protect filed\n * @param obj pointer to an object\n * @param prot 'OR'-ed values from `lv_protect_t`\n */\nvoid lv_obj_set_protect(lv_obj_t * obj, uint8_t prot);\n\n/**\n * Clear a bit or bits in the protect filed\n * @param obj pointer to an object\n * @param prot 'OR'-ed values from `lv_protect_t`\n */\nvoid lv_obj_clear_protect(lv_obj_t * obj, uint8_t prot);\n\n/**\n * Set a an event handler function for an object.\n * Used by the user to react on event which happens with the object.\n * @param obj pointer to an object\n * @param event_cb the new event function\n */\nvoid lv_obj_set_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb);\n\n/**\n * Send an event to the object\n * @param obj pointer to an object\n * @param event the type of the event from `lv_event_t`.\n * @param data arbitrary data depending on the object type and the event. (Usually `NULL`)\n * @return LV_RES_OK: `obj` was not deleted in the event; LV_RES_INV: `obj` was deleted in the event\n */\nlv_res_t lv_event_send(lv_obj_t * obj, lv_event_t event, const void * data);\n\n/**\n * Call an event function with an object, event, and data.\n * @param event_xcb an event callback function. If `NULL` `LV_RES_OK` will return without any actions.\n *        (the 'x' in the argument name indicates that its not a fully generic function because it not follows\n *         the `func_name(object, callback, ...)` convention)\n * @param obj pointer to an object to associate with the event (can be `NULL` to simply call the `event_cb`)\n * @param event an event\n * @param data pointer to a custom data\n * @return LV_RES_OK: `obj` was not deleted in the event; LV_RES_INV: `obj` was deleted in the event\n */\nlv_res_t lv_event_send_func(lv_event_cb_t event_xcb, lv_obj_t * obj, lv_event_t event, const void * data);\n\n/**\n * Get the `data` parameter of the current event\n * @return the `data` parameter\n */\nconst void * lv_event_get_data(void);\n\n/**\n * Set the a signal function of an object. Used internally by the library.\n * Always call the previous signal function in the new.\n * @param obj pointer to an object\n * @param signal_cb the new signal function\n */\nvoid lv_obj_set_signal_cb(lv_obj_t * obj, lv_signal_cb_t signal_cb);\n\n/**\n * Send an event to the object\n * @param obj pointer to an object\n * @param event the type of the event from `lv_event_t`.\n */\nvoid lv_signal_send(lv_obj_t * obj, lv_signal_t signal, void * param);\n\n/**\n * Set a new design function for an object\n * @param obj pointer to an object\n * @param design_cb the new design function\n */\nvoid lv_obj_set_design_cb(lv_obj_t * obj, lv_design_cb_t design_cb);\n\n/*----------------\n * Other set\n *--------------*/\n\n/**\n * Allocate a new ext. data for an object\n * @param obj pointer to an object\n * @param ext_size the size of the new ext. data\n * @return pointer to the allocated ext\n */\nvoid * lv_obj_allocate_ext_attr(lv_obj_t * obj, uint16_t ext_size);\n\n/**\n * Send a 'LV_SIGNAL_REFR_EXT_SIZE' signal to the object\n * @param obj pointer to an object\n */\nvoid lv_obj_refresh_ext_draw_pad(lv_obj_t * obj);\n\n/*=======================\n * Getter functions\n *======================*/\n\n/**\n * Return with the screen of an object\n * @param obj pointer to an object\n * @return pointer to a screen\n */\nlv_obj_t * lv_obj_get_screen(const lv_obj_t * obj);\n\n/**\n * Get the display of an object\n * @param scr pointer to an object\n * @return pointer the object's display\n */\nlv_disp_t * lv_obj_get_disp(const lv_obj_t * obj);\n\n/*---------------------\n * Parent/children get\n *--------------------*/\n\n/**\n * Returns with the parent of an object\n * @param obj pointer to an object\n * @return pointer to the parent of  'obj'\n */\nlv_obj_t * lv_obj_get_parent(const lv_obj_t * obj);\n\n/**\n * Iterate through the children of an object (start from the \"youngest, lastly created\")\n * @param obj pointer to an object\n * @param child NULL at first call to get the next children\n *                  and the previous return value later\n * @return the child after 'act_child' or NULL if no more child\n */\nlv_obj_t * lv_obj_get_child(const lv_obj_t * obj, const lv_obj_t * child);\n\n/**\n * Iterate through the children of an object (start from the \"oldest\", firstly created)\n * @param obj pointer to an object\n * @param child NULL at first call to get the next children\n *                  and the previous return value later\n * @return the child after 'act_child' or NULL if no more child\n */\nlv_obj_t * lv_obj_get_child_back(const lv_obj_t * obj, const lv_obj_t * child);\n\n/**\n * Count the children of an object (only children directly on 'obj')\n * @param obj pointer to an object\n * @return children number of 'obj'\n */\nuint16_t lv_obj_count_children(const lv_obj_t * obj);\n\n/** Recursively count the children of an object\n * @param obj pointer to an object\n * @return children number of 'obj'\n */\nuint16_t lv_obj_count_children_recursive(const lv_obj_t * obj);\n\n/*---------------------\n * Coordinate get\n *--------------------*/\n\n/**\n * Copy the coordinates of an object to an area\n * @param obj pointer to an object\n * @param cords_p pointer to an area to store the coordinates\n */\nvoid lv_obj_get_coords(const lv_obj_t * obj, lv_area_t * cords_p);\n\n/**\n * Reduce area retried by `lv_obj_get_coords()` the get graphically usable area of an object.\n * (Without the size of the border or other extra graphical elements)\n * @param coords_p store the result area here\n */\nvoid lv_obj_get_inner_coords(const lv_obj_t * obj, lv_area_t * coords_p);\n\n/**\n * Get the x coordinate of object\n * @param obj pointer to an object\n * @return distance of 'obj' from the left side of its parent\n */\nlv_coord_t lv_obj_get_x(const lv_obj_t * obj);\n\n/**\n * Get the y coordinate of object\n * @param obj pointer to an object\n * @return distance of 'obj' from the top of its parent\n */\nlv_coord_t lv_obj_get_y(const lv_obj_t * obj);\n\n/**\n * Get the width of an object\n * @param obj pointer to an object\n * @return the width\n */\nlv_coord_t lv_obj_get_width(const lv_obj_t * obj);\n\n/**\n * Get the height of an object\n * @param obj pointer to an object\n * @return the height\n */\nlv_coord_t lv_obj_get_height(const lv_obj_t * obj);\n\n/**\n * Get that width reduced by the left and right padding.\n * @param obj pointer to an object\n * @return the width which still fits into the container\n */\nlv_coord_t lv_obj_get_width_fit(lv_obj_t * obj);\n\n/**\n * Get that height reduced by the top an bottom padding.\n * @param obj pointer to an object\n * @return the height which still fits into the container\n */\nlv_coord_t lv_obj_get_height_fit(lv_obj_t * obj);\n\n/**\n * Get the automatic realign property of the object.\n * @param obj pointer to an object\n * @return  true: auto realign is enabled; false: auto realign is disabled\n */\nbool lv_obj_get_auto_realign(lv_obj_t * obj);\n\n/**\n * Get the left padding of extended clickable area\n * @param obj pointer to an object\n * @return the extended left padding\n */\nlv_coord_t lv_obj_get_ext_click_pad_left(const lv_obj_t * obj);\n\n/**\n * Get the right padding of extended clickable area\n * @param obj pointer to an object\n * @return the extended right padding\n */\nlv_coord_t lv_obj_get_ext_click_pad_right(const lv_obj_t * obj);\n\n/**\n * Get the top padding of extended clickable area\n * @param obj pointer to an object\n * @return the extended top padding\n */\nlv_coord_t lv_obj_get_ext_click_pad_top(const lv_obj_t * obj);\n\n/**\n * Get the bottom padding of extended clickable area\n * @param obj pointer to an object\n * @return the extended bottom padding\n */\nlv_coord_t lv_obj_get_ext_click_pad_bottom(const lv_obj_t * obj);\n\n/**\n * Get the extended size attribute of an object\n * @param obj pointer to an object\n * @return the extended size attribute\n */\nlv_coord_t lv_obj_get_ext_draw_pad(const lv_obj_t * obj);\n\n/*-----------------\n * Appearance get\n *---------------*/\n\n/**\n * Get the style pointer of an object (if NULL get style of the parent)\n * @param obj pointer to an object\n * @return pointer to a style\n */\nconst lv_style_t * lv_obj_get_style(const lv_obj_t * obj);\n\n/*-----------------\n * Attribute get\n *----------------*/\n\n/**\n * Get the hidden attribute of an object\n * @param obj pointer to an object\n * @return true: the object is hidden\n */\nbool lv_obj_get_hidden(const lv_obj_t * obj);\n\n/**\n * Get the click enable attribute of an object\n * @param obj pointer to an object\n * @return true: the object is clickable\n */\nbool lv_obj_get_click(const lv_obj_t * obj);\n\n/**\n * Get the top enable attribute of an object\n * @param obj pointer to an object\n * @return true: the auto top feature is enabled\n */\nbool lv_obj_get_top(const lv_obj_t * obj);\n\n/**\n * Get the drag enable attribute of an object\n * @param obj pointer to an object\n * @return true: the object is dragable\n */\nbool lv_obj_get_drag(const lv_obj_t * obj);\n\n/**\n * Get the directions an object can be dragged\n * @param obj pointer to an object\n * @return bitwise OR of allowed directions an object can be dragged in\n */\nlv_drag_dir_t lv_obj_get_drag_dir(const lv_obj_t * obj);\n\n/**\n * Get the drag throw enable attribute of an object\n * @param obj pointer to an object\n * @return true: drag throw is enabled\n */\nbool lv_obj_get_drag_throw(const lv_obj_t * obj);\n\n/**\n * Get the drag parent attribute of an object\n * @param obj pointer to an object\n * @return true: drag parent is enabled\n */\nbool lv_obj_get_drag_parent(const lv_obj_t * obj);\n\n/**\n * Get the drag parent attribute of an object\n * @param obj pointer to an object\n * @return true: drag parent is enabled\n */\nbool lv_obj_get_parent_event(const lv_obj_t * obj);\n\n/**\n * Get the opa scale enable parameter\n * @param obj pointer to an object\n * @return true: opa scaling is enabled for this object and all children; false: no opa scaling\n */\nlv_opa_t lv_obj_get_opa_scale_enable(const lv_obj_t * obj);\n\n/**\n * Get the opa scale parameter of an object\n * @param obj pointer to an object\n * @return opa scale [0..255]\n */\nlv_opa_t lv_obj_get_opa_scale(const lv_obj_t * obj);\n\n/**\n * Get the protect field of an object\n * @param obj pointer to an object\n * @return protect field ('OR'ed values of `lv_protect_t`)\n */\nuint8_t lv_obj_get_protect(const lv_obj_t * obj);\n\n/**\n * Check at least one bit of a given protect bitfield is set\n * @param obj pointer to an object\n * @param prot protect bits to test ('OR'ed values of `lv_protect_t`)\n * @return false: none of the given bits are set, true: at least one bit is set\n */\nbool lv_obj_is_protected(const lv_obj_t * obj, uint8_t prot);\n\n/**\n * Get the signal function of an object\n * @param obj pointer to an object\n * @return the signal function\n */\nlv_signal_cb_t lv_obj_get_signal_cb(const lv_obj_t * obj);\n\n/**\n * Get the design function of an object\n * @param obj pointer to an object\n * @return the design function\n */\nlv_design_cb_t lv_obj_get_design_cb(const lv_obj_t * obj);\n\n/**\n * Get the event function of an object\n * @param obj pointer to an object\n * @return the event function\n */\nlv_event_cb_t lv_obj_get_event_cb(const lv_obj_t * obj);\n\n/*------------------\n * Other get\n *-----------------*/\n\n/**\n * Get the ext pointer\n * @param obj pointer to an object\n * @return the ext pointer but not the dynamic version\n *         Use it as ext->data1, and NOT da(ext)->data1\n */\nvoid * lv_obj_get_ext_attr(const lv_obj_t * obj);\n\n/**\n * Get object's and its ancestors type. Put their name in `type_buf` starting with the current type.\n * E.g. buf.type[0]=\"lv_btn\", buf.type[1]=\"lv_cont\", buf.type[2]=\"lv_obj\"\n * @param obj pointer to an object which type should be get\n * @param buf pointer to an `lv_obj_type_t` buffer to store the types\n */\nvoid lv_obj_get_type(lv_obj_t * obj, lv_obj_type_t * buf);\n\n#if LV_USE_USER_DATA\n/**\n * Get the object's user data\n * @param obj pointer to an object\n * @return user data\n */\nlv_obj_user_data_t lv_obj_get_user_data(lv_obj_t * obj);\n\n/**\n * Get a pointer to the object's user data\n * @param obj pointer to an object\n * @return pointer to the user data\n */\nlv_obj_user_data_t * lv_obj_get_user_data_ptr(lv_obj_t * obj);\n\n/**\n * Set the object's user data. The data will be copied.\n * @param obj pointer to an object\n * @param data user data\n */\nvoid lv_obj_set_user_data(lv_obj_t * obj, lv_obj_user_data_t data);\n\n#endif\n\n#if LV_USE_GROUP\n/**\n * Get the group of the object\n * @param obj pointer to an object\n * @return the pointer to group of the object\n */\nvoid * lv_obj_get_group(const lv_obj_t * obj);\n\n/**\n * Tell whether the object is the focused object of a group or not.\n * @param obj pointer to an object\n * @return true: the object is focused, false: the object is not focused or not in a group\n */\nbool lv_obj_is_focused(const lv_obj_t * obj);\n\n#endif\n\n/**********************\n *      MACROS\n **********************/\n\n/**\n * Helps to quickly declare an event callback function.\n * Will be expanded to: `void <name> (lv_obj_t * obj, lv_event_t e)`\n *\n * Examples:\n * static LV_EVENT_CB_DECLARE(my_event1);  //Protoype declaration\n *\n * static LV_EVENT_CB_DECLARE(my_event1)\n * {\n *   if(e == LV_EVENT_CLICKED) {\n *      lv_obj_set_hidden(obj ,true);\n *   }\n * }\n */\n#define LV_EVENT_CB_DECLARE(name) void name(lv_obj_t * obj, lv_event_t e)\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_OBJ_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_core/lv_refr.h",
    "content": "/**\n * @file lv_refr.h\n *\n */\n\n#ifndef LV_REFR_H\n#define LV_REFR_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"lv_obj.h\"\n#include \"utils/types.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Initialize the screen refresh subsystem\n */\nvoid lv_refr_init(void);\n\n/**\n * Redraw the invalidated areas now.\n * Normally the redrawing is periodically executed in `lv_task_handler` but a long blocking process\n * can prevent the call of `lv_task_handler`. In this case if the the GUI is updated in the process\n * (e.g. progress bar) this function can be called when the screen should be updated.\n * @param disp pointer to display to refresh. NULL to refresh all displays.\n */\nvoid lv_refr_now(lv_disp_t * disp);\n\n/**\n * Invalidate an area on display to redraw it\n * @param area_p pointer to area which should be invalidated (NULL: delete the invalidated areas)\n * @param disp pointer to display where the area should be invalidated (NULL can be used if there is\n * only one display)\n */\nvoid lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p);\n\n/**\n * Get the display which is being refreshed\n * @return the display being refreshed\n */\nlv_disp_t * lv_refr_get_disp_refreshing(void);\n\n/**\n * Set the display which is being refreshed.\n * It shouldn1t be used directly by the user.\n * It can be used to trick the drawing functions about there is an active display.\n * @param the display being refreshed\n */\nvoid lv_refr_set_disp_refreshing(lv_disp_t * disp);\n\n/**\n * Called periodically to handle the refreshing\n * @param task pointer to the task itself\n */\nvoid lv_disp_refr_task(lv_task_t * task);\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_REFR_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_core/lv_style.h",
    "content": "/**\n * @file lv_style.h\n *\n */\n\n#ifndef LV_STYLE_H\n#define LV_STYLE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"utils/types.h\"\n#include \"../lv_font/lv_font.h\"\n#include \"../lv_misc/lv_color.h\"\n#include \"../lv_misc/lv_area.h\"\n#include \"../lv_misc/lv_anim.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_RADIUS_CIRCLE (LV_COORD_MAX) /**< A very big radius to always draw as circle*/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/*Border types (Use 'OR'ed values)*/\nenum {\n    LV_BORDER_NONE     = 0x00,\n    LV_BORDER_BOTTOM   = 0x01,\n    LV_BORDER_TOP      = 0x02,\n    LV_BORDER_LEFT     = 0x04,\n    LV_BORDER_RIGHT    = 0x08,\n    LV_BORDER_FULL     = 0x0F,\n    LV_BORDER_INTERNAL = 0x10, /**< FOR matrix-like objects (e.g. Button matrix)*/\n};\ntypedef uint8_t lv_border_part_t;\n\n/*Shadow types*/\nenum {\n    LV_SHADOW_BOTTOM = 0, /**< Only draw bottom shadow */\n    LV_SHADOW_FULL,       /**< Draw shadow on all sides */\n};\ntypedef uint8_t lv_shadow_type_t;\n\n/**\n * Objects in LittlevGL can be assigned a style - which holds information about\n * how the object should be drawn.\n * \n * This allows for easy customization without having to modify the object's design\n * function.\n */\ntypedef struct\n{\n    uint8_t glass : 1; /**< 1: Do not inherit this style*/\n\n    /** Object background. */\n    struct\n    {\n        lv_color_t main_color; /**< Object's main background color. */\n        lv_color_t grad_color; /**< Second color. If not equal to `main_color` a gradient will be drawn for the background. */\n        lv_coord_t radius; /**< Object's corner radius. You can use #LV_RADIUS_CIRCLE if you want to draw a circle. */\n        lv_opa_t opa; /**< Object's opacity (0-255). */\n\n        struct\n        {\n            lv_color_t color; /**< Border color */\n            lv_coord_t width; /**< Border width */\n            lv_border_part_t part; /**< Which borders to draw */\n            lv_opa_t opa; /**< Border opacity. */\n        } border;\n\n        \n        struct\n        {\n            lv_color_t color;\n            lv_coord_t width;\n            lv_shadow_type_t type; /**< Which parts of the shadow to draw */\n        } shadow;\n\n        struct\n        {\n            lv_coord_t top;\n            lv_coord_t bottom;\n            lv_coord_t left;\n            lv_coord_t right;\n            lv_coord_t inner;\n        } padding;\n    } body;\n\n    /** Style for text drawn by this object. */\n    struct\n    {\n        lv_color_t color; /**< Text color */\n        lv_color_t sel_color; /**< Text selection background color. */\n        const lv_font_t * font;\n        lv_coord_t letter_space; /**< Space between letters */\n        lv_coord_t line_space; /**< Space between lines (vertical) */\n        lv_opa_t opa; /**< Text opacity */\n    } text;\n\n    /**< Style of images. */\n    struct\n    {\n        lv_color_t color; /**< Color to recolor the image with */\n        lv_opa_t intense; /**< Opacity of recoloring (0 means no recoloring) */\n        lv_opa_t opa; /**< Opacity of whole image */\n    } image;\n\n    /**< Style of lines (not borders). */\n    struct\n    {\n        lv_color_t color;\n        lv_coord_t width;\n        lv_opa_t opa;\n        uint8_t rounded : 1; /**< 1: rounded line endings*/\n    } line;\n} lv_style_t;\n\n#if LV_USE_ANIMATION\n/** Data structure for style animations. */\ntypedef struct\n{\n    lv_style_t style_start; /*Save not only pointers because can be same as 'style_anim' then it\n                               will be modified too*/\n    lv_style_t style_end;\n    lv_style_t * style_anim;\n    lv_anim_ready_cb_t ready_cb;\n} lv_style_anim_dsc_t;\n#endif\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n *  Init the basic styles\n */\nvoid lv_style_init(void);\n\n/**\n * Copy a style to an other\n * @param dest pointer to the destination style\n * @param src pointer to the source style\n */\nvoid lv_style_copy(lv_style_t * dest, const lv_style_t * src);\n\n/**\n * Mix two styles according to a given ratio\n * @param start start style\n * @param end end style\n * @param res store the result style here\n * @param ratio the ratio of mix [0..256]; 0: `start` style; 256: `end` style\n */\nvoid lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * res, uint16_t ratio);\n\n#if LV_USE_ANIMATION\n\n/**\n * Initialize an animation variable.\n * E.g.:\n * lv_anim_t a;\n * lv_style_anim__init(&a);\n * lv_style_anim_set_...(&a);\n * lv_style_anim_create(&a);\n * @param a pointer to an `lv_anim_t` variable to initialize\n */\nvoid lv_style_anim_init(lv_anim_t * a);\n\n/**\n *\n * @param a pointer to an initialized `lv_anim_t` variable\n * @param to_anim pointer to the style to animate\n * @param start pointer to a style to animate from (start value)\n * @param end pointer to a style to animate to (end value)\n */\nvoid lv_style_anim_set_styles(lv_anim_t * a, lv_style_t * to_anim, const lv_style_t * start, const lv_style_t * end);\n\n/**\n * Set the duration and delay of an animation\n * @param a pointer to an initialized `lv_anim_t` variable\n * @param duration duration of the animation in milliseconds\n * @param delay delay before the animation in milliseconds\n */\nstatic inline void lv_style_anim_set_time(lv_anim_t * a, uint16_t duration, uint16_t delay)\n{\n    lv_anim_set_time(a, duration, delay);\n}\n\n/**\n * Set a function call when the animation is ready\n * @param a pointer to an initialized `lv_anim_t` variable\n * @param ready_cb a function call when the animation is ready\n */\nstatic inline void lv_style_anim_set_ready_cb(lv_anim_t * a, lv_anim_ready_cb_t ready_cb)\n{\n    lv_style_anim_dsc_t * dsc = (lv_style_anim_dsc_t *)a->var;\n    dsc->ready_cb             = ready_cb;\n}\n\n/**\n * Make the animation to play back to when the forward direction is ready\n * @param a pointer to an initialized `lv_anim_t` variable\n * @param wait_time time in milliseconds to wait before starting the back direction\n */\nstatic inline void lv_style_anim_set_playback(lv_anim_t * a, uint16_t wait_time)\n{\n    lv_anim_set_playback(a, wait_time);\n}\n\n/**\n * Disable playback. (Disabled after `lv_anim_init()`)\n * @param a pointer to an initialized `lv_anim_t` variable\n */\nstatic inline void lv_style_anim_clear_playback(lv_anim_t * a)\n{\n    lv_anim_clear_playback(a);\n}\n\n/**\n * Make the animation to start again when ready.\n * @param a pointer to an initialized `lv_anim_t` variable\n * @param wait_time time in milliseconds to wait before starting the animation again\n */\nstatic inline void lv_style_anim_set_repeat(lv_anim_t * a, uint16_t wait_time)\n{\n    lv_anim_set_repeat(a, wait_time);\n}\n\n/**\n * Disable repeat. (Disabled after `lv_anim_init()`)\n * @param a pointer to an initialized `lv_anim_t` variable\n */\nstatic inline void lv_style_anim_clear_repeat(lv_anim_t * a)\n{\n    lv_anim_clear_repeat(a);\n}\n\n/**\n * Create an animation\n * @param a an initialized 'anim_t' variable. Not required after call.\n */\nstatic inline void lv_style_anim_create(lv_anim_t * a)\n{\n    lv_anim_create(a);\n}\n\n#endif\n\n/*************************\n *    GLOBAL VARIABLES\n *************************/\nextern lv_style_t lv_style_scr;\nextern lv_style_t lv_style_transp;\nextern lv_style_t lv_style_transp_fit;\nextern lv_style_t lv_style_transp_tight;\nextern lv_style_t lv_style_plain;\nextern lv_style_t lv_style_plain_color;\nextern lv_style_t lv_style_pretty;\nextern lv_style_t lv_style_pretty_color;\nextern lv_style_t lv_style_btn_rel;\nextern lv_style_t lv_style_btn_pr;\nextern lv_style_t lv_style_btn_tgl_rel;\nextern lv_style_t lv_style_btn_tgl_pr;\nextern lv_style_t lv_style_btn_ina;\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_STYLE_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_draw/lv_draw.h",
    "content": "/**\n * @file lv_draw.h\n *\n */\n\n#ifndef LV_DRAW_H\n#define LV_DRAW_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#include \"../lv_core/lv_style.h\"\n#include \"../lv_misc/lv_txt.h\"\n#include \"lv_img_decoder.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Give a buffer with the given to use during drawing.\n * Be careful to not use the buffer while other processes are using it.\n * @param size the required size\n */\nvoid * lv_draw_get_buf(uint32_t size);\n\n/**\n * Free the draw buffer\n */\nvoid lv_draw_free_buf(void);\n\n#if LV_ANTIALIAS\n\n/**\n * Get the opacity of a pixel based it's position in a line segment\n * @param seg segment length\n * @param px_id position of  of a pixel which opacity should be get [0..seg-1]\n * @param base_opa the base opacity\n * @return the opacity of the given pixel\n */\nlv_opa_t lv_draw_aa_get_opa(lv_coord_t seg, lv_coord_t px_id, lv_opa_t base_opa);\n\n/**\n * Add a vertical  anti-aliasing segment (pixels with decreasing opacity)\n * @param x start point x coordinate\n * @param y start point y coordinate\n * @param length length of segment (negative value to start from 0 opacity)\n * @param mask draw only in this area\n * @param color color of pixels\n * @param opa maximum opacity\n */\nvoid lv_draw_aa_ver_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask, lv_color_t color,\n                        lv_opa_t opa);\n\n/**\n * Add a horizontal anti-aliasing segment (pixels with decreasing opacity)\n * @param x start point x coordinate\n * @param y start point y coordinate\n * @param length length of segment (negative value to start from 0 opacity)\n * @param mask draw only in this area\n * @param color color of pixels\n * @param opa maximum opacity\n */\nvoid lv_draw_aa_hor_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask, lv_color_t color,\n                        lv_opa_t opa);\n#endif\n\n/**********************\n *  GLOBAL VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   POST INCLUDES\n *********************/\n#include \"lv_draw_basic.h\"\n#include \"lv_draw_rect.h\"\n#include \"lv_draw_label.h\"\n#include \"lv_draw_img.h\"\n#include \"lv_draw_line.h\"\n#include \"lv_draw_triangle.h\"\n#include \"lv_draw_arc.h\"\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_DRAW_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_draw/lv_draw.mk",
    "content": "CSRCS += lv_draw_basic.c\nCSRCS += lv_draw.c\nCSRCS += lv_draw_rect.c\nCSRCS += lv_draw_label.c\nCSRCS += lv_draw_line.c\nCSRCS += lv_draw_img.c\nCSRCS += lv_draw_arc.c\nCSRCS += lv_draw_triangle.c\nCSRCS += lv_img_decoder.c\nCSRCS += lv_img_cache.c\n\nDEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_draw\nVPATH += :$(LVGL_DIR)/lvgl/src/lv_draw\n\nCFLAGS += \"-I$(LVGL_DIR)lvgl/src/lv_draw\"\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_draw/lv_draw_arc.h",
    "content": "/**\n * @file lv_draw_arc.h\n *\n */\n\n#ifndef LV_DRAW_ARC_H\n#define LV_DRAW_ARC_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"lv_draw.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Draw an arc. (Can draw pie too with great thickness.)\n * @param center_x the x coordinate of the center of the arc\n * @param center_y the y coordinate of the center of the arc\n * @param radius the radius of the arc\n * @param mask the arc will be drawn only in this mask\n * @param start_angle the start angle of the arc (0 deg on the bottom, 90 deg on the right)\n * @param end_angle the end angle of the arc\n * @param style style of the arc (`body.thickness`, `body.main_color`, `body.opa` is used)\n * @param opa_scale scale down all opacities by the factor\n */\nvoid lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, const lv_area_t * mask,\n                 uint16_t start_angle, uint16_t end_angle, const lv_style_t * style, lv_opa_t opa_scale);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_DRAW_ARC*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_draw/lv_draw_basic.h",
    "content": "/**\n * @file lv_draw_basic.h\n *\n */\n\n#ifndef LV_DRAW_BASIC_H\n#define LV_DRAW_BASIC_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#include \"../lv_font/lv_font.h\"\n#include \"../lv_misc/lv_color.h\"\n#include \"../lv_misc/lv_area.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\nvoid lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa);\n/**\n * Fill an area in the Virtual Display Buffer\n * @param cords_p coordinates of the area to fill\n * @param mask_p fill only o this mask\n * @param color fill color\n * @param opa opacity of the area (0..255)\n */\nvoid lv_draw_fill(const lv_area_t * cords_p, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa);\n\n/**\n * Draw a letter in the Virtual Display Buffer\n * @param pos_p left-top coordinate of the latter\n * @param mask_p the letter will be drawn only on this area\n * @param font_p pointer to font\n * @param letter a letter to draw\n * @param color color of letter\n * @param opa opacity of letter (0..255)\n */\nvoid lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv_font_t * font_p, uint32_t letter,\n                    lv_color_t color, lv_opa_t opa);\n\n/**\n * Draw a color map to the display (image)\n * @param cords_p coordinates the color map\n * @param mask_p the map will drawn only on this area  (truncated to VDB area)\n * @param map_p pointer to a lv_color_t array\n * @param opa opacity of the map\n * @param chroma_keyed true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels\n * @param alpha_byte true: extra alpha byte is inserted for every pixel\n * @param recolor mix the pixels with this color\n * @param recolor_opa the intense of recoloring\n */\nvoid lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p, const uint8_t * map_p, lv_opa_t opa,\n                 bool chroma_key, bool alpha_byte, lv_color_t recolor, lv_opa_t recolor_opa);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_DRAW_BASIC_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_draw/lv_draw_img.h",
    "content": "/**\n * @file lv_draw_img.h\n *\n */\n\n#ifndef LV_DRAW_IMG_H\n#define LV_DRAW_IMG_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"lv_draw.h\"\n#include \"lv_img_decoder.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Draw an image\n * @param coords the coordinates of the image\n * @param mask the image will be drawn only in this area\n * @param src pointer to a lv_color_t array which contains the pixels of the image\n * @param style style of the image\n * @param opa_scale scale down all opacities by the factor\n */\nvoid lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_style_t * style,\n                 lv_opa_t opa_scale);\n\n/**\n * Get the type of an image source\n * @param src pointer to an image source:\n *  - pointer to an 'lv_img_t' variable (image stored internally and compiled into the code)\n *  - a path to a file (e.g. \"S:/folder/image.bin\")\n *  - or a symbol (e.g. LV_SYMBOL_CLOSE)\n * @return type of the image source LV_IMG_SRC_VARIABLE/FILE/SYMBOL/UNKNOWN\n */\nlv_img_src_t lv_img_src_get_type(const void * src);\n\n/**\n * Get the color of an image's pixel\n * @param dsc an image descriptor\n * @param x x coordinate of the point to get\n * @param y x coordinate of the point to get\n * @param style style of the image. In case of `LV_IMG_CF_ALPHA_1/2/4/8` `style->image.color` shows\n * the color. Can be `NULL` but for `ALPHA` images black will be returned. In other cases it is not\n * used.\n * @return color of the point\n */\nlv_color_t lv_img_buf_get_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, const lv_style_t * style);\n/**\n * Get the alpha value of an image's pixel\n * @param dsc pointer to an image descriptor\n * @param x x coordinate of the point to set\n * @param y x coordinate of the point to set\n * @return alpha value of the point\n */\nlv_opa_t lv_img_buf_get_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y);\n\n/**\n * Set the color of a pixel of an image. The alpha channel won't be affected.\n * @param dsc pointer to an image descriptor\n * @param x x coordinate of the point to set\n * @param y x coordinate of the point to set\n * @param c color of the point\n */\nvoid lv_img_buf_set_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_color_t c);\n\n/**\n * Set the alpha value of a pixel of an image. The color won't be affected\n * @param dsc pointer to an image descriptor\n * @param x x coordinate of the point to set\n * @param y x coordinate of the point to set\n * @param opa the desired opacity\n */\nvoid lv_img_buf_set_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_opa_t opa);\n\n/**\n * Set the palette color of an indexed image. Valid only for `LV_IMG_CF_INDEXED1/2/4/8`\n * @param dsc pointer to an image descriptor\n * @param id the palette color to set:\n *   - for `LV_IMG_CF_INDEXED1`: 0..1\n *   - for `LV_IMG_CF_INDEXED2`: 0..3\n *   - for `LV_IMG_CF_INDEXED4`: 0..15\n *   - for `LV_IMG_CF_INDEXED8`: 0..255\n * @param c the color to set\n */\nvoid lv_img_buf_set_palette(lv_img_dsc_t * dsc, uint8_t id, lv_color_t c);\n\n/**\n * Get the pixel size of a color format in bits\n * @param cf a color format (`LV_IMG_CF_...`)\n * @return the pixel size in bits\n */\nuint8_t lv_img_color_format_get_px_size(lv_img_cf_t cf);\n\n/**\n * Check if a color format is chroma keyed or not\n * @param cf a color format (`LV_IMG_CF_...`)\n * @return true: chroma keyed; false: not chroma keyed\n */\nbool lv_img_color_format_is_chroma_keyed(lv_img_cf_t cf);\n\n/**\n * Check if a color format has alpha channel or not\n * @param cf a color format (`LV_IMG_CF_...`)\n * @return true: has alpha channel; false: doesn't have alpha channel\n */\nbool lv_img_color_format_has_alpha(lv_img_cf_t cf);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_TEMPL_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_draw/lv_draw_label.h",
    "content": "/**\n * @file lv_draw_label.h\n *\n */\n\n#ifndef LV_DRAW_LABEL_H\n#define LV_DRAW_LABEL_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"lv_draw.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/** Store some info to speed up drawing of very large texts\n * It takes a lot of time to get the first visible character because\n * all the previous characters needs to be checked to calculate the positions.\n * This structure stores an earlier (e.g. at -1000 px) coordinate and the index of that line.\n * Therefore the calculations can start from here.*/\ntypedef struct {\n    /** Index of the line at `y` coordinate*/\n    int32_t line_start;\n\n    /** Give the `y` coordinate of the first letter at `line start` index. Relative to the label's coordinates*/\n    int32_t y;\n\n    /** The 'y1' coordinate of the label when the hint was saved.\n     * Used to invalidate the hint if the label has moved too much. */\n    int32_t coord_y;\n}lv_draw_label_hint_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Write a text\n * @param coords coordinates of the label\n * @param mask the label will be drawn only in this area\n * @param style pointer to a style\n * @param opa_scale scale down all opacities by the factor\n * @param txt 0 terminated text to write\n * @param flag settings for the text from 'txt_flag_t' enum\n * @param offset text offset in x and y direction (NULL if unused)\n * @param sel_start start index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)\n * @param sel_end end index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)\n */\nvoid lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale,\n                   const char * txt, lv_txt_flag_t flag, lv_point_t * offset, uint16_t sel_start, uint16_t sel_end,\n                   lv_draw_label_hint_t * hint);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_DRAW_LABEL_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_draw/lv_draw_line.h",
    "content": "/**\n * @file lv_draw_line.h\n *\n */\n\n#ifndef LV_DRAW_LINE_H\n#define LV_DRAW_LINE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Draw a line\n * @param point1 first point of the line\n * @param point2 second point of the line\n * @param mask the line will be drawn only on this area\n * @param style pointer to a line's style\n * @param opa_scale scale down all opacities by the factor\n */\nvoid lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * mask,\n                  const lv_style_t * style, lv_opa_t opa_scale);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_DRAW_LINE_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_draw/lv_draw_rect.h",
    "content": "/**\n * @file lv_draw_rect.h\n *\n */\n\n#ifndef LV_DRAW_RECT_H\n#define LV_DRAW_RECT_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"lv_draw.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Draw a rectangle\n * @param coords the coordinates of the rectangle\n * @param mask the rectangle will be drawn only in this mask\n * @param style pointer to a style\n * @param opa_scale scale down all opacities by the factor\n */\nvoid lv_draw_rect(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_DRAW_RECT_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_draw/lv_draw_triangle.h",
    "content": "/**\n * @file lv_draw_triangle.h\n *\n */\n\n#ifndef LV_DRAW_TRIANGLE_H\n#define LV_DRAW_TRIANGLE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"lv_draw.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n *\n * @param points pointer to an array with 3 points\n * @param mask the triangle will be drawn only in this mask\n * @param style style for of the triangle\n * @param opa_scale scale down all opacities by the factor (0..255)\n */\nvoid lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale);\n\n/**\n * Draw a polygon from triangles. Only convex polygons are supported\n * @param points an array of points\n * @param point_cnt number of points\n * @param mask polygon will be drawn only in this mask\n * @param style style of the polygon\n * @param opa_scale scale down all opacities by the factor (0..255)\n */\nvoid lv_draw_polygon(const lv_point_t * points, uint32_t point_cnt, const lv_area_t * mask, const lv_style_t * style,\n                     lv_opa_t opa_scale);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_DRAW_TRIANGLE_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_draw/lv_img_cache.h",
    "content": "/**\n * @file lv_img_cache.h\n *\n */\n\n#ifndef LV_IMG_CACHE_H\n#define LV_IMG_CACHE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"lv_img_decoder.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**\n * When loading images from the network it can take a long time to download and decode the image.\n * \n * To avoid repeating this heavy load images can be cached.\n */\ntypedef struct\n{\n    lv_img_decoder_dsc_t dec_dsc; /**< Image information */\n\n    /** Count the cache entries's life. Add `time_tio_open` to `life` when the entry is used.\n     * Decrement all lifes by one every in every ::lv_img_cache_open.\n     * If life == 0 the entry can be reused */\n    int32_t life;\n} lv_img_cache_entry_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Open an image using the image decoder interface and cache it.\n * The image will be left open meaning if the image decoder open callback allocated memory then it will remain.\n * The image is closed if a new image is opened and the new image takes its place in the cache.\n * @param src source of the image. Path to file or pointer to an `lv_img_dsc_t` variable\n * @param style style of the image\n * @return pointer to the cache entry or NULL if can open the image\n */\nlv_img_cache_entry_t * lv_img_cache_open(const void * src, const lv_style_t * style);\n\n/**\n * Set the number of images to be cached.\n * More cached images mean more opened image at same time which might mean more memory usage.\n * E.g. if 20 PNG or JPG images are open in the RAM they consume memory while opened in the cache.\n * @param new_entry_cnt number of image to cache\n */\nvoid lv_img_cache_set_size(uint16_t new_slot_num);\n\n/**\n * Invalidate an image source in the cache.\n * Useful if the image source is updated therefore it needs to be cached again.\n * @param src an image source path to a file or pointer to an `lv_img_dsc_t` variable.\n */\nvoid lv_img_cache_invalidate_src(const void * src);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_IMG_CACHE_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_draw/lv_img_decoder.h",
    "content": "/**\n * @file lv_img_decoder.h\n *\n */\n\n#ifndef LV_IMG_DEOCER_H\n#define LV_IMG_DEOCER_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#include <stdint.h>\n#include \"../lv_misc/lv_fs.h\"\n#include \"../lv_misc/lv_types.h\"\n#include \"../lv_misc/lv_area.h\"\n#include \"../lv_core/lv_style.h\"\n\n/*********************\n *      DEFINES\n *********************/\n/*If image pixels contains alpha we need to know how much byte is a pixel*/\n#if LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8\n#define LV_IMG_PX_SIZE_ALPHA_BYTE 2\n#elif LV_COLOR_DEPTH == 16\n#define LV_IMG_PX_SIZE_ALPHA_BYTE 3\n#elif LV_COLOR_DEPTH == 32\n#define LV_IMG_PX_SIZE_ALPHA_BYTE 4\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**\n * Source of image. */\nenum {\n    LV_IMG_SRC_VARIABLE, /** Binary/C variable */\n    LV_IMG_SRC_FILE, /** File in filesystem */\n    LV_IMG_SRC_SYMBOL, /** Symbol (@ref lv_symbol_def.h) */\n    LV_IMG_SRC_UNKNOWN, /** Unknown source */\n};\n\ntypedef uint8_t lv_img_src_t;\n/**\n * LittlevGL image header\n */\ntypedef struct\n{\n\n    /* The first 8 bit is very important to distinguish the different source types.\n     * For more info see `lv_img_get_src_type()` in lv_img.c */\n    uint32_t cf : 5;          /* Color format: See `lv_img_color_format_t`*/\n    uint32_t always_zero : 3; /*It the upper bits of the first byte. Always zero to look like a\n                                 non-printable character*/\n\n    uint32_t reserved : 2; /*Reserved to be used later*/\n\n    uint32_t w : 11; /*Width of the image map*/\n    uint32_t h : 11; /*Height of the image map*/\n} lv_img_header_t;\n\n/*Image color format*/\nenum {\n    LV_IMG_CF_UNKNOWN = 0,\n\n    LV_IMG_CF_RAW,              /**< Contains the file as it is. Needs custom decoder function*/\n    LV_IMG_CF_RAW_ALPHA,        /**< Contains the file as it is. The image has alpha. Needs custom decoder\n                                   function*/\n    LV_IMG_CF_RAW_CHROMA_KEYED, /**< Contains the file as it is. The image is chroma keyed. Needs\n                                   custom decoder function*/\n\n    LV_IMG_CF_TRUE_COLOR,              /**< Color format and depth should match with LV_COLOR settings*/\n    LV_IMG_CF_TRUE_COLOR_ALPHA,        /**< Same as `LV_IMG_CF_TRUE_COLOR` but every pixel has an alpha byte*/\n    LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED, /**< Same as `LV_IMG_CF_TRUE_COLOR` but LV_COLOR_TRANSP pixels\n                                          will be transparent*/\n\n    LV_IMG_CF_INDEXED_1BIT, /**< Can have 2 different colors in a palette (always chroma keyed)*/\n    LV_IMG_CF_INDEXED_2BIT, /**< Can have 4 different colors in a palette (always chroma keyed)*/\n    LV_IMG_CF_INDEXED_4BIT, /**< Can have 16 different colors in a palette (always chroma keyed)*/\n    LV_IMG_CF_INDEXED_8BIT, /**< Can have 256 different colors in a palette (always chroma keyed)*/\n\n    LV_IMG_CF_ALPHA_1BIT, /**< Can have one color and it can be drawn or not*/\n    LV_IMG_CF_ALPHA_2BIT, /**< Can have one color but 4 different alpha value*/\n    LV_IMG_CF_ALPHA_4BIT, /**< Can have one color but 16 different alpha value*/\n    LV_IMG_CF_ALPHA_8BIT, /**< Can have one color but 256 different alpha value*/\n\n    LV_IMG_CF_RESERVED_15,              /**< Reserved for further use. */\n    LV_IMG_CF_RESERVED_16,              /**< Reserved for further use. */\n    LV_IMG_CF_RESERVED_17,              /**< Reserved for further use. */\n    LV_IMG_CF_RESERVED_18,              /**< Reserved for further use. */\n    LV_IMG_CF_RESERVED_19,              /**< Reserved for further use. */\n    LV_IMG_CF_RESERVED_20,              /**< Reserved for further use. */\n    LV_IMG_CF_RESERVED_21,              /**< Reserved for further use. */\n    LV_IMG_CF_RESERVED_22,              /**< Reserved for further use. */\n    LV_IMG_CF_RESERVED_23,              /**< Reserved for further use. */\n\n    LV_IMG_CF_USER_ENCODED_0,          /**< User holder encoding format. */\n    LV_IMG_CF_USER_ENCODED_1,          /**< User holder encoding format. */\n    LV_IMG_CF_USER_ENCODED_2,          /**< User holder encoding format. */\n    LV_IMG_CF_USER_ENCODED_3,          /**< User holder encoding format. */\n    LV_IMG_CF_USER_ENCODED_4,          /**< User holder encoding format. */\n    LV_IMG_CF_USER_ENCODED_5,          /**< User holder encoding format. */\n    LV_IMG_CF_USER_ENCODED_6,          /**< User holder encoding format. */\n    LV_IMG_CF_USER_ENCODED_7,          /**< User holder encoding format. */\n};\ntypedef uint8_t lv_img_cf_t;\n\n/** Image header it is compatible with\n * the result from image converter utility*/\ntypedef struct\n{\n    lv_img_header_t header;\n    uint32_t data_size;\n    const uint8_t * data;\n} lv_img_dsc_t;\n\n/* Decoder function definitions */\n\nstruct _lv_img_decoder;\nstruct _lv_img_decoder_dsc;\n\n/**\n * Get info from an image and store in the `header`\n * @param src the image source. Can be a pointer to a C array or a file name (Use\n * `lv_img_src_get_type` to determine the type)\n * @param header store the info here\n * @return LV_RES_OK: info written correctly; LV_RES_INV: failed\n */\ntypedef lv_res_t (*lv_img_decoder_info_f_t)(struct _lv_img_decoder * decoder, const void * src,\n                                            lv_img_header_t * header);\n\n/**\n * Open an image for decoding. Prepare it as it is required to read it later\n * @param decoder pointer to the decoder the function associated with\n * @param dsc pointer to decoder descriptor. `src`, `style` are already initialized in it.\n */\ntypedef lv_res_t (*lv_img_decoder_open_f_t)(struct _lv_img_decoder * decoder, struct _lv_img_decoder_dsc * dsc);\n\n/**\n * Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`.\n * Required only if the \"open\" function can't return with the whole decoded pixel array.\n * @param decoder pointer to the decoder the function associated with\n * @param dsc pointer to decoder descriptor\n * @param x start x coordinate\n * @param y start y coordinate\n * @param len number of pixels to decode\n * @param buf a buffer to store the decoded pixels\n * @return LV_RES_OK: ok; LV_RES_INV: failed\n */\ntypedef lv_res_t (*lv_img_decoder_read_line_f_t)(struct _lv_img_decoder * decoder, struct _lv_img_decoder_dsc * dsc,\n                                                 lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf);\n\n/**\n * Close the pending decoding. Free resources etc.\n * @param decoder pointer to the decoder the function associated with\n * @param dsc pointer to decoder descriptor\n */\ntypedef void (*lv_img_decoder_close_f_t)(struct _lv_img_decoder * decoder, struct _lv_img_decoder_dsc * dsc);\n\ntypedef struct _lv_img_decoder\n{\n    lv_img_decoder_info_f_t info_cb;\n    lv_img_decoder_open_f_t open_cb;\n    lv_img_decoder_read_line_f_t read_line_cb;\n    lv_img_decoder_close_f_t close_cb;\n\n#if LV_USE_USER_DATA\n    lv_img_decoder_user_data_t user_data;\n#endif\n} lv_img_decoder_t;\n\n/**Describe an image decoding session. Stores data about the decoding*/\ntypedef struct _lv_img_decoder_dsc\n{\n    /**The decoder which was able to open the image source*/\n    lv_img_decoder_t * decoder;\n\n    /**The image source. A file path like \"S:my_img.png\" or pointer to an `lv_img_dsc_t` variable*/\n    const void * src;\n\n    /**Style to draw the image.*/\n    const lv_style_t * style;\n\n    /**Type of the source: file or variable. Can be set in `open` function if required*/\n    lv_img_src_t src_type;\n\n    /**Info about the opened image: color format, size, etc. MUST be set in `open` function*/\n    lv_img_header_t header;\n\n    /** Pointer to a buffer where the image's data (pixels) are stored in a decoded, plain format.\n     *  MUST be set in `open` function*/\n    const uint8_t * img_data;\n\n    /** How much time did it take to open the image. [ms]\n     *  If not set `lv_img_cache` will measure and set the time to open*/\n    uint32_t time_to_open;\n\n    /**A text to display instead of the image when the image can't be opened.\n     * Can be set in `open` function or set NULL. */\n    const char * error_msg;\n\n    /**Store any custom data here is required*/\n    void * user_data;\n} lv_img_decoder_dsc_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Initialize the image decoder module\n */\nvoid lv_img_decoder_init(void);\n\n/**\n * Get information about an image.\n * Try the created image decoder one by one. Once one is able to get info that info will be used.\n * @param src the image source. Can be\n *  1) File name: E.g. \"S:folder/img1.png\" (The drivers needs to registered via `lv_fs_add_drv()`)\n *  2) Variable: Pointer to an `lv_img_dsc_t` variable\n *  3) Symbol: E.g. `LV_SYMBOL_OK`\n * @param header the image info will be stored here\n * @return LV_RES_OK: success; LV_RES_INV: wasn't able to get info about the image\n */\nlv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header);\n\n/**\n * Open an image.\n * Try the created image decoder one by one. Once one is able to open the image that decoder is save in `dsc`\n * @param dsc describe a decoding session. Simply a pointer to an `lv_img_decoder_dsc_t` variable.\n * @param src the image source. Can be\n *  1) File name: E.g. \"S:folder/img1.png\" (The drivers needs to registered via `lv_fs_add_drv()`)\n *  2) Variable: Pointer to an `lv_img_dsc_t` variable\n *  3) Symbol: E.g. `LV_SYMBOL_OK`\n * @param style the style of the image\n * @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set.\n *         LV_RES_INV: none of the registered image decoders were able to open the image.\n */\nlv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, const lv_style_t * style);\n\n/**\n * Read a line from an opened image\n * @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open`\n * @param x start X coordinate (from left)\n * @param y start Y coordinate (from top)\n * @param len number of pixels to read\n * @param buf store the data here\n * @return LV_RES_OK: success; LV_RES_INV: an error occurred\n */\nlv_res_t lv_img_decoder_read_line(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len,\n                                  uint8_t * buf);\n\n/**\n * Close a decoding session\n * @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open`\n */\nvoid lv_img_decoder_close(lv_img_decoder_dsc_t * dsc);\n\n/**\n * Create a new image decoder\n * @return pointer to the new image decoder\n */\nlv_img_decoder_t * lv_img_decoder_create(void);\n\n/**\n * Delete an image decoder\n * @param decoder pointer to an image decoder\n */\nvoid lv_img_decoder_delete(lv_img_decoder_t * decoder);\n\n/**\n * Set a callback to get information about the image\n * @param decoder pointer to an image decoder\n * @param info_cb a function to collect info about an image (fill an `lv_img_header_t` struct)\n */\nvoid lv_img_decoder_set_info_cb(lv_img_decoder_t * decoder, lv_img_decoder_info_f_t info_cb);\n\n/**\n * Set a callback to open an image\n * @param decoder pointer to an image decoder\n * @param open_cb a function to open an image\n */\nvoid lv_img_decoder_set_open_cb(lv_img_decoder_t * decoder, lv_img_decoder_open_f_t open_cb);\n\n/**\n * Set a callback to a decoded line of an image\n * @param decoder pointer to an image decoder\n * @param read_line_cb a function to read a line of an image\n */\nvoid lv_img_decoder_set_read_line_cb(lv_img_decoder_t * decoder, lv_img_decoder_read_line_f_t read_line_cb);\n\n/**\n * Set a callback to close a decoding session. E.g. close files and free other resources.\n * @param decoder pointer to an image decoder\n * @param close_cb a function to close a decoding session\n */\nvoid lv_img_decoder_set_close_cb(lv_img_decoder_t * decoder, lv_img_decoder_close_f_t close_cb);\n\n\n\n/**\n * Get info about a built-in image\n * @param decoder the decoder where this function belongs\n * @param src the image source: pointer to an `lv_img_dsc_t` variable, a file path or a symbol\n * @param header store the image data here\n * @return LV_RES_OK: the info is successfully stored in `header`; LV_RES_INV: unknown format or other error.\n */\nlv_res_t lv_img_decoder_built_in_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header);\n\n/**\n * Open a built in image\n * @param decoder the decoder where this function belongs\n * @param dsc pointer to decoder descriptor. `src`, `style` are already initialized in it.\n * @return LV_RES_OK: the info is successfully stored in `header`; LV_RES_INV: unknown format or other error.\n */\nlv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc);\n\n/**\n * Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`.\n * Required only if the \"open\" function can't return with the whole decoded pixel array.\n * @param decoder pointer to the decoder the function associated with\n * @param dsc pointer to decoder descriptor\n * @param x start x coordinate\n * @param y start y coordinate\n * @param len number of pixels to decode\n * @param buf a buffer to store the decoded pixels\n * @return LV_RES_OK: ok; LV_RES_INV: failed\n */\nlv_res_t lv_img_decoder_built_in_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc, lv_coord_t x,\n                                                  lv_coord_t y, lv_coord_t len, uint8_t * buf);\n\n/**\n * Close the pending decoding. Free resources etc.\n * @param decoder pointer to the decoder the function associated with\n * @param dsc pointer to decoder descriptor\n */\nvoid lv_img_decoder_built_in_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_TEMPL_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_font/lv_font.h",
    "content": "/**\n * @file lv_font.h\n *\n */\n\n#ifndef LV_FONT_H\n#define LV_FONT_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#include <stdint.h>\n#include <stddef.h>\n#include \"utils/types.h\"\n\n#include \"lv_symbol_def.h\"\n\n/*********************\n *      DEFINES\n *********************/\n/*Number of fractional digits in the advanced width (`adv_w`) field of `lv_font_glyph_dsc_t`*/\n#define LV_FONT_WIDTH_FRACT_DIGIT       4\n\n#define LV_FONT_KERN_POSITIVE        0\n#define LV_FONT_KERN_NEGATIVE        1\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/*------------------\n * General types\n *-----------------*/\n\n/** Describes the properties of a glyph. */\ntypedef struct\n{\n    uint16_t adv_w; /**< The glyph needs this space. Draw the next glyph after this width. 8 bit integer, 4 bit fractional */\n    uint8_t box_w;  /**< Width of the glyph's bounding box*/\n    uint8_t box_h;  /**< Height of the glyph's bounding box*/\n    int8_t ofs_x;   /**< x offset of the bounding box*/\n    int8_t ofs_y;  /**< y offset of the bounding box*/\n    uint8_t bpp;   /**< Bit-per-pixel: 1, 2, 4, 8*/\n}lv_font_glyph_dsc_t;\n\n/*Describe the properties of a font*/\ntypedef struct _lv_font_struct\n{\n    /** Get a glyph's  descriptor from a font*/\n    bool (*get_glyph_dsc)(const struct _lv_font_struct *, lv_font_glyph_dsc_t *, uint32_t letter, uint32_t letter_next);\n\n    /** Get a glyph's bitmap from a font*/\n    const uint8_t * (*get_glyph_bitmap)(const struct _lv_font_struct *, uint32_t);\n\n    /*Pointer to the font in a font pack (must have the same line height)*/\n    uint8_t line_height;      /**< The real line height where any text fits*/\n    uint8_t base_line;        /**< Base line measured from the top of the line_height*/\n    void * dsc;               /**< Store implementation specific data here*/\n#if LV_USE_USER_DATA\n    lv_font_user_data_t user_data; /**< Custom user data for font. */\n#endif\n} lv_font_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Return with the bitmap of a font.\n * @param font_p pointer to a font\n * @param letter an UNICODE character code\n * @return  pointer to the bitmap of the letter\n */\nconst uint8_t * lv_font_get_glyph_bitmap(const lv_font_t * font_p, uint32_t letter);\n\n/**\n * Get the descriptor of a glyph\n * @param font_p pointer to font\n * @param dsc_out store the result descriptor here\n * @param letter an UNICODE letter code\n * @return true: descriptor is successfully loaded into `dsc_out`.\n *         false: the letter was not found, no data is loaded to `dsc_out`\n */\nbool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_out, uint32_t letter, uint32_t letter_next);\n\n/**\n * Get the width of a glyph with kerning\n * @param font pointer to a font\n * @param letter an UNICODE letter\n * @param letter_next the next letter after `letter`. Used for kerning\n * @return the width of the glyph\n */\nuint16_t lv_font_get_glyph_width(const lv_font_t * font, uint32_t letter, uint32_t letter_next);\n\n/**\n * Get the line height of a font. All characters fit into this height\n * @param font_p pointer to a font\n * @return the height of a font\n */\nstatic inline uint8_t lv_font_get_line_height(const lv_font_t * font_p)\n{\n    return font_p->line_height;\n}\n\n/**********************\n *      MACROS\n **********************/\n\n#define LV_FONT_DECLARE(font_name) extern lv_font_t font_name;\n\n\n#if LV_FONT_UNSCII_8\nLV_FONT_DECLARE(lv_font_unscii_8)\n#endif\n\n#if LV_FONT_MONTSERRAT_12\nLV_FONT_DECLARE(lv_font_montserrat_12)\n#endif\n\n#if LV_FONT_MA_20\nLV_FONT_DECLARE(lv_font_montserrat_alternate_20)\n#endif\n\n#if LV_FONT_MA_30\nLV_FONT_DECLARE(lv_font_montserrat_alternate_30)\n#endif\n\n#if LV_FONT_MA_110\nLV_FONT_DECLARE(lv_font_montserrat_alternate_110)\n#endif\n\n/*Declare the custom (user defined) fonts*/\n#ifdef LV_FONT_CUSTOM_DECLARE\nLV_FONT_CUSTOM_DECLARE\n#endif\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*USE_FONT*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_font/lv_font.mk",
    "content": "CSRCS += lv_font.c\nCSRCS += lv_font_fmt_txt.c\nCSRCS += lv_font_unscii_8.c\nCSRCS += lv_font_montserrat_12.c\nCSRCS += lv_font_ma_20.c\nCSRCS += lv_font_ma_30.c\nCSRCS += lv_font_ma_80.c\nCSRCS += lv_font_ma_110.c\n\nDEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_font\nVPATH += :$(LVGL_DIR)/lvgl/src/lv_font\n\nCFLAGS += \"-I$(LVGL_DIR)/lvgl/src/lv_font\"\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_font/lv_font_fmt_txt.h",
    "content": "/**\n * @file lv_font.h\n *\n */\n\n#ifndef LV_FONT_FMT_TXT_H\n#define LV_FONT_FMT_TXT_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#include <stdint.h>\n#include <stddef.h>\n#include \"utils/types.h\"\n#include \"lv_font.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/** This describes a glyph. */\ntypedef struct\n{\n#if LV_FONT_FMT_TXT_LARGE == 0\n    uint32_t bitmap_index : 20;     /**< Start index of the bitmap. A font can be max 1 MB. */\n    uint32_t adv_w :12;             /**< Draw the next glyph after this width. 8.4 format (real_value * 16 is stored). */\n#else\n    uint32_t bitmap_index;          /**< Start index of the bitmap. A font can be max 4 GB. */\n    uint32_t adv_w;                 /**< Draw the next glyph after this width. 28.4 format (real_value * 16 is stored). */\n#endif\n    uint8_t box_w;                  /**< Width of the glyph's bounding box*/\n    uint8_t box_h;                  /**< Height of the glyph's bounding box*/\n    int8_t ofs_x;                   /**< x offset of the bounding box*/\n    uint8_t ofs_y;                  /**< y offset of the bounding box. Measured from the top of the line*/\n}lv_font_fmt_txt_glyph_dsc_t;\n\n\n/** Format of font character map. */\nenum {\n    LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY,\n    LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL,\n    LV_FONT_FMT_TXT_CMAP_SPARSE_TINY,\n    LV_FONT_FMT_TXT_CMAP_SPARSE_FULL,\n};\n\ntypedef uint8_t lv_font_fmt_txt_cmap_type_t;\n\n\n/* Map codepoints to a `glyph_dsc`s\n * Several formats are supported to optimize memory usage\n * See https://github.com/littlevgl/lv_font_conv/blob/master/doc/font_spec.md\n */\ntypedef struct {\n    /** First Unicode character for this range */\n    uint32_t range_start;\n\n    /** Number of Unicode characters related to this range.\n     * Last Unicode character = range_start + range_length - 1*/\n    uint16_t range_length;\n\n    /** First glyph ID (array index of `glyph_dsc`) for this range */\n    uint16_t glyph_id_start;\n\n    /*\n    According the specification there are 4 formats:\n        https://github.com/littlevgl/lv_font_conv/blob/master/doc/font_spec.md\n\n    For simplicity introduce \"relative code point\":\n        rcp = codepoint - range_start\n\n    and a search function:\n        search a \"value\" in an \"array\" and returns the index of \"value\".\n\n    Format 0 tiny\n        unicode_list == NULL && glyph_id_ofs_list == NULL\n        glyph_id = glyph_id_start + rcp\n\n    Format 0 full\n        unicode_list == NULL && glyph_id_ofs_list != NULL\n        glyph_id = glyph_id_start + glyph_id_ofs_list[rcp]\n\n    Sparse tiny\n        unicode_list != NULL && glyph_id_ofs_list == NULL\n        glyph_id = glyph_id_start + search(unicode_list, rcp)\n\n    Sparse full\n        unicode_list != NULL && glyph_id_ofs_list != NULL\n        glyph_id = glyph_id_start + glyph_id_ofs_list[search(unicode_list, rcp)]\n    */\n\n    const uint16_t * unicode_list;\n\n    /** if(type == LV_FONT_FMT_TXT_CMAP_FORMAT0_...) it's `uint8_t *`\n     * if(type == LV_FONT_FMT_TXT_CMAP_SPARSE_...)  it's `uint16_t *`\n     */\n    const void * glyph_id_ofs_list;\n\n    /** Length of `unicode_list` and/or `glyph_id_ofs_list`*/\n    uint16_t list_length;\n\n    /** Type of this character map*/\n    lv_font_fmt_txt_cmap_type_t type   :2;\n}lv_font_fmt_txt_cmap_t;\n\n/** A simple mapping of kern values from pairs*/\ntypedef struct {\n    /*To get a kern value of two code points:\n       1. Get the `glyph_id_left` and `glyph_id_right` from `lv_font_fmt_txt_cmap_t\n       2  for(i = 0; i < pair_cnt * 2; i+2)\n             if(gylph_ids[i] == glyph_id_left &&\n                gylph_ids[i+1] == glyph_id_right)\n                 return values[i / 2];\n     */\n    const void * glyph_ids;\n    const int8_t * values;\n    uint32_t pair_cnt   :24;\n    uint32_t glyph_ids_size :2;     /*0: `glyph_ids` is stored as `uint8_t`; 1: as `uint16_t`*/\n}lv_font_fmt_txt_kern_pair_t;\n\n/** More complex but more optimal class based kern value storage*/\ntypedef struct {\n    /*To get a kern value of two code points:\n          1. Get the `glyph_id_left` and `glyph_id_right` from `lv_font_fmt_txt_cmap_t\n          2  Get the class of the left and right glyphs as `left_class` and `right_class`\n              left_class = left_class_mapping[glyph_id_left];\n              right_class = right_class_mapping[glyph_id_right];\n          3. value = class_pair_values[(left_class-1)*right_class_cnt + (righ_class-1)]\n        */\n\n    const uint8_t * class_pair_values;    /*left_class_num * right_class_num value*/\n    const uint8_t * left_class_mapping;   /*Map the glyph_ids to classes: index -> glyph_id -> class_id*/\n    const uint8_t * right_class_mapping;  /*Map the glyph_ids to classes: index -> glyph_id -> class_id*/\n    uint8_t left_class_cnt;\n    uint8_t right_class_cnt;\n}lv_font_fmt_txt_kern_classes_t;\n\n\n/** Bitmap formats*/\ntypedef enum {\n    LV_FONT_FMT_TXT_PLAIN      = 0,\n    LV_FONT_FMT_TXT_COMPRESSED = 1,\n}lv_font_fmt_txt_bitmap_format_t;\n\n\n/*Describe store additional data for fonts */\ntypedef struct {\n    /*The bitmaps os all glyphs*/\n    const uint8_t * glyph_bitmap;\n\n    /*Describe the glyphs*/\n    const lv_font_fmt_txt_glyph_dsc_t * glyph_dsc;\n\n    /* Map the glyphs to Unicode characters.\n     * Array of `lv_font_cmap_fmt_txt_t` variables*/\n    const lv_font_fmt_txt_cmap_t * cmaps;\n\n    /* Store kerning values.\n     * Can be  `lv_font_fmt_txt_kern_pair_t *  or `lv_font_kern_classes_fmt_txt_t *`\n     * depending on `kern_classes`\n     */\n    const void * kern_dsc;\n\n    /*Scale kern values in 12.4 format*/\n    uint16_t kern_scale;\n\n    /*Number of cmap tables*/\n    uint16_t cmap_num       :10;\n\n    /*Bit per pixel: 1, 2, 4 or 8*/\n    uint16_t bpp            :3;\n\n    /*Type of `kern_dsc`*/\n    uint16_t kern_classes   :1;\n\n    /*\n     * storage format of the bitmap\n     * from `lv_font_fmt_txt_bitmap_format_t`\n     */\n    uint16_t bitmap_format  :2;\n\n    /*Cache the last letter and is glyph id*/\n    uint32_t last_letter;\n    uint32_t last_glyph_id;\n\n}lv_font_fmt_txt_dsc_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Used as `get_glyph_bitmap` callback in LittelvGL's native font format if the font is uncompressed.\n * @param font pointer to font\n * @param unicode_letter an unicode letter which bitmap should be get\n * @return pointer to the bitmap or NULL if not found\n */\nconst uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t letter);\n\n/**\n * Used as `get_glyph_dsc` callback in LittelvGL's native font format if the font is uncompressed.\n * @param font_p pointer to font\n * @param dsc_out store the result descriptor here\n * @param letter an UNICODE letter code\n * @return true: descriptor is successfully loaded into `dsc_out`.\n *         false: the letter was not found, no data is loaded to `dsc_out`\n */\nbool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next);\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n * ADD BUILT IN FONTS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_FONT_FMT_TXT_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_font/lv_symbol_def.h",
    "content": "#ifndef LV_SYMBOL_DEF_H\n#define LV_SYMBOL_DEF_H\n/* clang-format off */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n\n#define LV_SYMBOL_AUDIO           \"\\xef\\x80\\x81\"\n#define LV_SYMBOL_VIDEO           \"\\xef\\x80\\x88\"\n#define LV_SYMBOL_LIST            \"\\xef\\x80\\x8b\"\n#define LV_SYMBOL_OK              \"\\xef\\x80\\x8c\"\n#define LV_SYMBOL_CLOSE           \"\\xef\\x80\\x8d\"\n#define LV_SYMBOL_POWER           \"\\xef\\x80\\x91\"\n#define LV_SYMBOL_SETTINGS        \"\\xef\\x80\\x93\"\n#define LV_SYMBOL_TRASH           \"\\xef\\x80\\x94\"\n#define LV_SYMBOL_HOME            \"\\xef\\x80\\x95\"\n#define LV_SYMBOL_DOWNLOAD        \"\\xef\\x80\\x99\"\n#define LV_SYMBOL_DRIVE           \"\\xef\\x80\\x9c\"\n#define LV_SYMBOL_REFRESH         \"\\xef\\x80\\xa1\"\n#define LV_SYMBOL_MUTE            \"\\xef\\x80\\xa6\"\n#define LV_SYMBOL_VOLUME_MID      \"\\xef\\x80\\xa7\"\n#define LV_SYMBOL_VOLUME_MAX      \"\\xef\\x80\\xa8\"\n#define LV_SYMBOL_IMAGE           \"\\xef\\x80\\xbe\"\n#define LV_SYMBOL_EDIT            \"\\xef\\x81\\x80\"\n#define LV_SYMBOL_PREV            \"\\xef\\x81\\x88\"\n#define LV_SYMBOL_PLAY            \"\\xef\\x81\\x8b\"\n#define LV_SYMBOL_PAUSE           \"\\xef\\x81\\x8c\"\n#define LV_SYMBOL_STOP            \"\\xef\\x81\\x8d\"\n#define LV_SYMBOL_NEXT            \"\\xef\\x81\\x91\"\n#define LV_SYMBOL_EJECT           \"\\xef\\x81\\x92\"\n#define LV_SYMBOL_LEFT            \"\\xef\\x81\\x93\"\n#define LV_SYMBOL_RIGHT           \"\\xef\\x81\\x94\"\n#define LV_SYMBOL_PLUS            \"\\xef\\x81\\xa7\"\n#define LV_SYMBOL_MINUS           \"\\xef\\x81\\xa8\"\n#define LV_SYMBOL_WARNING         \"\\xef\\x81\\xb1\"\n#define LV_SYMBOL_SHUFFLE         \"\\xef\\x81\\xb4\"\n#define LV_SYMBOL_UP              \"\\xef\\x81\\xb7\"\n#define LV_SYMBOL_DOWN            \"\\xef\\x81\\xb8\"\n#define LV_SYMBOL_LOOP            \"\\xef\\x81\\xb9\"\n#define LV_SYMBOL_DIRECTORY       \"\\xef\\x81\\xbb\"\n#define LV_SYMBOL_UPLOAD          \"\\xef\\x82\\x93\"\n#define LV_SYMBOL_CALL            \"\\xef\\x82\\x95\"\n#define LV_SYMBOL_CUT             \"\\xef\\x83\\x84\"\n#define LV_SYMBOL_COPY            \"\\xef\\x83\\x85\"\n#define LV_SYMBOL_SAVE            \"\\xef\\x83\\x87\"\n#define LV_SYMBOL_CHARGE          \"\\xef\\x83\\xa7\"\n#define LV_SYMBOL_BELL            \"\\xef\\x83\\xb3\"\n#define LV_SYMBOL_KEYBOARD        \"\\xef\\x84\\x9c\"\n#define LV_SYMBOL_GPS             \"\\xef\\x84\\xa4\"\n#define LV_SYMBOL_FILE            \"\\xef\\x85\\x9b\"\n#define LV_SYMBOL_WIFI            \"\\xef\\x87\\xab\"\n#define LV_SYMBOL_BATTERY_FULL    \"\\xef\\x89\\x80\"\n#define LV_SYMBOL_BATTERY_3       \"\\xef\\x89\\x81\"\n#define LV_SYMBOL_BATTERY_2       \"\\xef\\x89\\x82\"\n#define LV_SYMBOL_BATTERY_1       \"\\xef\\x89\\x83\"\n#define LV_SYMBOL_BATTERY_EMPTY   \"\\xef\\x89\\x84\"\n#define LV_SYMBOL_BLUETOOTH       \"\\xef\\x8a\\x93\"\n#define LV_SYMBOL_METEOR          \"\\xef\\x9d\\x93\"\n#define LV_SYMBOL_ROCKET          \"\\xef\\x84\\xb5\"\n\n/** Invalid symbol at (U+F8FF). If written before a string then `lv_img` will show it as a label*/\n#define LV_SYMBOL_DUMMY           \"\\xEF\\xA3\\xBF\"\n\n/*\n * The following list is generated using\n * cat src/lv_misc/lv_symbol_def.h | sed -E -n 's/^#define\\s+(LV_SYMBOL_\\w+).*\"$/    _LV_STR_\\1,/p'\n */\nenum {\n    _LV_STR_SYMBOL_AUDIO,\n    _LV_STR_SYMBOL_VIDEO,\n    _LV_STR_SYMBOL_LIST,\n    _LV_STR_SYMBOL_OK,\n    _LV_STR_SYMBOL_CLOSE,\n    _LV_STR_SYMBOL_POWER,\n    _LV_STR_SYMBOL_SETTINGS,\n    _LV_STR_SYMBOL_TRASH,\n    _LV_STR_SYMBOL_HOME,\n    _LV_STR_SYMBOL_DOWNLOAD,\n    _LV_STR_SYMBOL_DRIVE,\n    _LV_STR_SYMBOL_REFRESH,\n    _LV_STR_SYMBOL_MUTE,\n    _LV_STR_SYMBOL_VOLUME_MID,\n    _LV_STR_SYMBOL_VOLUME_MAX,\n    _LV_STR_SYMBOL_IMAGE,\n    _LV_STR_SYMBOL_EDIT,\n    _LV_STR_SYMBOL_PREV,\n    _LV_STR_SYMBOL_PLAY,\n    _LV_STR_SYMBOL_PAUSE,\n    _LV_STR_SYMBOL_STOP,\n    _LV_STR_SYMBOL_NEXT,\n    _LV_STR_SYMBOL_EJECT,\n    _LV_STR_SYMBOL_LEFT,\n    _LV_STR_SYMBOL_RIGHT,\n    _LV_STR_SYMBOL_PLUS,\n    _LV_STR_SYMBOL_MINUS,\n    _LV_STR_SYMBOL_WARNING,\n    _LV_STR_SYMBOL_SHUFFLE,\n    _LV_STR_SYMBOL_UP,\n    _LV_STR_SYMBOL_DOWN,\n    _LV_STR_SYMBOL_LOOP,\n    _LV_STR_SYMBOL_DIRECTORY,\n    _LV_STR_SYMBOL_UPLOAD,\n    _LV_STR_SYMBOL_CALL,\n    _LV_STR_SYMBOL_CUT,\n    _LV_STR_SYMBOL_COPY,\n    _LV_STR_SYMBOL_SAVE,\n    _LV_STR_SYMBOL_CHARGE,\n    _LV_STR_SYMBOL_BELL,\n    _LV_STR_SYMBOL_KEYBOARD,\n    _LV_STR_SYMBOL_GPS,\n    _LV_STR_SYMBOL_FILE,\n    _LV_STR_SYMBOL_WIFI,\n    _LV_STR_SYMBOL_BATTERY_FULL,\n    _LV_STR_SYMBOL_BATTERY_3,\n    _LV_STR_SYMBOL_BATTERY_2,\n    _LV_STR_SYMBOL_BATTERY_1,\n    _LV_STR_SYMBOL_BATTERY_EMPTY,\n    _LV_STR_SYMBOL_BLUETOOTH,\n    _LV_STR_SYMBOL_DUMMY,\n};\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /*LV_SYMBOL_DEF_H*/\n\n\n\n\n\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_hal/lv_hal.h",
    "content": "/**\n * @file lv_hal.h\n *\n */\n\n#ifndef LV_HAL_H\n#define LV_HAL_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"lv_hal_disp.h\"\n#include \"lv_hal_indev.h\"\n#include \"lv_hal_tick.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_hal/lv_hal.mk",
    "content": "CSRCS += lv_hal_disp.c\nCSRCS += lv_hal_indev.c\nCSRCS += lv_hal_tick.c\n\nDEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_hal\nVPATH += :$(LVGL_DIR)/lvgl/src/lv_hal\n\nCFLAGS += \"-I$(LVGL_DIR)/lvgl/src/lv_hal\"\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_hal/lv_hal_disp.h",
    "content": "/**\n * @file lv_hal_disp.h\n *\n * @description Display Driver HAL interface header file\n *\n */\n\n#ifndef LV_HAL_DISP_H\n#define LV_HAL_DISP_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#include <stdint.h>\n#include \"utils/types.h\"\n#include \"lv_hal.h\"\n#include \"../lv_misc/lv_color.h\"\n#include \"../lv_misc/lv_area.h\"\n#include \"../lv_misc/lv_ll.h\"\n#include \"../lv_misc/lv_task.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#ifndef LV_INV_BUF_SIZE\n#define LV_INV_BUF_SIZE 32 /*Buffer size for invalid areas */\n#endif\n\n#ifndef LV_ATTRIBUTE_FLUSH_READY\n#define LV_ATTRIBUTE_FLUSH_READY\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\nstruct _disp_t;\nstruct _disp_drv_t;\n\n/**\n * Structure for holding display buffer information.\n */\ntypedef struct\n{\n    void * buf1; /**< First display buffer. */\n    void * buf2; /**< Second display buffer. */\n\n    /*Internal, used by the library*/\n    void * buf_act;\n    uint32_t size; /*In pixel count*/\n    lv_area_t area;\n    volatile uint32_t flushing : 1;\n} lv_disp_buf_t;\n\n/**\n * Display Driver structure to be registered by HAL\n */\ntypedef struct _disp_drv_t\n{\n\n    lv_coord_t hor_res; /**< Horizontal resolution. */\n    lv_coord_t ver_res; /**< Vertical resolution. */\n\n    /** Pointer to a buffer initialized with `lv_disp_buf_init()`.\n     * LittlevGL will use this buffer(s) to draw the screens contents */\n    lv_disp_buf_t * buffer;\n\n#if LV_ANTIALIAS\n    uint32_t antialiasing : 1; /**< 1: antialiasing is enabled on this display. */\n#endif\n    uint32_t rotated : 1; /**< 1: turn the display by 90 degree. @warning Does not update coordinates for you!*/\n\n#if LV_COLOR_SCREEN_TRANSP\n    /**Handle if the the screen doesn't have a solid (opa == LV_OPA_COVER) background.\n     * Use only if required because it's slower.*/\n    uint32_t screen_transp : 1;\n#endif\n\n    /** MANDATORY: Write the internal buffer (VDB) to the display. 'lv_disp_flush_ready()' has to be\n     * called when finished */\n    void (*flush_cb)(struct _disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);\n\n    /** OPTIONAL: Extend the invalidated areas to match with the display drivers requirements\n     * E.g. round `y` to, 8, 16 ..) on a monochrome display*/\n    void (*rounder_cb)(struct _disp_drv_t * disp_drv, lv_area_t * area);\n\n    /** OPTIONAL: Set a pixel in a buffer according to the special requirements of the display\n     * Can be used for color format not supported in LittelvGL. E.g. 2 bit -> 4 gray scales\n     * @note Much slower then drawing with supported color formats. */\n    void (*set_px_cb)(struct _disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,\n                      lv_color_t color, lv_opa_t opa);\n\n    /** OPTIONAL: Called after every refresh cycle to tell the rendering and flushing time + the\n     * number of flushed pixels */\n    void (*monitor_cb)(struct _disp_drv_t * disp_drv, uint32_t time, uint32_t px);\n\n#if LV_USE_GPU\n    /** OPTIONAL: Blend two memories using opacity (GPU only)*/\n    void (*gpu_blend_cb)(struct _disp_drv_t * disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length,\n                         lv_opa_t opa);\n\n    /** OPTIONAL: Fill a memory with a color (GPU only)*/\n    void (*gpu_fill_cb)(struct _disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,\n                        const lv_area_t * fill_area, lv_color_t color);\n#endif\n\n    /** On CHROMA_KEYED images this color will be transparent.\n     * `LV_COLOR_TRANSP` by default. (lv_conf.h)*/\n    lv_color_t color_chroma_key;\n\n#if LV_USE_USER_DATA\n    lv_disp_drv_user_data_t user_data; /**< Custom display driver user data */\n#endif\n\n} lv_disp_drv_t;\n\nstruct _lv_obj_t;\n\n/**\n * Display structure.\n * ::lv_disp_drv_t is the first member of the structure.\n */\ntypedef struct _disp_t\n{\n    /**< Driver to the display*/\n    lv_disp_drv_t driver;\n\n    /**< A task which periodically checks the dirty areas and refreshes them*/\n    lv_task_t * refr_task;\n\n    /** Screens of the display*/\n    lv_ll_t scr_ll;\n    struct _lv_obj_t * act_scr; /**< Currently active screen on this display */\n    struct _lv_obj_t * top_layer; /**< @see lv_disp_get_layer_top */\n    struct _lv_obj_t * sys_layer; /**< @see lv_disp_get_layer_sys */\n\n    /** Invalidated (marked to redraw) areas*/\n    lv_area_t inv_areas[LV_INV_BUF_SIZE];\n    uint8_t inv_area_joined[LV_INV_BUF_SIZE];\n    uint32_t inv_p : 10;\n\n    /*Miscellaneous data*/\n    uint32_t last_activity_time; /**< Last time there was activity on this display */\n} lv_disp_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Initialize a display driver with default values.\n * It is used to have known values in the fields and not junk in memory.\n * After it you can safely set only the fields you need.\n * @param driver pointer to driver variable to initialize\n */\nvoid lv_disp_drv_init(lv_disp_drv_t * driver);\n\n/**\n * Initialize a display buffer\n * @param disp_buf pointer `lv_disp_buf_t` variable to initialize\n * @param buf1 A buffer to be used by LittlevGL to draw the image.\n *             Always has to specified and can't be NULL.\n *             Can be an array allocated by the user. E.g. `static lv_color_t disp_buf1[1024 * 10]`\n *             Or a memory address e.g. in external SRAM\n * @param buf2 Optionally specify a second buffer to make image rendering and image flushing\n *             (sending to the display) parallel.\n *             In the `disp_drv->flush` you should use DMA or similar hardware to send\n *             the image to the display in the background.\n *             It lets LittlevGL to render next frame into the other buffer while previous is being\n * sent. Set to `NULL` if unused.\n * @param size_in_px_cnt size of the `buf1` and `buf2` in pixel count.\n */\nvoid lv_disp_buf_init(lv_disp_buf_t * disp_buf, void * buf1, void * buf2, uint32_t size_in_px_cnt);\n\n/**\n * Register an initialized display driver.\n * Automatically set the first display as active.\n * @param driver pointer to an initialized 'lv_disp_drv_t' variable (can be local variable)\n * @return pointer to the new display or NULL on error\n */\nlv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver);\n\n/**\n * Update the driver in run time.\n * @param disp pointer to a display. (return value of `lv_disp_drv_register`)\n * @param new_drv pointer to the new driver\n */\nvoid lv_disp_drv_update(lv_disp_t * disp, lv_disp_drv_t * new_drv);\n\n/**\n * Remove a display\n * @param disp pointer to display\n */\nvoid lv_disp_remove(lv_disp_t * disp);\n\n/**\n * Set a default screen. The new screens will be created on it by default.\n * @param disp pointer to a display\n */\nvoid lv_disp_set_default(lv_disp_t * disp);\n\n/**\n * Get the default display\n * @return pointer to the default display\n */\nlv_disp_t * lv_disp_get_default(void);\n\n/**\n * Get the horizontal resolution of a display\n * @param disp pointer to a display (NULL to use the default display)\n * @return the horizontal resolution of the display\n */\nlv_coord_t lv_disp_get_hor_res(lv_disp_t * disp);\n\n/**\n * Get the vertical resolution of a display\n * @param disp pointer to a display (NULL to use the default display)\n * @return the vertical resolution of the display\n */\nlv_coord_t lv_disp_get_ver_res(lv_disp_t * disp);\n\n/**\n * Get if anti-aliasing is enabled for a display or not\n * @param disp pointer to a display (NULL to use the default display)\n * @return true: anti-aliasing is enabled; false: disabled\n */\nbool lv_disp_get_antialiasing(lv_disp_t * disp);\n\n//! @cond Doxygen_Suppress\n\n/**\n * Call in the display driver's `flush_cb` function when the flushing is finished\n * @param disp_drv pointer to display driver in `flush_cb` where this function is called\n */\nLV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_drv_t * disp_drv);\n\n//! @endcond\n\n/**\n * Get the next display.\n * @param disp pointer to the current display. NULL to initialize.\n * @return the next display or NULL if no more. Give the first display when the parameter is NULL\n */\nlv_disp_t * lv_disp_get_next(lv_disp_t * disp);\n\n/**\n * Get the internal buffer of a display\n * @param disp pointer to a display\n * @return pointer to the internal buffers\n */\nlv_disp_buf_t * lv_disp_get_buf(lv_disp_t * disp);\n\n/**\n * Get the number of areas in the buffer\n * @return number of invalid areas\n */\nuint16_t lv_disp_get_inv_buf_size(lv_disp_t * disp);\n\n/**\n * Pop (delete) the last 'num' invalidated areas from the buffer\n * @param num number of areas to delete\n */\nvoid lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num);\n\n/**\n * Check the driver configuration if it's double buffered (both `buf1` and `buf2` are set)\n * @param disp pointer to to display to check\n * @return true: double buffered; false: not double buffered\n */\nbool lv_disp_is_double_buf(lv_disp_t * disp);\n\n/**\n * Check the driver configuration if it's TRUE double buffered (both `buf1` and `buf2` are set and\n * `size` is screen sized)\n * @param disp pointer to to display to check\n * @return true: double buffered; false: not double buffered\n */\nbool lv_disp_is_true_double_buf(lv_disp_t * disp);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_hal/lv_hal_indev.h",
    "content": "/**\n * @file lv_hal_indev.h\n *\n * @description Input Device HAL interface layer header file\n *\n */\n\n#ifndef LV_HAL_INDEV_H\n#define LV_HAL_INDEV_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#include \"utils/types.h\"\n#include <stdint.h>\n#include \"../lv_misc/lv_area.h\"\n#include \"../lv_misc/lv_task.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\nstruct _lv_obj_t;\nstruct _disp_t;\nstruct _lv_indev_t;\nstruct _lv_indev_drv_t;\n\n/** Possible input device types*/\nenum {\n    LV_INDEV_TYPE_NONE,    /**< Uninitialized state*/\n    LV_INDEV_TYPE_POINTER, /**< Touch pad, mouse, external button*/\n    LV_INDEV_TYPE_KEYPAD,  /**< Keypad or keyboard*/\n    LV_INDEV_TYPE_BUTTON,  /**< External (hardware button) which is assigned to a specific point of the\n                              screen*/\n    LV_INDEV_TYPE_ENCODER, /**< Encoder with only Left, Right turn and a Button*/\n};\ntypedef uint8_t lv_indev_type_t;\n\n/** States for input devices*/\nenum { LV_INDEV_STATE_REL = 0, LV_INDEV_STATE_PR };\ntypedef uint8_t lv_indev_state_t;\n\n/** Data structure passed to an input driver to fill */\ntypedef struct\n{\n    lv_point_t point; /**< For LV_INDEV_TYPE_POINTER the currently pressed point*/\n    uint32_t key;     /**< For LV_INDEV_TYPE_KEYPAD the currently pressed key*/\n    uint32_t btn_id;  /**< For LV_INDEV_TYPE_BUTTON the currently pressed button*/\n    int16_t enc_diff; /**< For LV_INDEV_TYPE_ENCODER number of steps since the previous read*/\n\n    lv_indev_state_t state; /**< LV_INDEV_STATE_REL or LV_INDEV_STATE_PR*/\n} lv_indev_data_t;\n\n/** Initialized by the user and registered by 'lv_indev_add()'*/\ntypedef struct _lv_indev_drv_t\n{\n\n    /**< Input device type*/\n    lv_indev_type_t type;\n\n    /**< Function pointer to read input device data.\n     * Return 'true' if there is more data to be read (buffered).\n     * Most drivers can safely return 'false' */\n    bool (*read_cb)(struct _lv_indev_drv_t * indev_drv, lv_indev_data_t * data);\n\n    /** Called when an action happened on the input device.\n     * The second parameter is the event from `lv_event_t`*/\n    void (*feedback_cb)(struct _lv_indev_drv_t *, uint8_t);\n\n#if LV_USE_USER_DATA\n    lv_indev_drv_user_data_t user_data;\n#endif\n\n    /**< Pointer to the assigned display*/\n    struct _disp_t * disp;\n\n    /**< Task to read the periodically read the input device*/\n    lv_task_t * read_task;\n\n    /**< Number of pixels to slide before actually drag the object*/\n    uint8_t drag_limit;\n\n    /**< Drag throw slow-down in [%]. Greater value means faster slow-down */\n    uint8_t drag_throw;\n\n    /**< Long press time in milliseconds*/\n    uint16_t long_press_time;\n\n    /**< Repeated trigger period in long press [ms] */\n    uint16_t long_press_rep_time;\n} lv_indev_drv_t;\n\n/** Run time data of input devices\n * Internally used by the library, you should not need to touch it.\n */\ntypedef struct _lv_indev_proc_t\n{\n    lv_indev_state_t state; /**< Current state of the input device. */\n    union\n    {\n        struct\n        { /*Pointer and button data*/\n            lv_point_t act_point; /**< Current point of input device. */\n            lv_point_t last_point; /**< Last point of input device. */\n            lv_point_t vect; /**< Difference between `act_point` and `last_point`. */\n            lv_point_t drag_sum; /*Count the dragged pixels to check LV_INDEV_DEF_DRAG_LIMIT*/\n            lv_point_t drag_throw_vect;\n            struct _lv_obj_t * act_obj;      /*The object being pressed*/\n            struct _lv_obj_t * last_obj;     /*The last obejct which was pressed (used by dragthrow and\n                                                other post-release event)*/\n            struct _lv_obj_t * last_pressed; /*The lastly pressed object*/\n\n            /*Flags*/\n            uint8_t drag_limit_out : 1;\n            uint8_t drag_in_prog : 1;\n        } pointer;\n        struct\n        { /*Keypad data*/\n            lv_indev_state_t last_state;\n            uint32_t last_key;\n        } keypad;\n    } types;\n\n    uint32_t pr_timestamp;         /**< Pressed time stamp*/\n    uint32_t longpr_rep_timestamp; /**< Long press repeat time stamp*/\n\n    /*Flags*/\n    uint8_t long_pr_sent : 1;\n    uint8_t reset_query : 1;\n    uint8_t disabled : 1;\n    uint8_t wait_until_release : 1;\n} lv_indev_proc_t;\n\nstruct _lv_obj_t;\nstruct _lv_group_t;\n\n/** The main input device descriptor with driver, runtime data ('proc') and some additional\n * information*/\ntypedef struct _lv_indev_t\n{\n    lv_indev_drv_t driver;\n    lv_indev_proc_t proc;\n    struct _lv_obj_t * cursor;     /**< Cursor for LV_INPUT_TYPE_POINTER*/\n    struct _lv_group_t * group;    /**< Keypad destination group*/\n    const lv_point_t * btn_points; /**< Array points assigned to the button ()screen will be pressed\n                                      here by the buttons*/\n} lv_indev_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Initialize an input device driver with default values.\n * It is used to surly have known values in the fields ant not memory junk.\n * After it you can set the fields.\n * @param driver pointer to driver variable to initialize\n */\nvoid lv_indev_drv_init(lv_indev_drv_t * driver);\n\n/**\n * Register an initialized input device driver.\n * @param driver pointer to an initialized 'lv_indev_drv_t' variable (can be local variable)\n * @return pointer to the new input device or NULL on error\n */\nlv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver);\n\n/**\n * Update the driver in run time.\n * @param indev pointer to a input device. (return value of `lv_indev_drv_register`)\n * @param new_drv pointer to the new driver\n */\nvoid lv_indev_drv_update(lv_indev_t * indev, lv_indev_drv_t * new_drv);\n\n/**\n * Get the next input device.\n * @param indev pointer to the current input device. NULL to initialize.\n * @return the next input devise or NULL if no more. Give the first input device when the parameter\n * is NULL\n */\nlv_indev_t * lv_indev_get_next(lv_indev_t * indev);\n\n/**\n * Read data from an input device.\n * @param indev pointer to an input device\n * @param data input device will write its data here\n * @return false: no more data; true: there more data to read (buffered)\n */\nbool lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_hal/lv_hal_tick.h",
    "content": "/**\n * @file lv_hal_tick.h\n * Provide access to the system tick with 1 millisecond resolution\n */\n\n#ifndef LV_HAL_TICK_H\n#define LV_HAL_TICK_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n#include <stdint.h>\n#include \"utils/types.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#ifndef LV_ATTRIBUTE_TICK_INC\n#define LV_ATTRIBUTE_TICK_INC\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n//! @cond Doxygen_Suppress\n\n/**\n * You have to call this function periodically\n * @param tick_period the call period of this function in milliseconds\n */\nLV_ATTRIBUTE_TICK_INC void lv_tick_inc(uint32_t tick_period);\n\n//! @endcond\n\n/**\n * Get the elapsed milliseconds since start up\n * @return the elapsed milliseconds\n */\nuint32_t lv_tick_get(void);\n\n/**\n * Get the elapsed milliseconds since a previous time stamp\n * @param prev_tick a previous time stamp (return value of systick_get() )\n * @return the elapsed milliseconds since 'prev_tick'\n */\nuint32_t lv_tick_elaps(uint32_t prev_tick);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_HAL_TICK_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_misc/lv_anim.h",
    "content": "/**\n * @file anim.h\n *\n */\n\n#ifndef ANIM_H\n#define ANIM_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#include <stdint.h>\n#include \"utils/types.h\"\n#include <string.h>\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/** Can be used to indicate if animations are enabled or disabled in a case*/\nenum {\n    LV_ANIM_OFF,\n    LV_ANIM_ON,\n};\n\ntypedef uint8_t lv_anim_enable_t;\n\n/** Type of the animated value*/\ntypedef lv_coord_t lv_anim_value_t;\n\n#if LV_USE_ANIMATION\n\nstruct _lv_anim_t;\n\n/** Generic prototype of \"animator\" functions.\n * First parameter is the variable to animate.\n * Second parameter is the value to set.\n * Compatible with `lv_xxx_set_yyy(obj, value)` functions\n * The `x` in `_xcb_t` means its not a fully generic prototype because\n * it doesn't receive `lv_anim_t *` as its first argument*/\ntypedef void (*lv_anim_exec_xcb_t)(void *, lv_anim_value_t);\n\n/** Same as `lv_anim_exec_xcb_t` but receives `lv_anim_t *` as the first parameter.\n * It's more consistent but less convenient. Might be used by binding generator functions.*/\ntypedef void (*lv_anim_custom_exec_cb_t)(struct _lv_anim_t *, lv_anim_value_t);\n\n/** Get the current value during an animation*/\ntypedef lv_anim_value_t (*lv_anim_path_cb_t)(const struct _lv_anim_t *);\n\n/** Callback to call when the animation is ready*/\ntypedef void (*lv_anim_ready_cb_t)(struct _lv_anim_t *);\n\n/** Describes an animation*/\ntypedef struct _lv_anim_t\n{\n    void * var;                  /**<Variable to animate*/\n    lv_anim_exec_xcb_t exec_cb;   /**< Function to execute to animate*/\n    lv_anim_path_cb_t path_cb;   /**< Function to get the steps of animations*/\n    lv_anim_ready_cb_t ready_cb; /**< Call it when the animation is ready*/\n    int32_t start;               /**< Start value*/\n    int32_t end;                 /**< End value*/\n    uint16_t time;               /**< Animation time in ms*/\n    int16_t act_time;            /**< Current time in animation. Set to negative to make delay.*/\n    uint16_t playback_pause;     /**< Wait before play back*/\n    uint16_t repeat_pause;       /**< Wait before repeat*/\n#if LV_USE_USER_DATA\n    lv_anim_user_data_t user_data; /**< Custom user data*/\n#endif\n\n    uint8_t playback : 1; /**< When the animation is ready play it back*/\n    uint8_t repeat : 1;   /**< Repeat the animation infinitely*/\n    /*Animation system use these - user shouldn't set*/\n    uint8_t playback_now : 1; /**< Play back is in progress*/\n    uint32_t has_run : 1;     /**< Indicates the animation has run in this round*/\n} lv_anim_t;\n\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Init. the animation module\n */\nvoid lv_anim_core_init(void);\n\n/**\n * Initialize an animation variable.\n * E.g.:\n * lv_anim_t a;\n * lv_anim_init(&a);\n * lv_anim_set_...(&a);\n * lv_anim_create(&a);\n * @param a pointer to an `lv_anim_t` variable to initialize\n */\nvoid lv_anim_init(lv_anim_t * a);\n\n/**\n * Set a variable to animate function to execute on `var`\n * @param a pointer to an initialized `lv_anim_t` variable\n * @param var pointer to a variable to animate\n * @param exec_cb a function to execute.\n *                LittelvGL's built-in functions can be used.\n *                E.g. lv_obj_set_x\n */\nstatic inline void lv_anim_set_exec_cb(lv_anim_t * a, void * var, lv_anim_exec_xcb_t exec_cb)\n{\n    a->var     = var;\n    a->exec_cb = exec_cb;\n}\n\n/**\n * Set the duration and delay of an animation\n * @param a pointer to an initialized `lv_anim_t` variable\n * @param duration duration of the animation in milliseconds\n * @param delay delay before the animation in milliseconds\n */\nstatic inline void lv_anim_set_time(lv_anim_t * a, uint16_t duration, uint16_t delay)\n{\n    a->time     = duration;\n    a->act_time = -delay;\n}\n\n/**\n * Set the start and end values of an animation\n * @param a pointer to an initialized `lv_anim_t` variable\n * @param start the start value\n * @param end the end value\n */\nstatic inline void lv_anim_set_values(lv_anim_t * a, lv_anim_value_t start, lv_anim_value_t end)\n{\n    a->start = start;\n    a->end   = end;\n}\n\n/**\n * Similar to `lv_anim_set_var_and_cb` but `lv_anim_custom_exec_cb_t` receives\n * `lv_anim_t * ` as its first parameter instead of `void *`.\n * This function might be used when LittlevGL is binded to other languages because\n * it's more consistent to have `lv_anim_t *` as first parameter.\n * @param a pointer to an initialized `lv_anim_t` variable\n * @param exec_cb a function to execute.\n */\nstatic inline void lv_anim_set_custom_exec_cb(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb)\n{\n    a->var     = a;\n    a->exec_cb = (lv_anim_exec_xcb_t)exec_cb;\n}\n\n/**\n * Set the path (curve) of the animation.\n * @param a pointer to an initialized `lv_anim_t` variable\n * @param path_cb a function the get the current value of the animation.\n *                The built in functions starts with `lv_anim_path_...`\n */\nstatic inline void lv_anim_set_path_cb(lv_anim_t * a, lv_anim_path_cb_t path_cb)\n{\n    a->path_cb = path_cb;\n}\n\n/**\n * Set a function call when the animation is ready\n * @param a pointer to an initialized `lv_anim_t` variable\n * @param ready_cb a function call when the animation is ready\n */\nstatic inline void lv_anim_set_ready_cb(lv_anim_t * a, lv_anim_ready_cb_t ready_cb)\n{\n    a->ready_cb = ready_cb;\n}\n\n/**\n * Make the animation to play back to when the forward direction is ready\n * @param a pointer to an initialized `lv_anim_t` variable\n * @param wait_time time in milliseconds to wait before starting the back direction\n */\nstatic inline void lv_anim_set_playback(lv_anim_t * a, uint16_t wait_time)\n{\n    a->playback       = 1;\n    a->playback_pause = wait_time;\n}\n\n/**\n * Disable playback. (Disabled after `lv_anim_init()`)\n * @param a pointer to an initialized `lv_anim_t` variable\n */\nstatic inline void lv_anim_clear_playback(lv_anim_t * a)\n{\n    a->playback = 0;\n}\n\n/**\n * Make the animation to start again when ready.\n * @param a pointer to an initialized `lv_anim_t` variable\n * @param wait_time time in milliseconds to wait before starting the animation again\n */\nstatic inline void lv_anim_set_repeat(lv_anim_t * a, uint16_t wait_time)\n{\n    a->repeat       = 1;\n    a->repeat_pause = wait_time;\n}\n\n/**\n * Disable repeat. (Disabled after `lv_anim_init()`)\n * @param a pointer to an initialized `lv_anim_t` variable\n */\nstatic inline void lv_anim_clear_repeat(lv_anim_t * a)\n{\n    a->repeat = 0;\n}\n\n/**\n * Create an animation\n * @param a an initialized 'anim_t' variable. Not required after call.\n */\nvoid lv_anim_create(lv_anim_t * a);\n\n/**\n * Delete an animation of a variable with a given animator function\n * @param var pointer to variable\n * @param exec_cb a function pointer which is animating 'var',\n *           or NULL to ignore it and delete all the animations of 'var\n * @return true: at least 1 animation is deleted, false: no animation is deleted\n */\nbool lv_anim_del(void * var, lv_anim_exec_xcb_t exec_cb);\n\n/**\n * Delete an aniamation by getting the animated variable from `a`.\n * Only animations with `exec_cb` will be deleted.\n * This function exist becasue it's logical that all anim functions receives an\n * `lv_anim_t` as their first parameter. It's not practical in C but might makes\n * the API more conequent and makes easier to genrate bindings.\n * @param a pointer to an animation.\n * @param exec_cb a function pointer which is animating 'var',\n *           or NULL to ignore it and delete all the animations of 'var\n * @return true: at least 1 animation is deleted, false: no animation is deleted\n */\nstatic inline bool lv_anim_custom_del(lv_anim_t * a, lv_anim_custom_exec_cb_t exec_cb)\n{\n    return lv_anim_del(a->var, (lv_anim_exec_xcb_t)exec_cb);\n}\n\n/**\n * Get the number of currently running animations\n * @return the number of running animations\n */\nuint16_t lv_anim_count_running(void);\n\n/**\n * Calculate the time of an animation with a given speed and the start and end values\n * @param speed speed of animation in unit/sec\n * @param start start value of the animation\n * @param end end value of the animation\n * @return the required time [ms] for the animation with the given parameters\n */\nuint16_t lv_anim_speed_to_time(uint16_t speed, lv_anim_value_t start, lv_anim_value_t end);\n\n/**\n * Calculate the current value of an animation applying linear characteristic\n * @param a pointer to an animation\n * @return the current value to set\n */\nlv_anim_value_t lv_anim_path_linear(const lv_anim_t * a);\n\n/**\n * Calculate the current value of an animation slowing down the start phase\n * @param a pointer to an animation\n * @return the current value to set\n */\nlv_anim_value_t lv_anim_path_ease_in(const lv_anim_t * a);\n\n/**\n * Calculate the current value of an animation slowing down the end phase\n * @param a pointer to an animation\n * @return the current value to set\n */\nlv_anim_value_t lv_anim_path_ease_out(const lv_anim_t * a);\n\n/**\n * Calculate the current value of an animation applying an \"S\" characteristic (cosine)\n * @param a pointer to an animation\n * @return the current value to set\n */\nlv_anim_value_t lv_anim_path_ease_in_out(const lv_anim_t * a);\n\n/**\n * Calculate the current value of an animation with overshoot at the end\n * @param a pointer to an animation\n * @return the current value to set\n */\nlv_anim_value_t lv_anim_path_overshoot(const lv_anim_t * a);\n\n/**\n * Calculate the current value of an animation with 3 bounces\n * @param a pointer to an animation\n * @return the current value to set\n */\nlv_anim_value_t lv_anim_path_bounce(const lv_anim_t * a);\n\n/**\n * Calculate the current value of an animation applying step characteristic.\n * (Set end value on the end of the animation)\n * @param a pointer to an animation\n * @return the current value to set\n */\nlv_anim_value_t lv_anim_path_step(const lv_anim_t * a);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_ANIMATION == 0*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_ANIM_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_misc/lv_area.h",
    "content": "/**\n * @file lv_area.h\n *\n */\n\n#ifndef LV_AREA_H\n#define LV_AREA_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#include <string.h>\n#include \"utils/types.h\"\n#include <stdint.h>\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n/*********************\n *      DEFINES\n *********************/\n/*To avoid overflow don't let the max ranges (reduce with 1000) */\n#define LV_COORD_MAX ((lv_coord_t)((uint32_t)((uint32_t)1 << (8 * sizeof(lv_coord_t) - 1)) - 1000))\n#define LV_COORD_MIN (-LV_COORD_MAX)\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**\n * Represents a point on the screen.\n */\n\n\ntypedef struct\n{\n    lv_coord_t x;\n    lv_coord_t y;\n} lv_point_t;\n\n/** Represents an area of the screen. */\ntypedef struct\n{\n    lv_coord_t x1;\n    lv_coord_t y1;\n    lv_coord_t x2;\n    lv_coord_t y2;\n} lv_area_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Initialize an area\n * @param area_p pointer to an area\n * @param x1 left coordinate of the area\n * @param y1 top coordinate of the area\n * @param x2 right coordinate of the area\n * @param y2 bottom coordinate of the area\n */\nvoid lv_area_set(lv_area_t * area_p, lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2);\n\n/**\n * Copy an area\n * @param dest pointer to the destination area\n * @param src pointer to the source area\n */\ninline static void lv_area_copy(lv_area_t * dest, const lv_area_t * src)\n{\n    memcpy(dest, src, sizeof(lv_area_t));\n}\n\n/**\n * Get the width of an area\n * @param area_p pointer to an area\n * @return the width of the area (if x1 == x2 -> width = 1)\n */\nstatic inline lv_coord_t lv_area_get_width(const lv_area_t * area_p)\n{\n    return area_p->x2 - area_p->x1 + 1;\n}\n\n/**\n * Get the height of an area\n * @param area_p pointer to an area\n * @return the height of the area (if y1 == y2 -> height = 1)\n */\nstatic inline lv_coord_t lv_area_get_height(const lv_area_t * area_p)\n{\n    return area_p->y2 - area_p->y1 + 1;\n}\n\n/**\n * Set the width of an area\n * @param area_p pointer to an area\n * @param w the new width of the area (w == 1 makes x1 == x2)\n */\nvoid lv_area_set_width(lv_area_t * area_p, lv_coord_t w);\n\n/**\n * Set the height of an area\n * @param area_p pointer to an area\n * @param h the new height of the area (h == 1 makes y1 == y2)\n */\nvoid lv_area_set_height(lv_area_t * area_p, lv_coord_t h);\n\n/**\n * Set the position of an area (width and height will be kept)\n * @param area_p pointer to an area\n * @param x the new x coordinate of the area\n * @param y the new y coordinate of the area\n */\nvoid lv_area_set_pos(lv_area_t * area_p, lv_coord_t x, lv_coord_t y);\n\n/**\n * Return with area of an area (x * y)\n * @param area_p pointer to an area\n * @return size of area\n */\nuint32_t lv_area_get_size(const lv_area_t * area_p);\n\n/**\n * Get the common parts of two areas\n * @param res_p pointer to an area, the result will be stored her\n * @param a1_p pointer to the first area\n * @param a2_p pointer to the second area\n * @return false: the two area has NO common parts, res_p is invalid\n */\nbool lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t * a2_p);\n\n/**\n * Join two areas into a third which involves the other two\n * @param res_p pointer to an area, the result will be stored here\n * @param a1_p pointer to the first area\n * @param a2_p pointer to the second area\n */\nvoid lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t * a2_p);\n\n/**\n * Check if a point is on an area\n * @param a_p pointer to an area\n * @param p_p pointer to a point\n * @return false:the point is out of the area\n */\nbool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p);\n\n/**\n * Check if two area has common parts\n * @param a1_p pointer to an area.\n * @param a2_p pointer to an other area\n * @return false: a1_p and a2_p has no common parts\n */\nbool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p);\n\n/**\n * Check if an area is fully on an other\n * @param ain_p pointer to an area which could be on aholder_p\n * @param aholder pointer to an area which could involve ain_p\n * @return\n */\nbool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_misc/lv_async.h",
    "content": "/**\n * @file lv_async.h\n *\n */\n\n#ifndef LV_ASYNC_H\n#define LV_ASYNC_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n\n#include \"lv_task.h\"\n#include \"lv_types.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**\n * Type for async callback.\n */\ntypedef void (*lv_async_cb_t)(void *);\n\ntypedef struct _lv_async_info_t {\n    lv_async_cb_t cb;\n    void *user_data;\n} lv_async_info_t;\n\nstruct _lv_obj_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Call an asynchronous function the next time lv_task_handler() is run. This function is likely to return\n * **before** the call actually happens!\n * @param task_xcb a callback which is the task itself.\n *                 (the 'x' in the argument name indicates that its not a fully generic function because it not follows\n *                  the `func_name(object, callback, ...)` convention)\n * @param user_data custom parameter\n */\nlv_res_t lv_async_call(lv_async_cb_t async_xcb, void * user_data);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_TEMPL_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_misc/lv_circ.h",
    "content": "/**\n * @file lv_circ.h\n *\n */\n\n#ifndef LV_CIRC_H\n#define LV_CIRC_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#include <stddef.h>\n#include \"lv_area.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_CIRC_OCT1_X(p) (p.x)\n#define LV_CIRC_OCT1_Y(p) (p.y)\n#define LV_CIRC_OCT2_X(p) (p.y)\n#define LV_CIRC_OCT2_Y(p) (p.x)\n#define LV_CIRC_OCT3_X(p) (-p.y)\n#define LV_CIRC_OCT3_Y(p) (p.x)\n#define LV_CIRC_OCT4_X(p) (-p.x)\n#define LV_CIRC_OCT4_Y(p) (p.y)\n#define LV_CIRC_OCT5_X(p) (-p.x)\n#define LV_CIRC_OCT5_Y(p) (-p.y)\n#define LV_CIRC_OCT6_X(p) (-p.y)\n#define LV_CIRC_OCT6_Y(p) (-p.x)\n#define LV_CIRC_OCT7_X(p) (p.y)\n#define LV_CIRC_OCT7_Y(p) (-p.x)\n#define LV_CIRC_OCT8_X(p) (p.x)\n#define LV_CIRC_OCT8_Y(p) (-p.y)\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Initialize the circle drawing\n * @param c pointer to a point. The coordinates will be calculated here\n * @param tmp point to a variable. It will store temporary data\n * @param radius radius of the circle\n */\nvoid lv_circ_init(lv_point_t * c, lv_coord_t * tmp, lv_coord_t radius);\n\n/**\n * Test the circle drawing is ready or not\n * @param c same as in circ_init\n * @return true if the circle is not ready yet\n */\nbool lv_circ_cont(lv_point_t * c);\n\n/**\n * Get the next point from the circle\n * @param c same as in circ_init. The next point stored here.\n * @param tmp same as in circ_init.\n */\nvoid lv_circ_next(lv_point_t * c, lv_coord_t * tmp);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_misc/lv_color.h",
    "content": "/**\n * @file lv_color.h\n *\n */\n\n#ifndef LV_COLOR_H\n#define LV_COLOR_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n/*Error checking*/\n#if LV_COLOR_DEPTH == 24\n#error \"LV_COLOR_DEPTH  24 is deprecated. Use LV_COLOR_DEPTH  32 instead (lv_conf.h)\"\n#endif\n\n#if LV_COLOR_DEPTH != 32 && LV_COLOR_SCREEN_TRANSP != 0\n#error \"LV_COLOR_SCREEN_TRANSP requires LV_COLOR_DEPTH == 32. Set it in lv_conf.h\"\n#endif\n\n#if LV_COLOR_DEPTH != 16 && LV_COLOR_16_SWAP != 0\n#error \"LV_COLOR_16_SWAP requires LV_COLOR_DEPTH == 16. Set it in lv_conf.h\"\n#endif\n\n#include <stdint.h>\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_COLOR_WHITE LV_COLOR_MAKE(0xFF, 0xFF, 0xFF)\n#define LV_COLOR_SILVER LV_COLOR_MAKE(0xC0, 0xC0, 0xC0)\n#define LV_COLOR_GRAY LV_COLOR_MAKE(0x80, 0x80, 0x80)\n#define LV_COLOR_BLACK LV_COLOR_MAKE(0x00, 0x00, 0x00)\n#define LV_COLOR_RED LV_COLOR_MAKE(0xFF, 0x00, 0x00)\n#define LV_COLOR_MAROON LV_COLOR_MAKE(0x80, 0x00, 0x00)\n#define LV_COLOR_YELLOW LV_COLOR_MAKE(0xFF, 0xFF, 0x00)\n#define LV_COLOR_OLIVE LV_COLOR_MAKE(0x80, 0x80, 0x00)\n#define LV_COLOR_LIME LV_COLOR_MAKE(0x00, 0xFF, 0x00)\n#define LV_COLOR_GREEN LV_COLOR_MAKE(0x00, 0x80, 0x00)\n#define LV_COLOR_CYAN LV_COLOR_MAKE(0x00, 0xFF, 0xFF)\n#define LV_COLOR_AQUA LV_COLOR_CYAN\n#define LV_COLOR_TEAL LV_COLOR_MAKE(0x00, 0x80, 0x80)\n#define LV_COLOR_BLUE LV_COLOR_MAKE(0x00, 0x00, 0xFF)\n#define LV_COLOR_NAVY LV_COLOR_MAKE(0x00, 0x00, 0x80)\n#define LV_COLOR_MAGENTA LV_COLOR_MAKE(0xFF, 0x00, 0xFF)\n#define LV_COLOR_PURPLE LV_COLOR_MAKE(0x80, 0x00, 0x80)\n#define LV_COLOR_ORANGE LV_COLOR_MAKE(0xFF, 0xA5, 0x00)\n\n/**\n * Opacity percentages.\n */\nenum {\n    LV_OPA_TRANSP = 0,\n    LV_OPA_0      = 0,\n    LV_OPA_10     = 25,\n    LV_OPA_20     = 51,\n    LV_OPA_30     = 76,\n    LV_OPA_40     = 102,\n    LV_OPA_50     = 127,\n    LV_OPA_60     = 153,\n    LV_OPA_70     = 178,\n    LV_OPA_80     = 204,\n    LV_OPA_90     = 229,\n    LV_OPA_100    = 255,\n    LV_OPA_COVER  = 255,\n};\n\n#define LV_OPA_MIN 16  /*Opacities below this will be transparent*/\n#define LV_OPA_MAX 251 /*Opacities above this will fully cover*/\n\n#if LV_COLOR_DEPTH == 1\n#define LV_COLOR_SIZE 8\n#elif LV_COLOR_DEPTH == 8\n#define LV_COLOR_SIZE 8\n#elif LV_COLOR_DEPTH == 16\n#define LV_COLOR_SIZE 16\n#elif LV_COLOR_DEPTH == 32\n#define LV_COLOR_SIZE 32\n#else\n#error \"Invalid LV_COLOR_DEPTH in lv_conf.h! Set it to 1, 8, 16 or 32!\"\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\ntypedef union\n{\n    uint8_t blue : 1;\n    uint8_t green : 1;\n    uint8_t red : 1;\n    uint8_t full : 1;\n} lv_color1_t;\n\ntypedef union\n{\n    struct\n    {\n        uint8_t blue : 2;\n        uint8_t green : 3;\n        uint8_t red : 3;\n    } ch;\n    uint8_t full;\n} lv_color8_t;\n\ntypedef union\n{\n    struct\n    {\n#if LV_COLOR_16_SWAP == 0\n        uint16_t blue : 5;\n        uint16_t green : 6;\n        uint16_t red : 5;\n#else\n        uint16_t green_h : 3;\n        uint16_t red : 5;\n        uint16_t blue : 5;\n        uint16_t green_l : 3;\n#endif\n    } ch;\n    uint16_t full;\n} lv_color16_t;\n\ntypedef union\n{\n    struct\n    {\n        uint8_t blue;\n        uint8_t green;\n        uint8_t red;\n        uint8_t alpha;\n    } ch;\n    uint32_t full;\n} lv_color32_t;\n\n#if LV_COLOR_DEPTH == 1\ntypedef uint8_t lv_color_int_t;\ntypedef lv_color1_t lv_color_t;\n#elif LV_COLOR_DEPTH == 8\ntypedef uint8_t lv_color_int_t;\ntypedef lv_color8_t lv_color_t;\n#elif LV_COLOR_DEPTH == 16\ntypedef uint16_t lv_color_int_t;\ntypedef lv_color16_t lv_color_t;\n#elif LV_COLOR_DEPTH == 32\ntypedef uint32_t lv_color_int_t;\ntypedef lv_color32_t lv_color_t;\n#else\n#error \"Invalid LV_COLOR_DEPTH in lv_conf.h! Set it to 1, 8, 16 or 32!\"\n#endif\n\ntypedef uint8_t lv_opa_t;\n\ntypedef struct\n{\n    uint16_t h;\n    uint8_t s;\n    uint8_t v;\n} lv_color_hsv_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/*In color conversations:\n * - When converting to bigger color type the LSB weight of 1 LSB is calculated\n *   E.g. 16 bit Red has 5 bits\n *         8 bit Red has 2 bits\n *        ----------------------\n *        8 bit red LSB = (2^5 - 1) / (2^2 - 1) = 31 / 3 = 10\n *\n * - When calculating to smaller color type simply shift out the LSBs\n *   E.g.  8 bit Red has 2 bits\n *        16 bit Red has 5 bits\n *        ----------------------\n *         Shift right with 5 - 3 = 2\n */\n\nstatic inline uint8_t lv_color_to1(lv_color_t color)\n{\n#if LV_COLOR_DEPTH == 1\n    return color.full;\n#elif LV_COLOR_DEPTH == 8\n    if((color.ch.red & 0x4) || (color.ch.green & 0x4) || (color.ch.blue & 0x2)) {\n        return 1;\n    } else {\n        return 0;\n    }\n#elif LV_COLOR_DEPTH == 16\n#if LV_COLOR_16_SWAP == 0\n    if((color.ch.red & 0x10) || (color.ch.green & 0x20) || (color.ch.blue & 0x10)) {\n        return 1;\n#else\n    if((color.ch.red & 0x10) || (color.ch.green_h & 0x20) || (color.ch.blue & 0x10)) {\n        return 1;\n#endif\n    } else {\n        return 0;\n    }\n#elif LV_COLOR_DEPTH == 32\n    if((color.ch.red & 0x80) || (color.ch.green & 0x80) || (color.ch.blue & 0x80)) {\n        return 1;\n    } else {\n        return 0;\n    }\n#endif\n}\n\nstatic inline uint8_t lv_color_to8(lv_color_t color)\n{\n#if LV_COLOR_DEPTH == 1\n    if(color.full == 0)\n        return 0;\n    else\n        return 0xFF;\n#elif LV_COLOR_DEPTH == 8\n    return color.full;\n#elif LV_COLOR_DEPTH == 16\n\n#if LV_COLOR_16_SWAP == 0\n    lv_color8_t ret;\n    ret.ch.red   = color.ch.red >> 2;   /* 5 - 3  = 2*/\n    ret.ch.green = color.ch.green >> 3; /* 6 - 3  = 3*/\n    ret.ch.blue  = color.ch.blue >> 3;  /* 5 - 2  = 3*/\n    return ret.full;\n#else\n    lv_color8_t ret;\n    ret.ch.red   = color.ch.red >> 2;  /* 5 - 3  = 2*/\n    ret.ch.green = color.ch.green_h;   /* 6 - 3  = 3*/\n    ret.ch.blue  = color.ch.blue >> 3; /* 5 - 2  = 3*/\n    return ret.full;\n#endif\n#elif LV_COLOR_DEPTH == 32\n    lv_color8_t ret;\n    ret.ch.red   = color.ch.red >> 5;   /* 8 - 3  = 5*/\n    ret.ch.green = color.ch.green >> 5; /* 8 - 3  = 5*/\n    ret.ch.blue  = color.ch.blue >> 6;  /* 8 - 2  = 6*/\n    return ret.full;\n#endif\n}\n\nstatic inline uint16_t lv_color_to16(lv_color_t color)\n{\n#if LV_COLOR_DEPTH == 1\n    if(color.full == 0)\n        return 0;\n    else\n        return 0xFFFF;\n#elif LV_COLOR_DEPTH == 8\n    lv_color16_t ret;\n#if LV_COLOR_16_SWAP == 0\n    ret.ch.red = color.ch.red * 4;     /*(2^5 - 1)/(2^3 - 1) = 31/7 = 4*/\n    ret.ch.green = color.ch.green * 9; /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/\n    ret.ch.blue = color.ch.blue * 10;  /*(2^5 - 1)/(2^2 - 1) = 31/3 = 10*/\n#else\n    ret.red        = color.ch.red * 4;\n    uint8_t g_tmp  = color.ch.green * 9;\n    ret.ch.green_h = (g_tmp & 0x1F) >> 3;\n    ret.ch.green_l = g_tmp & 0x07;\n    ret.ch.blue    = color.ch.blue * 10;\n#endif\n    return ret.full;\n#elif LV_COLOR_DEPTH == 16\n    return color.full;\n#elif LV_COLOR_DEPTH == 32\n    lv_color16_t ret;\n#if LV_COLOR_16_SWAP == 0\n    ret.ch.red   = color.ch.red >> 3;   /* 8 - 5  = 3*/\n    ret.ch.green = color.ch.green >> 2; /* 8 - 6  = 2*/\n    ret.ch.blue  = color.ch.blue >> 3;  /* 8 - 5  = 3*/\n#else\n    ret.ch.red     = color.ch.red >> 3;\n    ret.ch.green_h = (color.ch.green & 0xE0) >> 5;\n    ret.ch.green_l = (color.ch.green & 0x1C) >> 2;\n    ret.ch.blue    = color.ch.blue >> 3;\n#endif\n    return ret.full;\n#endif\n}\n\nstatic inline uint32_t lv_color_to32(lv_color_t color)\n{\n#if LV_COLOR_DEPTH == 1\n    if(color.full == 0)\n        return 0;\n    else\n        return 0xFFFFFFFF;\n#elif LV_COLOR_DEPTH == 8\n    lv_color32_t ret;\n    ret.ch.red = color.ch.red * 36;     /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/\n    ret.ch.green = color.ch.green * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/\n    ret.ch.blue = color.ch.blue * 85;   /*(2^8 - 1)/(2^2 - 1) = 255/3 = 85*/\n    ret.ch.alpha = 0xFF;\n    return ret.full;\n#elif LV_COLOR_DEPTH == 16\n#if LV_COLOR_16_SWAP == 0\n    lv_color32_t ret;\n    ret.ch.red   = color.ch.red * 8;   /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/\n    ret.ch.green = color.ch.green * 4; /*(2^8 - 1)/(2^6 - 1) = 255/63 = 4*/\n    ret.ch.blue  = color.ch.blue * 8;  /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/\n    ret.ch.alpha = 0xFF;\n    return ret.full;\n#else\n    lv_color32_t ret;\n    ret.ch.red   = color.ch.red * 8;                                 /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/\n    ret.ch.green = ((color.ch.green_h << 3) + color.ch.green_l) * 4; /*(2^8 - 1)/(2^6 - 1) = 255/63 = 4*/\n    ret.ch.blue  = color.ch.blue * 8;                                /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/\n    ret.ch.alpha = 0xFF;\n    return ret.full;\n#endif\n#elif LV_COLOR_DEPTH == 32\n    return color.full;\n#endif\n}\n\nstatic inline lv_color_t lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix)\n{\n    lv_color_t ret;\n#if LV_COLOR_DEPTH != 1\n    /*LV_COLOR_DEPTH == 8, 16 or 32*/\n    ret.ch.red = (uint16_t)((uint16_t)c1.ch.red * mix + (c2.ch.red * (255 - mix))) >> 8;\n#if LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP\n    /*If swapped Green is in 2 parts*/\n    uint16_t g_1   = (c1.ch.green_h << 3) + c1.ch.green_l;\n    uint16_t g_2   = (c2.ch.green_h << 3) + c2.ch.green_l;\n    uint16_t g_out = (uint16_t)((uint16_t)g_1 * mix + (g_2 * (255 - mix))) >> 8;\n    ret.ch.green_h = g_out >> 3;\n    ret.ch.green_l = g_out & 0x7;\n#else\n    ret.ch.green = (uint16_t)((uint16_t)c1.ch.green * mix + (c2.ch.green * (255 - mix))) >> 8;\n#endif\n    ret.ch.blue = (uint16_t)((uint16_t)c1.ch.blue * mix + (c2.ch.blue * (255 - mix))) >> 8;\n#if LV_COLOR_DEPTH == 32\n    ret.ch.alpha = 0xFF;\n#endif\n#else\n    /*LV_COLOR_DEPTH == 1*/\n    ret.full = mix > LV_OPA_50 ? c1.full : c2.full;\n#endif\n\n    return ret;\n}\n\n/**\n * Get the brightness of a color\n * @param color a color\n * @return the brightness [0..255]\n */\nstatic inline uint8_t lv_color_brightness(lv_color_t color)\n{\n    lv_color32_t c32;\n    c32.full        = lv_color_to32(color);\n    uint16_t bright = 3 * c32.ch.red + c32.ch.blue + 4 * c32.ch.green;\n    return (uint16_t)bright >> 3;\n}\n\n/* The most simple macro to create a color from R,G and B values */\n#if LV_COLOR_DEPTH == 1\n#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){(b8 >> 7 | g8 >> 7 | r8 >> 7)})\nstatic inline lv_color_t lv_color_make(int r8, int g8, int b8)\n{\n    lv_color_t color;\n    color.full = (b8 >> 7 | g8 >> 7 | r8 >> 7);\n    return color;\n}\n#elif LV_COLOR_DEPTH == 8\n#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 6, g8 >> 5, r8 >> 5}})\nstatic inline lv_color_t lv_color_make(uint8_t r8, int g8, int b8)\n{\n    lv_color_t color;\n    color.ch.blue = b8 >> 6;\n    color.ch.green = g8 >> 5;\n    color.ch.red = r8 >> 5;\n    return color;\n}\n#elif LV_COLOR_DEPTH == 16\n#if LV_COLOR_16_SWAP == 0\n#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 3, g8 >> 2, r8 >> 3}})\nstatic inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)\n{\n    lv_color_t color;\n    color.ch.blue  = (uint16_t)(b8 >> 3);\n    color.ch.green = (uint16_t)(g8 >> 2);\n    color.ch.red   = (uint16_t)(r8 >> 3);\n    return color;\n}\n#else\n#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{g8 >> 5, r8 >> 3, b8 >> 3, (g8 >> 2) & 0x7}})\nstatic inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)\n{\n    lv_color_t color;\n    color.ch.green_h = (uint16_t)(g8 >> 5);\n    color.ch.red = (uint16_t)(r8 >> 3);\n    color.ch.blue = (uint16_t)(b8 >> 3);\n    color.ch.green_l = (uint16_t)((g8 >> 2) & 0x7);\n    return color;\n}\n#endif\n#elif LV_COLOR_DEPTH == 32\n#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8, g8, r8, 0xff}}) /*Fix 0xff alpha*/\nstatic inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)\n{\n    lv_color_t color;\n    color.ch.blue  = b8;\n    color.ch.green = g8;\n    color.ch.red   = r8;\n    color.ch.alpha = 0xff;\n    return color;\n}\n#endif\n\nstatic inline lv_color_t lv_color_hex(uint32_t c)\n{\n    return lv_color_make((uint8_t)((c >> 16) & 0xFF), (uint8_t)((c >> 8) & 0xFF), (uint8_t)(c & 0xFF));\n}\n\nstatic inline lv_color_t lv_color_hex3(uint32_t c)\n{\n    return lv_color_make((uint8_t)(((c >> 4) & 0xF0) | ((c >> 8) & 0xF)), (uint8_t)((c & 0xF0) | ((c & 0xF0) >> 4)),\n                         (uint8_t)((c & 0xF) | ((c & 0xF) << 4)));\n}\n\n/**\n * Convert a HSV color to RGB\n * @param h hue [0..359]\n * @param s saturation [0..100]\n * @param v value [0..100]\n * @return the given RGB color in RGB (with LV_COLOR_DEPTH depth)\n */\nlv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v);\n\n/**\n * Convert an RGB color to HSV\n * @param r red\n * @param g green\n * @param b blue\n * @return the given RGB color n HSV\n */\nlv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*USE_COLOR*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_misc/lv_fs.h",
    "content": "/**\n * @file lv_fs.h\n *\n */\n\n#ifndef LV_FS_H\n#define LV_FS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_FILESYSTEM\n\n#include <stdint.h>\n#include \"utils/types.h\"\n#include \"lv_mem.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_FS_MAX_FN_LENGTH 64\n\n/**********************\n *      TYPEDEFS\n **********************/\n/**\n * Errors in the filesystem module.\n */\nenum {\n    LV_FS_RES_OK = 0,\n    LV_FS_RES_HW_ERR,     /*Low level hardware error*/\n    LV_FS_RES_FS_ERR,     /*Error in the file system structure */\n    LV_FS_RES_NOT_EX,     /*Driver, file or directory is not exists*/\n    LV_FS_RES_FULL,       /*Disk full*/\n    LV_FS_RES_LOCKED,     /*The file is already opened*/\n    LV_FS_RES_DENIED,     /*Access denied. Check 'fs_open' modes and write protect*/\n    LV_FS_RES_BUSY,       /*The file system now can't handle it, try later*/\n    LV_FS_RES_TOUT,       /*Process time outed*/\n    LV_FS_RES_NOT_IMP,    /*Requested function is not implemented*/\n    LV_FS_RES_OUT_OF_MEM, /*Not enough memory for an internal operation*/\n    LV_FS_RES_INV_PARAM,  /*Invalid parameter among arguments*/\n    LV_FS_RES_UNKNOWN,    /*Other unknown error*/\n};\ntypedef uint8_t lv_fs_res_t;\n\n/**\n * Filesystem mode.\n */\nenum {\n    LV_FS_MODE_WR = 0x01,\n    LV_FS_MODE_RD = 0x02,\n};\ntypedef uint8_t lv_fs_mode_t;\n\ntypedef struct _lv_fs_drv_t\n{\n    char letter;\n    uint16_t file_size;\n    uint16_t rddir_size;\n    bool (*ready_cb)(struct _lv_fs_drv_t * drv);\n\n    lv_fs_res_t (*open_cb)(struct _lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode);\n    lv_fs_res_t (*close_cb)(struct _lv_fs_drv_t * drv, void * file_p);\n    lv_fs_res_t (*remove_cb)(struct _lv_fs_drv_t * drv, const char * fn);\n    lv_fs_res_t (*read_cb)(struct _lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);\n    lv_fs_res_t (*write_cb)(struct _lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);\n    lv_fs_res_t (*seek_cb)(struct _lv_fs_drv_t * drv, void * file_p, uint32_t pos);\n    lv_fs_res_t (*tell_cb)(struct _lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);\n    lv_fs_res_t (*trunc_cb)(struct _lv_fs_drv_t * drv, void * file_p);\n    lv_fs_res_t (*size_cb)(struct _lv_fs_drv_t * drv, void * file_p, uint32_t * size_p);\n    lv_fs_res_t (*rename_cb)(struct _lv_fs_drv_t * drv, const char * oldname, const char * newname);\n    lv_fs_res_t (*free_space_cb)(struct _lv_fs_drv_t * drv, uint32_t * total_p, uint32_t * free_p);\n\n    lv_fs_res_t (*dir_open_cb)(struct _lv_fs_drv_t * drv, void * rddir_p, const char * path);\n    lv_fs_res_t (*dir_read_cb)(struct _lv_fs_drv_t * drv, void * rddir_p, char * fn);\n    lv_fs_res_t (*dir_close_cb)(struct _lv_fs_drv_t * drv, void * rddir_p);\n\n#if LV_USE_USER_DATA\n    lv_fs_drv_user_data_t user_data; /**< Custom file user data */\n#endif\n} lv_fs_drv_t;\n\ntypedef struct\n{\n    void * file_d;\n    lv_fs_drv_t * drv;\n} lv_fs_file_t;\n\ntypedef struct\n{\n    void * dir_d;\n    lv_fs_drv_t * drv;\n} lv_fs_dir_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Initialize the File system interface\n */\nvoid lv_fs_init(void);\n\n/**\n * Initialize a file system driver with default values.\n * It is used to surly have known values in the fields ant not memory junk.\n * After it you can set the fields.\n * @param drv pointer to driver variable to initialize\n */\nvoid lv_fs_drv_init(lv_fs_drv_t * drv);\n\n/**\n * Add a new drive\n * @param drv_p pointer to an lv_fs_drv_t structure which is inited with the\n * corresponding function pointers. The data will be copied so the variable can be local.\n */\nvoid lv_fs_drv_register(lv_fs_drv_t * drv_p);\n\n/**\n * Give a pointer to a driver from its letter\n * @param letter the driver letter\n * @return pointer to a driver or NULL if not found\n */\nlv_fs_drv_t * lv_fs_get_drv(char letter);\n\n/**\n * Test if a drive is rady or not. If the `ready` function was not initialized `true` will be\n * returned.\n * @param letter letter of the drive\n * @return true: drive is ready; false: drive is not ready\n */\nbool lv_fs_is_ready(char letter);\n\n/**\n * Open a file\n * @param file_p pointer to a lv_fs_file_t variable\n * @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt)\n * @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mode);\n\n/**\n * Close an already opened file\n * @param file_p pointer to a lv_fs_file_t variable\n * @return  LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_close(lv_fs_file_t * file_p);\n\n/**\n * Delete a file\n * @param path path of the file to delete\n * @return  LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_remove(const char * path);\n\n/**\n * Read from a file\n * @param file_p pointer to a lv_fs_file_t variable\n * @param buf pointer to a buffer where the read bytes are stored\n * @param btr Bytes To Read\n * @param br the number of real read bytes (Bytes Read). NULL if unused.\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_read(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t * br);\n\n/**\n * Write into a file\n * @param file_p pointer to a lv_fs_file_t variable\n * @param buf pointer to a buffer with the bytes to write\n * @param btr Bytes To Write\n * @param br the number of real written bytes (Bytes Written). NULL if unused.\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_write(lv_fs_file_t * file_p, const void * buf, uint32_t btw, uint32_t * bw);\n\n/**\n * Set the position of the 'cursor' (read write pointer) in a file\n * @param file_p pointer to a lv_fs_file_t variable\n * @param pos the new position expressed in bytes index (0: start of file)\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos);\n\n/**\n * Give the position of the read write pointer\n * @param file_p pointer to a lv_fs_file_t variable\n * @param pos_p pointer to store the position of the read write pointer\n * @return LV_FS_RES_OK or any error from 'fs_res_t'\n */\nlv_fs_res_t lv_fs_tell(lv_fs_file_t * file_p, uint32_t * pos);\n\n/**\n * Truncate the file size to the current position of the read write pointer\n * @param file_p pointer to an 'ufs_file_t' variable. (opened with lv_fs_open )\n * @return LV_FS_RES_OK: no error, the file is read\n *         any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_trunc(lv_fs_file_t * file_p);\n\n/**\n * Give the size of a file bytes\n * @param file_p pointer to a lv_fs_file_t variable\n * @param size pointer to a variable to store the size\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_size(lv_fs_file_t * file_p, uint32_t * size);\n\n/**\n * Rename a file\n * @param oldname path to the file\n * @param newname path with the new name\n * @return LV_FS_RES_OK or any error from 'fs_res_t'\n */\nlv_fs_res_t lv_fs_rename(const char * oldname, const char * newname);\n\n/**\n * Initialize a 'fs_dir_t' variable for directory reading\n * @param rddir_p pointer to a 'fs_read_dir_t' variable\n * @param path path to a directory\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path);\n\n/**\n * Read the next filename form a directory.\n * The name of the directories will begin with '/'\n * @param rddir_p pointer to an initialized 'fs_rdir_t' variable\n * @param fn pointer to a buffer to store the filename\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_dir_read(lv_fs_dir_t * rddir_p, char * fn);\n\n/**\n * Close the directory reading\n * @param rddir_p pointer to an initialized 'fs_dir_t' variable\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_dir_close(lv_fs_dir_t * rddir_p);\n\n/**\n * Get the free and total size of a driver in kB\n * @param letter the driver letter\n * @param total_p pointer to store the total size [kB]\n * @param free_p pointer to store the free size [kB]\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_free_space(char letter, uint32_t * total_p, uint32_t * free_p);\n\n/**\n * Fill a buffer with the letters of existing drivers\n * @param buf buffer to store the letters ('\\0' added after the last letter)\n * @return the buffer\n */\nchar * lv_fs_get_letters(char * buf);\n\n/**\n * Return with the extension of the filename\n * @param fn string with a filename\n * @return pointer to the beginning extension or empty string if no extension\n */\nconst char * lv_fs_get_ext(const char * fn);\n\n/**\n * Step up one level\n * @param path pointer to a file name\n * @return the truncated file name\n */\nchar * lv_fs_up(char * path);\n\n/**\n * Get the last element of a path (e.g. U:/folder/file -> file)\n * @param buf buffer to store the letters ('\\0' added after the last letter)\n * @return pointer to the beginning of the last element in the path\n */\nconst char * lv_fs_get_last(const char * path);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_FILESYSTEM*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_FS_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_misc/lv_gc.h",
    "content": "/**\n * @file lv_gc.h\n *\n */\n\n#ifndef LV_GC_H\n#define LV_GC_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#include <stdint.h>\n#include \"utils/types.h\"\n#include \"lv_mem.h\"\n#include \"lv_ll.h\"\n#include \"../lv_draw/lv_img_cache.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n#define LV_GC_ROOTS(prefix)                                                                                            \\\n    prefix lv_ll_t _lv_task_ll;  /*Linked list to store the lv_tasks*/                                                 \\\n    prefix lv_ll_t _lv_disp_ll;  /*Linked list of screens*/                                                            \\\n    prefix lv_ll_t _lv_indev_ll; /*Linked list of screens*/                                                            \\\n    prefix lv_ll_t _lv_drv_ll;                                                                                         \\\n    prefix lv_ll_t _lv_file_ll;                                                                                        \\\n    prefix lv_ll_t _lv_anim_ll;                                                                                        \\\n    prefix lv_ll_t _lv_group_ll;                                                                                       \\\n    prefix lv_ll_t _lv_img_defoder_ll;                                                                                 \\\n    prefix lv_img_cache_entry_t * _lv_img_cache_array;                                                                 \\\n    prefix void * _lv_task_act;                                                                                        \\\n    prefix void * _lv_draw_buf; \n\n#define LV_NO_PREFIX\n#define LV_ROOTS LV_GC_ROOTS(LV_NO_PREFIX)\n\n#if LV_ENABLE_GC == 1\n#if LV_MEM_CUSTOM != 1\n#error \"GC requires CUSTOM_MEM\"\n#endif /* LV_MEM_CUSTOM */\n#else  /* LV_ENABLE_GC */\n#define LV_GC_ROOT(x) x\nLV_GC_ROOTS(extern)\n#endif /* LV_ENABLE_GC */\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_GC_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_misc/lv_ll.h",
    "content": "/**\n * @file lv_ll.c\n * Handle linked lists. The nodes are dynamically allocated by the 'lv_mem' module.\n */\n\n#ifndef LV_LL_H\n#define LV_LL_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"lv_mem.h\"\n#include <stdint.h>\n#include <stddef.h>\n#include \"utils/types.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/** Dummy type to make handling easier*/\ntypedef uint8_t lv_ll_node_t;\n\n/** Description of a linked list*/\ntypedef struct\n{\n    uint32_t n_size;\n    lv_ll_node_t * head;\n    lv_ll_node_t * tail;\n} lv_ll_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Initialize linked list\n * @param ll_dsc pointer to ll_dsc variable\n * @param node_size the size of 1 node in bytes\n */\nvoid lv_ll_init(lv_ll_t * ll_p, uint32_t node_size);\n\n/**\n * Add a new head to a linked list\n * @param ll_p pointer to linked list\n * @return pointer to the new head\n */\nvoid * lv_ll_ins_head(lv_ll_t * ll_p);\n\n/**\n * Insert a new node in front of the n_act node\n * @param ll_p pointer to linked list\n * @param n_act pointer a node\n * @return pointer to the new head\n */\nvoid * lv_ll_ins_prev(lv_ll_t * ll_p, void * n_act);\n\n/**\n * Add a new tail to a linked list\n * @param ll_p pointer to linked list\n * @return pointer to the new tail\n */\nvoid * lv_ll_ins_tail(lv_ll_t * ll_p);\n\n/**\n * Remove the node 'node_p' from 'll_p' linked list.\n * It does not free the the memory of node.\n * @param ll_p pointer to the linked list of 'node_p'\n * @param node_p pointer to node in 'll_p' linked list\n */\nvoid lv_ll_rem(lv_ll_t * ll_p, void * node_p);\n\n/**\n * Remove and free all elements from a linked list. The list remain valid but become empty.\n * @param ll_p pointer to linked list\n */\nvoid lv_ll_clear(lv_ll_t * ll_p);\n\n/**\n * Move a node to a new linked list\n * @param ll_ori_p pointer to the original (old) linked list\n * @param ll_new_p pointer to the new linked list\n * @param node pointer to a node\n * @param head true: be the head in the new list\n *             false be the head in the new list\n */\nvoid lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node, bool head);\n\n/**\n * Return with head node of the linked list\n * @param ll_p pointer to linked list\n * @return pointer to the head of 'll_p'\n */\nvoid * lv_ll_get_head(const lv_ll_t * ll_p);\n\n/**\n * Return with tail node of the linked list\n * @param ll_p pointer to linked list\n * @return pointer to the head of 'll_p'\n */\nvoid * lv_ll_get_tail(const lv_ll_t * ll_p);\n\n/**\n * Return with the pointer of the next node after 'n_act'\n * @param ll_p pointer to linked list\n * @param n_act pointer a node\n * @return pointer to the next node\n */\nvoid * lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act);\n\n/**\n * Return with the pointer of the previous node after 'n_act'\n * @param ll_p pointer to linked list\n * @param n_act pointer a node\n * @return pointer to the previous node\n */\nvoid * lv_ll_get_prev(const lv_ll_t * ll_p, const void * n_act);\n\n/**\n * Return the length of the linked list.\n * @param ll_p pointer to linked list\n * @return length of the linked list\n */\nuint32_t lv_ll_get_len(const lv_ll_t * ll_p);\n\n/**\n * Move a nodw before an other node in the same linked list\n * @param ll_p pointer to a linked list\n * @param n_act pointer to node to move\n * @param n_after pointer to a node which should be after `n_act`\n */\nvoid lv_ll_move_before(lv_ll_t * ll_p, void * n_act, void * n_after);\n\n/**\n * Check if a linked list is empty\n * @param ll_p pointer to a linked list\n * @return true: the linked list is empty; false: not empty\n */\nbool lv_ll_is_empty(lv_ll_t * ll_p);\n/**********************\n *      MACROS\n **********************/\n\n#define LV_LL_READ(list, i) for(i = lv_ll_get_head(&list); i != NULL; i = lv_ll_get_next(&list, i))\n\n#define LV_LL_READ_BACK(list, i) for(i = lv_ll_get_tail(&list); i != NULL; i = lv_ll_get_prev(&list, i))\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_misc/lv_log.h",
    "content": "/**\n * @file lv_log.h\n *\n */\n\n#ifndef LV_LOG_H\n#define LV_LOG_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n#include <stdint.h>\n\n/*********************\n *      DEFINES\n *********************/\n\n/*Possible log level. For compatibility declare it independently from `LV_USE_LOG`*/\n\n#define LV_LOG_LEVEL_TRACE 0 /**< A lot of logs to give detailed information*/\n#define LV_LOG_LEVEL_INFO 1  /**< Log important events*/\n#define LV_LOG_LEVEL_WARN 2  /**< Log if something unwanted happened but didn't caused problem*/\n#define LV_LOG_LEVEL_ERROR 3 /**< Only critical issue, when the system may fail*/\n#define LV_LOG_LEVEL_NONE 4 /**< Do not log anything*/\n#define _LV_LOG_LEVEL_NUM 5 /**< Number of log levels */\n\ntypedef int8_t lv_log_level_t;\n\n#if LV_USE_LOG\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**\n * Log print function. Receives \"Log Level\", \"File path\", \"Line number\" and \"Description\".\n */\ntypedef void (*lv_log_print_g_cb_t)(lv_log_level_t level, const char *, uint32_t, const char *);\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Register custom print/write function to call when a log is added.\n * It can format its \"File path\", \"Line number\" and \"Description\" as required\n * and send the formatted log message to a consol or serial port.\n * @param print_cb a function pointer to print a log\n */\nvoid lv_log_register_print_cb(lv_log_print_g_cb_t print_cb);\n\n/**\n * Add a log\n * @param level the level of log. (From `lv_log_level_t` enum)\n * @param file name of the file when the log added\n * @param line line number in the source code where the log added\n * @param dsc description of the log\n */\nvoid lv_log_add(lv_log_level_t level, const char * file, int line, const char * dsc);\n\n/**********************\n *      MACROS\n **********************/\n\n#if LV_LOG_LEVEL <= LV_LOG_LEVEL_TRACE\n#define LV_LOG_TRACE(dsc) lv_log_add(LV_LOG_LEVEL_TRACE, __FILE__, __LINE__, dsc);\n#else\n#define LV_LOG_TRACE(dsc)                                                                                              \\\n    {                                                                                                                  \\\n        ;                                                                                                              \\\n    }\n#endif\n\n#if LV_LOG_LEVEL <= LV_LOG_LEVEL_INFO\n#define LV_LOG_INFO(dsc) lv_log_add(LV_LOG_LEVEL_INFO, __FILE__, __LINE__, dsc);\n#else\n#define LV_LOG_INFO(dsc)                                                                                               \\\n    {                                                                                                                  \\\n        ;                                                                                                              \\\n    }\n#endif\n\n#if LV_LOG_LEVEL <= LV_LOG_LEVEL_WARN\n#define LV_LOG_WARN(dsc) lv_log_add(LV_LOG_LEVEL_WARN, __FILE__, __LINE__, dsc);\n#else\n#define LV_LOG_WARN(dsc)                                                                                               \\\n    {                                                                                                                  \\\n        ;                                                                                                              \\\n    }\n#endif\n\n#if LV_LOG_LEVEL <= LV_LOG_LEVEL_ERROR\n#define LV_LOG_ERROR(dsc) lv_log_add(LV_LOG_LEVEL_ERROR, __FILE__, __LINE__, dsc);\n#else\n#define LV_LOG_ERROR(dsc)                                                                                              \\\n    {                                                                                                                  \\\n        ;                                                                                                              \\\n    }\n#endif\n\n#else /*LV_USE_LOG*/\n\n/*Do nothing if `LV_USE_LOG  0`*/\n#define lv_log_add(level, file, line, dsc)                                                                             \\\n    {                                                                                                                  \\\n        ;                                                                                                              \\\n    }\n#define LV_LOG_TRACE(dsc)                                                                                              \\\n    {                                                                                                                  \\\n        ;                                                                                                              \\\n    }\n#define LV_LOG_INFO(dsc)                                                                                               \\\n    {                                                                                                                  \\\n        ;                                                                                                              \\\n    }\n#define LV_LOG_WARN(dsc)                                                                                               \\\n    {                                                                                                                  \\\n        ;                                                                                                              \\\n    }\n#define LV_LOG_ERROR(dsc)                                                                                              \\\n    {                                                                                                                  \\\n        ;                                                                                                              \\\n    }\n#endif /*LV_USE_LOG*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_LOG_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_misc/lv_math.h",
    "content": "/**\n * @file math_base.h\n *\n */\n\n#ifndef LV_MATH_H\n#define LV_MATH_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#include <stdint.h>\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_MATH_MIN(a, b) ((a) < (b) ? (a) : (b))\n#define LV_MATH_MAX(a, b) ((a) > (b) ? (a) : (b))\n#define LV_MATH_ABS(x) ((x) > 0 ? (x) : (-(x)))\n\n#define LV_TRIGO_SIN_MAX 32767\n#define LV_TRIGO_SHIFT 15 /**<  >> LV_TRIGO_SHIFT to normalize*/\n\n#define LV_BEZIER_VAL_MAX 1024 /**< Max time in Bezier functions (not [0..1] to use integers) */\n#define LV_BEZIER_VAL_SHIFT 10 /**< log2(LV_BEZIER_VAL_MAX): used to normalize up scaled values*/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Return with sinus of an angle\n * @param angle\n * @return sinus of 'angle'. sin(-90) = -32767, sin(90) = 32767\n */\nint16_t lv_trigo_sin(int16_t angle);\n\n/**\n * Calculate a value of a Cubic Bezier function.\n * @param t time in range of [0..LV_BEZIER_VAL_MAX]\n * @param u0 start values in range of [0..LV_BEZIER_VAL_MAX]\n * @param u1 control value 1 values in range of [0..LV_BEZIER_VAL_MAX]\n * @param u2 control value 2 in range of [0..LV_BEZIER_VAL_MAX]\n * @param u3 end values in range of [0..LV_BEZIER_VAL_MAX]\n * @return the value calculated from the given parameters in range of [0..LV_BEZIER_VAL_MAX]\n */\nint32_t lv_bezier3(uint32_t t, int32_t u0, int32_t u1, int32_t u2, int32_t u3);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_misc/lv_mem.h",
    "content": "/**\n * @file lv_mem.h\n *\n */\n\n#ifndef LV_MEM_H\n#define LV_MEM_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#include <stdint.h>\n#include <stddef.h>\n#include \"lv_log.h\"\n\n/*********************\n *      DEFINES\n *********************/\n// Check windows\n#ifdef __WIN64\n#define LV_MEM_ENV64\n#endif\n\n// Check GCC\n#ifdef __GNUC__\n#if defined(__x86_64__) || defined(__ppc64__)\n#define LV_MEM_ENV64\n#endif\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**\n * Heap information structure.\n */\ntypedef struct\n{\n    uint32_t total_size; /**< Total heap size */\n    uint32_t free_cnt;\n    uint32_t free_size; /**< Size of available memory */\n    uint32_t free_biggest_size;\n    uint32_t used_cnt;\n    uint8_t used_pct; /**< Percentage used */\n    uint8_t frag_pct; /**< Amount of fragmentation */\n} lv_mem_monitor_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Initiaize the dyn_mem module (work memory and other variables)\n */\nvoid lv_mem_init(void);\n\n/**\n * Allocate a memory dynamically\n * @param size size of the memory to allocate in bytes\n * @return pointer to the allocated memory\n */\nvoid * lv_mem_alloc(uint32_t size);\n\n/**\n * Free an allocated data\n * @param data pointer to an allocated memory\n */\nvoid lv_mem_free(const void * data);\n\n/**\n * Reallocate a memory with a new size. The old content will be kept.\n * @param data pointer to an allocated memory.\n * Its content will be copied to the new memory block and freed\n * @param new_size the desired new size in byte\n * @return pointer to the new memory\n */\nvoid * lv_mem_realloc(void * data_p, uint32_t new_size);\n\n/**\n * Join the adjacent free memory blocks\n */\nvoid lv_mem_defrag(void);\n\n/**\n * Give information about the work memory of dynamic allocation\n * @param mon_p pointer to a dm_mon_p variable,\n *              the result of the analysis will be stored here\n */\nvoid lv_mem_monitor(lv_mem_monitor_t * mon_p);\n\n/**\n * Give the size of an allocated memory\n * @param data pointer to an allocated memory\n * @return the size of data memory in bytes\n */\nuint32_t lv_mem_get_size(const void * data);\n\n/**********************\n *      MACROS\n **********************/\n\n/**\n * Halt on NULL pointer\n * p pointer to a memory\n */\n#if LV_USE_LOG == 0\n#define lv_mem_assert(p)                                                                                               \\\n    {                                                                                                                  \\\n        if(p == NULL)                                                                                                  \\\n            while(1)                                                                                                   \\\n                ;                                                                                                      \\\n    }\n#else\n#define lv_mem_assert(p)                                                                                               \\\n    {                                                                                                                  \\\n        if(p == NULL) {                                                                                                \\\n            LV_LOG_ERROR(\"Out of memory!\");                                                                            \\\n            while(1)                                                                                                   \\\n                ;                                                                                                      \\\n        }                                                                                                              \\\n    }\n#endif\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_MEM_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_misc/lv_misc.mk",
    "content": "CSRCS += lv_circ.c\nCSRCS += lv_area.c\nCSRCS += lv_task.c\nCSRCS += lv_fs.c\nCSRCS += lv_anim.c\nCSRCS += lv_mem.c\nCSRCS += lv_ll.c\nCSRCS += lv_color.c\nCSRCS += lv_txt.c\nCSRCS += lv_math.c\nCSRCS += lv_log.c\nCSRCS += lv_gc.c\nCSRCS += lv_utils.c\nCSRCS += lv_async.c\n\nDEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_misc\nVPATH += :$(LVGL_DIR)/lvgl/src/lv_misc\n\nCFLAGS += \"-I$(LVGL_DIR)/lvgl/src/lv_misc\"\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_misc/lv_task.h",
    "content": "/**\n * @file lv_task.c\n * An 'lv_task'  is a void (*fp) (void* param) type function which will be called periodically.\n * A priority (5 levels + disable) can be assigned to lv_tasks.\n */\n\n#ifndef LV_TASK_H\n#define LV_TASK_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#include <stdint.h>\n#include \"utils/types.h\"\n#include \"lv_mem.h\"\n#include \"lv_ll.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#ifndef LV_ATTRIBUTE_TASK_HANDLER\n#define LV_ATTRIBUTE_TASK_HANDLER\n#endif\n/**********************\n *      TYPEDEFS\n **********************/\n\nstruct _lv_task_t;\n\n/**\n * Tasks execute this type type of functions.\n */\ntypedef void (*lv_task_cb_t)(struct _lv_task_t *);\n\n/**\n * Possible priorities for lv_tasks\n */\nenum {\n    LV_TASK_PRIO_OFF = 0,\n    LV_TASK_PRIO_LOWEST,\n    LV_TASK_PRIO_LOW,\n    LV_TASK_PRIO_MID,\n    LV_TASK_PRIO_HIGH,\n    LV_TASK_PRIO_HIGHEST,\n    _LV_TASK_PRIO_NUM,\n};\ntypedef uint8_t lv_task_prio_t;\n\n/**\n * Descriptor of a lv_task\n */\ntypedef struct _lv_task_t\n{\n    uint32_t period; /**< How often the task should run */\n    uint32_t last_run; /**< Last time the task ran */\n    lv_task_cb_t task_cb; /**< Task function */\n\n    void * user_data; /**< Custom user data */\n\n    uint8_t prio : 3; /**< Task priority */\n    uint8_t once : 1; /**< 1: one shot task */\n} lv_task_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Init the lv_task module\n */\nvoid lv_task_core_init(void);\n\n//! @cond Doxygen_Suppress\n\n/**\n * Call it  periodically to handle lv_tasks.\n */\nLV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void);\n\n//! @endcond\n\n/**\n * Create an \"empty\" task. It needs to initialzed with at least\n * `lv_task_set_cb` and `lv_task_set_period`\n * @return pointer to the craeted task\n */\nlv_task_t * lv_task_create_basic(void);\n\n/**\n * Create a new lv_task\n * @param task_xcb a callback which is the task itself. It will be called periodically.\n *                 (the 'x' in the argument name indicates that its not a fully generic function because it not follows\n *                  the `func_name(object, callback, ...)` convention)\n * @param period call period in ms unit\n * @param prio priority of the task (LV_TASK_PRIO_OFF means the task is stopped)\n * @param user_data custom parameter\n * @return pointer to the new task\n */\nlv_task_t * lv_task_create(lv_task_cb_t task_xcb, uint32_t period, lv_task_prio_t prio, void * user_data);\n\n/**\n * Delete a lv_task\n * @param task pointer to task_cb created by task\n */\nvoid lv_task_del(lv_task_t * task);\n\n/**\n * Set the callback the task (the function to call periodically)\n * @param task pointer to a task\n * @param task_cb the function to call periodically\n */\nvoid lv_task_set_cb(lv_task_t * task, lv_task_cb_t task_cb);\n\n/**\n * Set new priority for a lv_task\n * @param task pointer to a lv_task\n * @param prio the new priority\n */\nvoid lv_task_set_prio(lv_task_t * task, lv_task_prio_t prio);\n\n/**\n * Set new period for a lv_task\n * @param task pointer to a lv_task\n * @param period the new period\n */\nvoid lv_task_set_period(lv_task_t * task, uint32_t period);\n\n/**\n * Make a lv_task ready. It will not wait its period.\n * @param task pointer to a lv_task.\n */\nvoid lv_task_ready(lv_task_t * task);\n\n/**\n * Delete the lv_task after one call\n * @param task pointer to a lv_task.\n */\nvoid lv_task_once(lv_task_t * task);\n\n/**\n * Reset a lv_task.\n * It will be called the previously set period milliseconds later.\n * @param task pointer to a lv_task.\n */\nvoid lv_task_reset(lv_task_t * task);\n\n/**\n * Enable or disable the whole  lv_task handling\n * @param en: true: lv_task handling is running, false: lv_task handling is suspended\n */\nvoid lv_task_enable(bool en);\n\n/**\n * Get idle percentage\n * @return the lv_task idle in percentage\n */\nuint8_t lv_task_get_idle(void);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_misc/lv_templ.h",
    "content": "/**\n * @file lv_templ.h\n *\n */\n\n#ifndef LV_TEMPL_H\n#define LV_TEMPL_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_TEMPL_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_misc/lv_txt.h",
    "content": "/**\n * @file lv_text.h\n *\n */\n\n#ifndef LV_TXT_H\n#define LV_TXT_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#include \"utils/types.h\"\n#include \"lv_area.h\"\n#include \"lv_area.h\"\n#include \"../lv_font/lv_font.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_TXT_COLOR_CMD \"#\"\n\n#define LV_TXT_ENC_UTF8 1\n#define LV_TXT_ENC_ASCII 2\n\n/**********************\n *      TYPEDEFS\n **********************/\n/**\n * Options for text rendering.\n */\nenum {\n    LV_TXT_FLAG_NONE    = 0x00,\n    LV_TXT_FLAG_RECOLOR = 0x01, /**< Enable parsing of recolor command*/\n    LV_TXT_FLAG_EXPAND  = 0x02, /**< Ignore width to avoid automatic word wrapping*/\n    LV_TXT_FLAG_CENTER  = 0x04, /**< Align the text to the middle*/\n    LV_TXT_FLAG_RIGHT   = 0x08, /**< Align the text to the right*/\n};\ntypedef uint8_t lv_txt_flag_t;\n\n/**\n * State machine for text renderer. */\nenum {\n    LV_TXT_CMD_STATE_WAIT, /**< Waiting for command*/\n    LV_TXT_CMD_STATE_PAR,  /**< Processing the parameter*/\n    LV_TXT_CMD_STATE_IN,   /**< Processing the command*/\n};\ntypedef uint8_t lv_txt_cmd_state_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Get size of a text\n * @param size_res pointer to a 'point_t' variable to store the result\n * @param text pointer to a text\n * @param font pinter to font of the text\n * @param letter_space letter space of the text\n * @param line_space line space of the text\n * @param flags settings for the text from 'txt_flag_t' enum\n * @param max_width max with of the text (break the lines to fit this size) Set CORD_MAX to avoid\n * line breaks\n */\nvoid lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t * font, lv_coord_t letter_space,\n                     lv_coord_t line_space, lv_coord_t max_width, lv_txt_flag_t flag);\n\n/**\n * Get the next line of text. Check line length and break chars too.\n * @param txt a '\\0' terminated string\n * @param font pointer to a font\n * @param letter_space letter space\n * @param max_width max with of the text (break the lines to fit this size) Set CORD_MAX to avoid\n * line breaks\n * @param flags settings for the text from 'txt_flag_type' enum\n * @return the index of the first char of the new line (in byte index not letter index. With UTF-8\n * they are different)\n */\nuint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font, lv_coord_t letter_space, lv_coord_t max_width,\n                              lv_txt_flag_t flag);\n\n/**\n * Give the length of a text with a given font\n * @param txt a '\\0' terminate string\n * @param length length of 'txt' in byte count and not characters (Á is 1 character but 2 bytes in\n * UTF-8)\n * @param font pointer to a font\n * @param letter_space letter space\n * @param flags settings for the text from 'txt_flag_t' enum\n * @return length of a char_num long text\n */\nlv_coord_t lv_txt_get_width(const char * txt, uint16_t length, const lv_font_t * font, lv_coord_t letter_space,\n                            lv_txt_flag_t flag);\n\n/**\n * Check next character in a string and decide if te character is part of the command or not\n * @param state pointer to a txt_cmd_state_t variable which stores the current state of command\n * processing\n * @param c the current character\n * @return true: the character is part of a command and should not be written,\n *         false: the character should be written\n */\nbool lv_txt_is_cmd(lv_txt_cmd_state_t * state, uint32_t c);\n\n/**\n * Insert a string into an other\n * @param txt_buf the original text (must be big enough for the result text)\n * @param pos position to insert (0: before the original text, 1: after the first char etc.)\n * @param ins_txt text to insert\n */\nvoid lv_txt_ins(char * txt_buf, uint32_t pos, const char * ins_txt);\n\n/**\n * Delete a part of a string\n * @param txt string to modify\n * @param pos position where to start the deleting (0: before the first char, 1: after the first\n * char etc.)\n * @param len number of characters to delete\n */\nvoid lv_txt_cut(char * txt, uint32_t pos, uint32_t len);\n\n/***************************************************************\n *  GLOBAL FUNCTION POINTERS FOR CAHRACTER ENCODING INTERFACE\n ***************************************************************/\n\n/**\n * Give the size of an encoded character\n * @param str pointer to a character in a string\n * @return length of the encoded character (1,2,3 ...). O in invalid\n */\nextern uint8_t (*lv_txt_encoded_size)(const char *);\n\n/**\n * Convert an Unicode letter to encoded\n * @param letter_uni an Unicode letter\n * @return Encoded character in Little Endian to be compatible with C chars (e.g. 'Á', 'Ü')\n */\nextern uint32_t (*lv_txt_unicode_to_encoded)(uint32_t);\n\n/**\n * Convert a wide character, e.g. 'Á' little endian to be compatible with the encoded format.\n * @param c a wide character\n * @return `c` in the encoded format\n */\nextern uint32_t (*lv_txt_encoded_conv_wc)(uint32_t c);\n\n/**\n * Decode the next encoded character from a string.\n * @param txt pointer to '\\0' terminated string\n * @param i start index in 'txt' where to start.\n *                After the call it will point to the next encoded char in 'txt'.\n *                NULL to use txt[0] as index\n * @return the decoded Unicode character or 0 on invalid data code\n */\nextern uint32_t (*lv_txt_encoded_next)(const char *, uint32_t *);\n\n/**\n * Get the previous encoded character form a string.\n * @param txt pointer to '\\0' terminated string\n * @param i_start index in 'txt' where to start. After the call it will point to the previous\n * encoded char in 'txt'.\n * @return the decoded Unicode character or 0 on invalid data\n */\nextern uint32_t (*lv_txt_encoded_prev)(const char *, uint32_t *);\n\n/**\n * Convert a letter index (in an the encoded text) to byte index.\n * E.g. in UTF-8 \"AÁRT\" index of 'R' is 2 but start at byte 3 because 'Á' is 2 bytes long\n * @param txt a '\\0' terminated UTF-8 string\n * @param enc_id letter index\n * @return byte index of the 'enc_id'th letter\n */\nextern uint32_t (*lv_txt_encoded_get_byte_id)(const char *, uint32_t);\n\n/**\n * Convert a byte index (in an encoded text) to character index.\n * E.g. in UTF-8 \"AÁRT\" index of 'R' is 2 but start at byte 3 because 'Á' is 2 bytes long\n * @param txt a '\\0' terminated UTF-8 string\n * @param byte_id byte index\n * @return character index of the letter at 'byte_id'th position\n */\nextern uint32_t (*lv_encoded_get_char_id)(const char *, uint32_t);\n\n/**\n * Get the number of characters (and NOT bytes) in a string.\n * E.g. in UTF-8 \"ÁBC\" is 3 characters (but 4 bytes)\n * @param txt a '\\0' terminated char string\n * @return number of characters\n */\nextern uint32_t (*lv_txt_get_encoded_length)(const char *);\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*USE_TXT*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_misc/lv_types.h",
    "content": "/**\n * @file lv_types.h\n *\n */\n\n#ifndef LV_TYPES_H\n#define LV_TYPES_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**\n * LittlevGL error codes.\n */\nenum {\n    LV_RES_INV = 0, /*Typically indicates that the object is deleted (become invalid) in the action\n                       function or an operation was failed*/\n    LV_RES_OK,      /*The object is valid (no deleted) after the action*/\n};\ntypedef uint8_t lv_res_t;\n\ntypedef unsigned long int lv_uintptr_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_TYPES_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_misc/lv_utils.h",
    "content": "/**\n * @file lv_utils.h\n *\n */\n\n#ifndef LV_UTILS_H\n#define LV_UTILS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#include <stdint.h>\n#include <stddef.h>\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n/**\n * Convert a number to string\n * @param num a number\n * @param buf pointer to a `char` buffer. The result will be stored here (max 10 elements)\n * @return same as `buf` (just for convenience)\n */\nchar * lv_utils_num_to_str(int32_t num, char * buf);\n\n/** Searches base[0] to base[n - 1] for an item that matches *key.\n *\n * @note The function cmp must return negative if its first\n *  argument (the search key) is less that its second (a table entry),\n *  zero if equal, and positive if greater.\n *\n *  @note Items in the array must be in ascending order.\n *\n * @param key    Pointer to item being searched for\n * @param base   Pointer to first element to search\n * @param n      Number of elements\n * @param size   Size of each element\n * @param cmp    Pointer to comparison function (see #lv_font_codeCompare as a comparison function\n * example)\n *\n * @return a pointer to a matching item, or NULL if none exists.\n */\nvoid * lv_utils_bsearch(const void * key, const void * base, uint32_t n, uint32_t size,\n                        int32_t (*cmp)(const void * pRef, const void * pElement));\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_arc.h",
    "content": "/**\n * @file lv_arc.h\n *\n */\n\n#ifndef LV_ARC_H\n#define LV_ARC_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_ARC != 0\n\n#include \"../lv_core/lv_obj.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n/*Data of arc*/\ntypedef struct\n{\n    /*New data for this type */\n    lv_coord_t angle_start;\n    lv_coord_t angle_end;\n} lv_arc_ext_t;\n\n/*Styles*/\nenum {\n    LV_ARC_STYLE_MAIN,\n};\ntypedef uint8_t lv_arc_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a arc objects\n * @param par pointer to an object, it will be the parent of the new arc\n * @param copy pointer to a arc object, if not NULL then the new object will be copied from it\n * @return pointer to the created arc\n */\nlv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the start and end angles of an arc. 0 deg: bottom, 90 deg: right etc.\n * @param arc pointer to an arc object\n * @param start the start angle [0..360]\n * @param end the end angle [0..360]\n */\nvoid lv_arc_set_angles(lv_obj_t * arc, uint16_t start, uint16_t end);\n\n/**\n * Set a style of a arc.\n * @param arc pointer to arc object\n * @param type which style should be set\n * @param style pointer to a style\n *  */\nvoid lv_arc_set_style(lv_obj_t * arc, lv_arc_style_t type, const lv_style_t * style);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the start angle of an arc.\n * @param arc pointer to an arc object\n * @return the start angle [0..360]\n */\nuint16_t lv_arc_get_angle_start(lv_obj_t * arc);\n\n/**\n * Get the end angle of an arc.\n * @param arc pointer to an arc object\n * @return the end angle [0..360]\n */\nuint16_t lv_arc_get_angle_end(lv_obj_t * arc);\n\n/**\n * Get style of a arc.\n * @param arc pointer to arc object\n * @param type which style should be get\n * @return style pointer to the style\n *  */\nconst lv_style_t * lv_arc_get_style(const lv_obj_t * arc, lv_arc_style_t type);\n\n/*=====================\n * Other functions\n *====================*/\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_ARC*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_ARC_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_bar.h",
    "content": "/**\n * @file lv_bar.h\n *\n */\n\n#ifndef LV_BAR_H\n#define LV_BAR_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_BAR != 0\n\n#include \"../lv_core/lv_obj.h\"\n#include \"../lv_misc/lv_anim.h\"\n#include \"lv_cont.h\"\n#include \"lv_btn.h\"\n#include \"lv_label.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/** Bar animation start value. (Not the real value of the Bar just indicates process animation)*/\n#define LV_BAR_ANIM_STATE_START 0\n\n/** Bar animation end value.  (Not the real value of the Bar just indicates process animation)*/\n#define LV_BAR_ANIM_STATE_END 256\n\n/** Mark no animation is in progress */\n#define LV_BAR_ANIM_STATE_INV -1\n\n/** log2(LV_BAR_ANIM_STATE_END) used to normalize data*/\n#define LV_BAR_ANIM_STATE_NORM 8\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/** Data of bar*/\ntypedef struct\n{\n    /*No inherited ext, derived from the base object */\n\n    /*New data for this type */\n    int16_t cur_value; /*Current value of the bar*/\n    int16_t min_value; /*Minimum value of the bar*/\n    int16_t max_value; /*Maximum value of the bar*/\n#if LV_USE_ANIMATION\n    lv_anim_value_t anim_start;\n    lv_anim_value_t anim_end;\n    lv_anim_value_t anim_state;\n    lv_anim_value_t anim_time;\n#endif\n    uint8_t sym : 1;                /*Symmetric: means the center is around zero value*/\n    const lv_style_t * style_indic; /*Style of the indicator*/\n} lv_bar_ext_t;\n\n/** Bar styles. */\nenum {\n    LV_BAR_STYLE_BG, /** Bar background style. */\n    LV_BAR_STYLE_INDIC, /** Bar fill area style. */\n};\ntypedef uint8_t lv_bar_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a bar objects\n * @param par pointer to an object, it will be the parent of the new bar\n * @param copy pointer to a bar object, if not NULL then the new object will be copied from it\n * @return pointer to the created bar\n */\nlv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a new value on the bar\n * @param bar pointer to a bar object\n * @param value new value\n * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately\n */\nvoid lv_bar_set_value(lv_obj_t * bar, int16_t value, lv_anim_enable_t anim);\n\n/**\n * Set minimum and the maximum values of a bar\n * @param bar pointer to the bar object\n * @param min minimum value\n * @param max maximum value\n */\nvoid lv_bar_set_range(lv_obj_t * bar, int16_t min, int16_t max);\n\n/**\n * Make the bar symmetric to zero. The indicator will grow from zero instead of the minimum\n * position.\n * @param bar pointer to a bar object\n * @param en true: enable disable symmetric behavior; false: disable\n */\nvoid lv_bar_set_sym(lv_obj_t * bar, bool en);\n\n/**\n * Set the animation time of the bar\n * @param bar pointer to a bar object\n * @param anim_time the animation time in milliseconds.\n */\nvoid lv_bar_set_anim_time(lv_obj_t * bar, uint16_t anim_time);\n\n/**\n * Set a style of a bar\n * @param bar pointer to a bar object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_bar_set_style(lv_obj_t * bar, lv_bar_style_t type, const lv_style_t * style);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the value of a bar\n * @param bar pointer to a bar object\n * @return the value of the bar\n */\nint16_t lv_bar_get_value(const lv_obj_t * bar);\n\n/**\n * Get the minimum value of a bar\n * @param bar pointer to a bar object\n * @return the minimum value of the bar\n */\nint16_t lv_bar_get_min_value(const lv_obj_t * bar);\n\n/**\n * Get the maximum value of a bar\n * @param bar pointer to a bar object\n * @return the maximum value of the bar\n */\nint16_t lv_bar_get_max_value(const lv_obj_t * bar);\n\n/**\n * Get whether the bar is symmetric or not.\n * @param bar pointer to a bar object\n * @return true: symmetric is enabled; false: disable\n */\nbool lv_bar_get_sym(lv_obj_t * bar);\n\n/**\n * Get the animation time of the bar\n * @param bar pointer to a bar object\n * @return the animation time in milliseconds.\n */\nuint16_t lv_bar_get_anim_time(lv_obj_t * bar);\n\n/**\n * Get a style of a bar\n * @param bar pointer to a bar object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_bar_get_style(const lv_obj_t * bar, lv_bar_style_t type);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_BAR*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_BAR_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_btn.h",
    "content": "/**\n * @file lv_btn.h\n *\n */\n\n#ifndef LV_BTN_H\n#define LV_BTN_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_BTN != 0\n\n/*Testing of dependencies*/\n#if LV_USE_CONT == 0\n#error \"lv_btn: lv_cont is required. Enable it in lv_conf.h (LV_USE_CONT  1) \"\n#endif\n\n#include \"lv_cont.h\"\n#include \"../lv_core/lv_indev.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/** Possible states of a button.\n * It can be used not only by buttons but other button-like objects too*/\nenum {\n    /**Released*/\n    LV_BTN_STATE_REL,\n\n    /**Pressed*/\n    LV_BTN_STATE_PR,\n\n    /**Toggled released*/\n    LV_BTN_STATE_TGL_REL,\n\n    /**Toggled pressed*/\n    LV_BTN_STATE_TGL_PR,\n\n    /**Inactive*/\n    LV_BTN_STATE_INA,\n\n    /**Number of states*/\n    _LV_BTN_STATE_NUM,\n};\ntypedef uint8_t lv_btn_state_t;\n\n/** Extended data of button*/\ntypedef struct\n{\n    /** Ext. of ancestor*/\n    lv_cont_ext_t cont;\n\n    /*New data for this type */\n\n    /**Styles in each state*/\n    const lv_style_t * styles[_LV_BTN_STATE_NUM];\n#if LV_BTN_INK_EFFECT\n    /** [ms] Time of ink fill effect (0: disable ink effect)*/\n    uint16_t ink_in_time;\n\n    /** [ms] Wait before the ink disappears */\n    uint16_t ink_wait_time;\n\n    /** [ms] Time of ink disappearing*/\n    uint16_t ink_out_time;\n#endif\n\n    /** Current state of the button from 'lv_btn_state_t' enum*/\n    lv_btn_state_t state : 3;\n\n    /** 1: Toggle enabled*/\n    uint8_t toggle : 1;\n} lv_btn_ext_t;\n\n/**Styles*/\nenum {\n    /** Release style */\n    LV_BTN_STYLE_REL,\n\n    /**Pressed style*/\n    LV_BTN_STYLE_PR,\n\n    /** Toggle released style*/\n    LV_BTN_STYLE_TGL_REL,\n\n    /** Toggle pressed style */\n    LV_BTN_STYLE_TGL_PR,\n\n    /** Inactive style*/\n    LV_BTN_STYLE_INA,\n};\ntypedef uint8_t lv_btn_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a button object\n * @param par pointer to an object, it will be the parent of the new button\n * @param copy pointer to a button object, if not NULL then the new object will be copied from it\n * @return pointer to the created button\n */\nlv_obj_t * lv_btn_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Enable the toggled states. On release the button will change from/to toggled state.\n * @param btn pointer to a button object\n * @param tgl true: enable toggled states, false: disable\n */\nvoid lv_btn_set_toggle(lv_obj_t * btn, bool tgl);\n\n/**\n * Set the state of the button\n * @param btn pointer to a button object\n * @param state the new state of the button (from lv_btn_state_t enum)\n */\nvoid lv_btn_set_state(lv_obj_t * btn, lv_btn_state_t state);\n\n/**\n * Toggle the state of the button (ON->OFF, OFF->ON)\n * @param btn pointer to a button object\n */\nvoid lv_btn_toggle(lv_obj_t * btn);\n\n/**\n * Set the layout on a button\n * @param btn pointer to a button object\n * @param layout a layout from 'lv_cont_layout_t'\n */\nstatic inline void lv_btn_set_layout(lv_obj_t * btn, lv_layout_t layout)\n{\n    lv_cont_set_layout(btn, layout);\n}\n\n/**\n * Set the fit policy in all 4 directions separately.\n * It tells how to change the button size automatically.\n * @param btn pointer to a button object\n * @param left left fit policy from `lv_fit_t`\n * @param right right fit policy from `lv_fit_t`\n * @param top top fit policy from `lv_fit_t`\n * @param bottom bottom fit policy from `lv_fit_t`\n */\nstatic inline void lv_btn_set_fit4(lv_obj_t * btn, lv_fit_t left, lv_fit_t right, lv_fit_t top, lv_fit_t bottom)\n{\n    lv_cont_set_fit4(btn, left, right, top, bottom);\n}\n\n/**\n * Set the fit policy horizontally and vertically separately.\n * It tells how to change the button size automatically.\n * @param btn pointer to a button object\n * @param hor horizontal fit policy from `lv_fit_t`\n * @param ver vertical fit policy from `lv_fit_t`\n */\nstatic inline void lv_btn_set_fit2(lv_obj_t * btn, lv_fit_t hor, lv_fit_t ver)\n{\n    lv_cont_set_fit2(btn, hor, ver);\n}\n\n/**\n * Set the fit policy in all 4 direction at once.\n * It tells how to change the button size automatically.\n * @param btn pointer to a button object\n * @param fit fit policy from `lv_fit_t`\n */\nstatic inline void lv_btn_set_fit(lv_obj_t * btn, lv_fit_t fit)\n{\n    lv_cont_set_fit(btn, fit);\n}\n\n/**\n * Set time of the ink effect (draw a circle on click to animate in the new state)\n * @param btn pointer to a button object\n * @param time the time of the ink animation\n */\nvoid lv_btn_set_ink_in_time(lv_obj_t * btn, uint16_t time);\n\n/**\n * Set the wait time before the ink disappears\n * @param btn pointer to a button object\n * @param time the time of the ink animation\n */\nvoid lv_btn_set_ink_wait_time(lv_obj_t * btn, uint16_t time);\n\n/**\n * Set time of the ink out effect (animate to the released state)\n * @param btn pointer to a button object\n * @param time the time of the ink animation\n */\nvoid lv_btn_set_ink_out_time(lv_obj_t * btn, uint16_t time);\n\n/**\n * Set a style of a button.\n * @param btn pointer to button object\n * @param type which style should be set\n * @param style pointer to a style\n *  */\nvoid lv_btn_set_style(lv_obj_t * btn, lv_btn_style_t type, const lv_style_t * style);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the current state of the button\n * @param btn pointer to a button object\n * @return the state of the button (from lv_btn_state_t enum)\n */\nlv_btn_state_t lv_btn_get_state(const lv_obj_t * btn);\n\n/**\n * Get the toggle enable attribute of the button\n * @param btn pointer to a button object\n * @return true: toggle enabled, false: disabled\n */\nbool lv_btn_get_toggle(const lv_obj_t * btn);\n\n/**\n * Get the layout of a button\n * @param btn pointer to button object\n * @return the layout from 'lv_cont_layout_t'\n */\nstatic inline lv_layout_t lv_btn_get_layout(const lv_obj_t * btn)\n{\n    return lv_cont_get_layout(btn);\n}\n\n/**\n * Get the left fit mode\n * @param btn pointer to a button object\n * @return an element of `lv_fit_t`\n */\nstatic inline lv_fit_t lv_btn_get_fit_left(const lv_obj_t * btn)\n{\n    return lv_cont_get_fit_left(btn);\n}\n\n/**\n * Get the right fit mode\n * @param btn pointer to a button object\n * @return an element of `lv_fit_t`\n */\nstatic inline lv_fit_t lv_btn_get_fit_right(const lv_obj_t * btn)\n{\n    return lv_cont_get_fit_right(btn);\n}\n\n/**\n * Get the top fit mode\n * @param btn pointer to a button object\n * @return an element of `lv_fit_t`\n */\nstatic inline lv_fit_t lv_btn_get_fit_top(const lv_obj_t * btn)\n{\n    return lv_cont_get_fit_top(btn);\n}\n\n/**\n * Get the bottom fit mode\n * @param btn pointer to a button object\n * @return an element of `lv_fit_t`\n */\nstatic inline lv_fit_t lv_btn_get_fit_bottom(const lv_obj_t * btn)\n{\n    return lv_cont_get_fit_bottom(btn);\n}\n\n/**\n * Get time of the ink in effect (draw a circle on click to animate in the new state)\n * @param btn pointer to a button object\n * @return the time of the ink animation\n */\nuint16_t lv_btn_get_ink_in_time(const lv_obj_t * btn);\n\n/**\n * Get the wait time before the ink disappears\n * @param btn pointer to a button object\n * @return the time of the ink animation\n */\nuint16_t lv_btn_get_ink_wait_time(const lv_obj_t * btn);\n\n/**\n * Get time of the ink out effect (animate to the releases state)\n * @param btn pointer to a button object\n * @return the time of the ink animation\n */\nuint16_t lv_btn_get_ink_out_time(const lv_obj_t * btn);\n\n/**\n * Get style of a button.\n * @param btn pointer to button object\n * @param type which style should be get\n * @return style pointer to the style\n *  */\nconst lv_style_t * lv_btn_get_style(const lv_obj_t * btn, lv_btn_style_t type);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_BUTTON*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_BTN_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_btnm.h",
    "content": "/**\n * @file lv_btnm.h\n *\n */\n\n#ifndef LV_BTNM_H\n#define LV_BTNM_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_BTNM != 0\n\n#include \"../lv_core/lv_obj.h\"\n#include \"lv_label.h\"\n#include \"lv_btn.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_BTNM_WIDTH_MASK 0x0007\n#define LV_BTNM_BTN_NONE 0xFFFF\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/** Type to store button control bits (disabled, hidden etc.) */\nenum {\n    LV_BTNM_CTRL_HIDDEN     = 0x0008, /**< Button hidden */\n    LV_BTNM_CTRL_NO_REPEAT  = 0x0010, /**< Do not repeat press this button. */\n    LV_BTNM_CTRL_INACTIVE   = 0x0020, /**< Disable this button. */\n    LV_BTNM_CTRL_TGL_ENABLE = 0x0040, /**< Button *can* be toggled. */\n    LV_BTNM_CTRL_TGL_STATE  = 0x0080, /**< Button is currently toggled (e.g. checked). */\n    LV_BTNM_CTRL_CLICK_TRIG = 0x0100, /**< 1: Send LV_EVENT_SELECTED on CLICK, 0: Send LV_EVENT_SELECTED on PRESS*/\n};\ntypedef uint16_t lv_btnm_ctrl_t;\n\n/*Data of button matrix*/\ntypedef struct\n{\n    /*No inherited ext.*/ /*Ext. of ancestor*/\n    /*New data for this type */\n    const char ** map_p;                              /*Pointer to the current map*/\n    lv_area_t * button_areas;                         /*Array of areas of buttons*/\n    lv_btnm_ctrl_t * ctrl_bits;                       /*Array of control bytes*/\n    const lv_style_t * styles_btn[_LV_BTN_STATE_NUM]; /*Styles of buttons in each state*/\n    uint16_t btn_cnt;                                 /*Number of button in 'map_p'(Handled by the library)*/\n    uint16_t btn_id_pr;                               /*Index of the currently pressed button or LV_BTNM_BTN_NONE*/\n    uint16_t btn_id_act;    /*Index of the active button (being pressed/released etc) or LV_BTNM_BTN_NONE */\n    uint8_t recolor : 1;    /*Enable button recoloring*/\n    uint8_t one_toggle : 1; /*Single button toggled at once*/\n} lv_btnm_ext_t;\n\nenum {\n    LV_BTNM_STYLE_BG,\n    LV_BTNM_STYLE_BTN_REL,\n    LV_BTNM_STYLE_BTN_PR,\n    LV_BTNM_STYLE_BTN_TGL_REL,\n    LV_BTNM_STYLE_BTN_TGL_PR,\n    LV_BTNM_STYLE_BTN_INA,\n};\ntypedef uint8_t lv_btnm_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a button matrix objects\n * @param par pointer to an object, it will be the parent of the new button matrix\n * @param copy pointer to a button matrix object, if not NULL then the new object will be copied\n * from it\n * @return pointer to the created button matrix\n */\nlv_obj_t * lv_btnm_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a new map. Buttons will be created/deleted according to the map. The\n * button matrix keeps a reference to the map and so the string array must not\n * be deallocated during the life of the matrix.\n * @param btnm pointer to a button matrix object\n * @param map pointer a string array. The last string has to be: \"\". Use \"\\n\" to make a line break.\n */\nvoid lv_btnm_set_map(const lv_obj_t * btnm, const char * map[]);\n\n/**\n * Set the button control map (hidden, disabled etc.) for a button matrix. The\n * control map array will be copied and so may be deallocated after this\n * function returns.\n * @param btnm pointer to a button matrix object\n * @param ctrl_map pointer to an array of `lv_btn_ctrl_t` control bytes. The\n *                 length of the array and position of the elements must match\n *                 the number and order of the individual buttons (i.e. excludes\n *                 newline entries).\n *                 An element of the map should look like e.g.:\n *                 `ctrl_map[0] = width | LV_BTNM_CTRL_NO_REPEAT |  LV_BTNM_CTRL_TGL_ENABLE`\n */\nvoid lv_btnm_set_ctrl_map(const lv_obj_t * btnm, const lv_btnm_ctrl_t ctrl_map[]);\n\n/**\n * Set the pressed button i.e. visually highlight it.\n * Mainly used a when the btnm is in a group to show the selected button\n * @param btnm pointer to button matrix object\n * @param id index of the currently pressed button (`LV_BTNM_BTN_NONE` to unpress)\n */\nvoid lv_btnm_set_pressed(const lv_obj_t * btnm, uint16_t id);\n\n/**\n * Set a style of a button matrix\n * @param btnm pointer to a button matrix object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_btnm_set_style(lv_obj_t * btnm, lv_btnm_style_t type, const lv_style_t * style);\n\n/**\n * Enable recoloring of button's texts\n * @param btnm pointer to button matrix object\n * @param en true: enable recoloring; false: disable\n */\nvoid lv_btnm_set_recolor(const lv_obj_t * btnm, bool en);\n\n/**\n * Set the attributes of a button of the button matrix\n * @param btnm pointer to button matrix object\n * @param btn_id 0 based index of the button to modify. (Not counting new lines)\n */\nvoid lv_btnm_set_btn_ctrl(const lv_obj_t * btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl);\n\n/**\n * Clear the attributes of a button of the button matrix\n * @param btnm pointer to button matrix object\n * @param btn_id 0 based index of the button to modify. (Not counting new lines)\n */\nvoid lv_btnm_clear_btn_ctrl(const lv_obj_t * btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl);\n\n/**\n * Set the attributes of all buttons of a button matrix\n * @param btnm pointer to a button matrix object\n * @param ctrl attribute(s) to set from `lv_btnm_ctrl_t`. Values can be ORed.\n */\nvoid lv_btnm_set_btn_ctrl_all(lv_obj_t * btnm, lv_btnm_ctrl_t ctrl);\n\n/**\n * Clear the attributes of all buttons of a button matrix\n * @param btnm pointer to a button matrix object\n * @param ctrl attribute(s) to set from `lv_btnm_ctrl_t`. Values can be ORed.\n * @param en true: set the attributes; false: clear the attributes\n */\nvoid lv_btnm_clear_btn_ctrl_all(lv_obj_t * btnm, lv_btnm_ctrl_t ctrl);\n\n/**\n * Set a single buttons relative width.\n * This method will cause the matrix be regenerated and is a relatively\n * expensive operation. It is recommended that initial width be specified using\n * `lv_btnm_set_ctrl_map` and this method only be used for dynamic changes.\n * @param btnm pointer to button matrix object\n * @param btn_id 0 based index of the button to modify.\n * @param width Relative width compared to the buttons in the same row. [1..7]\n */\nvoid lv_btnm_set_btn_width(const lv_obj_t * btnm, uint16_t btn_id, uint8_t width);\n\n/**\n * Make the button matrix like a selector widget (only one button may be toggled at a time).\n *\n * Toggling must be enabled on the buttons you want to be selected with `lv_btnm_set_ctrl` or\n * `lv_btnm_set_btn_ctrl_all`.\n *\n * @param btnm Button matrix object\n * @param one_toggle Whether \"one toggle\" mode is enabled\n */\nvoid lv_btnm_set_one_toggle(lv_obj_t * btnm, bool one_toggle);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the current map of a button matrix\n * @param btnm pointer to a button matrix object\n * @return the current map\n */\nconst char ** lv_btnm_get_map_array(const lv_obj_t * btnm);\n\n/**\n * Check whether the button's text can use recolor or not\n * @param btnm pointer to button matrix object\n * @return true: text recolor enable; false: disabled\n */\nbool lv_btnm_get_recolor(const lv_obj_t * btnm);\n\n/**\n * Get the index of the lastly \"activated\" button by the user (pressed, released etc)\n * Useful in the the `event_cb` to get the text of the button, check if hidden etc.\n * @param btnm pointer to button matrix object\n * @return  index of the last released button (LV_BTNM_BTN_NONE: if unset)\n */\nuint16_t lv_btnm_get_active_btn(const lv_obj_t * btnm);\n\n/**\n * Get the text of the lastly \"activated\" button by the user (pressed, released etc)\n * Useful in the the `event_cb`\n * @param btnm pointer to button matrix object\n * @return text of the last released button (NULL: if unset)\n */\nconst char * lv_btnm_get_active_btn_text(const lv_obj_t * btnm);\n\n/**\n * Get the pressed button's index.\n * The button be really pressed by the user or manually set to pressed with `lv_btnm_set_pressed`\n * @param btnm pointer to button matrix object\n * @return  index of the pressed button (LV_BTNM_BTN_NONE: if unset)\n */\nuint16_t lv_btnm_get_pressed_btn(const lv_obj_t * btnm);\n\n/**\n * Get the button's text\n * @param btnm pointer to button matrix object\n * @param btn_id the index a button not counting new line characters. (The return value of\n * lv_btnm_get_pressed/released)\n * @return  text of btn_index` button\n */\nconst char * lv_btnm_get_btn_text(const lv_obj_t * btnm, uint16_t btn_id);\n\n/**\n * Get the whether a control value is enabled or disabled for button of a button matrix\n * @param btnm pointer to a button matrix object\n * @param btn_id the index a button not counting new line characters. (E.g. the return value of\n * lv_btnm_get_pressed/released)\n * @param ctrl control values to check (ORed value can be used)\n * @return true: long press repeat is disabled; false: long press repeat enabled\n */\nbool lv_btnm_get_btn_ctrl(lv_obj_t * btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl);\n\n/**\n * Get a style of a button matrix\n * @param btnm pointer to a button matrix object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_btnm_get_style(const lv_obj_t * btnm, lv_btnm_style_t type);\n\n/**\n * Find whether \"one toggle\" mode is enabled.\n * @param btnm Button matrix object\n * @return whether \"one toggle\" mode is enabled\n */\nbool lv_btnm_get_one_toggle(const lv_obj_t * btnm);\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_BTNM*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_BTNM_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_calendar.h",
    "content": "/**\n * @file lv_calendar.h\n *\n */\n\n#ifndef LV_CALENDAR_H\n#define LV_CALENDAR_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_CALENDAR != 0\n\n#include \"../lv_core/lv_obj.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**\n * Represents a date on the calendar object (platform-agnostic).\n */\ntypedef struct\n{\n    uint16_t year;\n    int8_t month;\n    int8_t day;\n} lv_calendar_date_t;\n\n/*Data of calendar*/\ntypedef struct\n{\n    /*None*/ /*Ext. of ancestor*/\n    /*New data for this type */\n    lv_calendar_date_t today;               /*Date of today*/\n    lv_calendar_date_t showed_date;         /*Currently visible month (day is ignored)*/\n    lv_calendar_date_t * highlighted_dates; /*Apply different style on these days (pointer to an\n                                               array defined by the user)*/\n    uint8_t highlighted_dates_num;          /*Number of elements in `highlighted_days`*/\n    int8_t btn_pressing;                    /*-1: prev month pressing, +1 next month pressing on the header*/\n    lv_calendar_date_t pressed_date;\n    const char ** day_names;   /*Pointer to an array with the name of the days (NULL: use default names)*/\n    const char ** month_names; /*Pointer to an array with the name of the month (NULL. use default names)*/\n\n    /*Styles*/\n    const lv_style_t * style_header;\n    const lv_style_t * style_header_pr;\n    const lv_style_t * style_day_names;\n    const lv_style_t * style_highlighted_days;\n    const lv_style_t * style_inactive_days;\n    const lv_style_t * style_week_box;\n    const lv_style_t * style_today_box;\n} lv_calendar_ext_t;\n\n/** Calendar styles*/\nenum {\n    LV_CALENDAR_STYLE_BG, /**< Background and \"normal\" date numbers style */\n    LV_CALENDAR_STYLE_HEADER, /** Calendar header style */\n    LV_CALENDAR_STYLE_HEADER_PR, /** Calendar header style (when pressed) */\n    LV_CALENDAR_STYLE_DAY_NAMES, /** Day name style */\n    LV_CALENDAR_STYLE_HIGHLIGHTED_DAYS, /** Highlighted day style */ \n    LV_CALENDAR_STYLE_INACTIVE_DAYS, /** Inactive day style */\n    LV_CALENDAR_STYLE_WEEK_BOX, /** Week highlight style */\n    LV_CALENDAR_STYLE_TODAY_BOX, /** Today highlight style */\n};\ntypedef uint8_t lv_calendar_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a calendar objects\n * @param par pointer to an object, it will be the parent of the new calendar\n * @param copy pointer to a calendar object, if not NULL then the new object will be copied from it\n * @return pointer to the created calendar\n */\nlv_obj_t * lv_calendar_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the today's date\n * @param calendar pointer to a calendar object\n * @param today pointer to an `lv_calendar_date_t` variable containing the date of today. The value\n * will be saved it can be local variable too.\n */\nvoid lv_calendar_set_today_date(lv_obj_t * calendar, lv_calendar_date_t * today);\n\n/**\n * Set the currently showed\n * @param calendar pointer to a calendar object\n * @param showed pointer to an `lv_calendar_date_t` variable containing the date to show. The value\n * will be saved it can be local variable too.\n */\nvoid lv_calendar_set_showed_date(lv_obj_t * calendar, lv_calendar_date_t * showed);\n\n/**\n * Set the the highlighted dates\n * @param calendar pointer to a calendar object\n * @param highlighted pointer to an `lv_calendar_date_t` array containing the dates. ONLY A POINTER\n * WILL BE SAVED! CAN'T BE LOCAL ARRAY.\n * @param date_num number of dates in the array\n */\nvoid lv_calendar_set_highlighted_dates(lv_obj_t * calendar, lv_calendar_date_t * highlighted, uint16_t date_num);\n\n/**\n * Set the name of the days\n * @param calendar pointer to a calendar object\n * @param day_names pointer to an array with the names. E.g. `const char * days[7] = {\"Sun\", \"Mon\",\n * ...}` Only the pointer will be saved so this variable can't be local which will be destroyed\n * later.\n */\nvoid lv_calendar_set_day_names(lv_obj_t * calendar, const char ** day_names);\n\n/**\n * Set the name of the month\n * @param calendar pointer to a calendar object\n * @param day_names pointer to an array with the names. E.g. `const char * days[12] = {\"Jan\", \"Feb\",\n * ...}` Only the pointer will be saved so this variable can't be local which will be destroyed\n * later.\n */\nvoid lv_calendar_set_month_names(lv_obj_t * calendar, const char ** day_names);\n\n/**\n * Set a style of a calendar.\n * @param calendar pointer to calendar object\n * @param type which style should be set\n * @param style pointer to a style\n *  */\nvoid lv_calendar_set_style(lv_obj_t * calendar, lv_calendar_style_t type, const lv_style_t * style);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the today's date\n * @param calendar pointer to a calendar object\n * @return return pointer to an `lv_calendar_date_t` variable containing the date of today.\n */\nlv_calendar_date_t * lv_calendar_get_today_date(const lv_obj_t * calendar);\n\n/**\n * Get the currently showed\n * @param calendar pointer to a calendar object\n * @return pointer to an `lv_calendar_date_t` variable containing the date is being shown.\n */\nlv_calendar_date_t * lv_calendar_get_showed_date(const lv_obj_t * calendar);\n\n/**\n * Get the the pressed date.\n * @param calendar pointer to a calendar object\n * @return pointer to an `lv_calendar_date_t` variable containing the pressed date.\n *         `NULL` if not date pressed (e.g. the header)\n */\nlv_calendar_date_t * lv_calendar_get_pressed_date(const lv_obj_t * calendar);\n\n/**\n * Get the the highlighted dates\n * @param calendar pointer to a calendar object\n * @return pointer to an `lv_calendar_date_t` array containing the dates.\n */\nlv_calendar_date_t * lv_calendar_get_highlighted_dates(const lv_obj_t * calendar);\n\n/**\n * Get the number of the highlighted dates\n * @param calendar pointer to a calendar object\n * @return number of highlighted days\n */\nuint16_t lv_calendar_get_highlighted_dates_num(const lv_obj_t * calendar);\n\n/**\n * Get the name of the days\n * @param calendar pointer to a calendar object\n * @return pointer to the array of day names\n */\nconst char ** lv_calendar_get_day_names(const lv_obj_t * calendar);\n\n/**\n * Get the name of the month\n * @param calendar pointer to a calendar object\n * @return pointer to the array of month names\n */\nconst char ** lv_calendar_get_month_names(const lv_obj_t * calendar);\n\n/**\n * Get style of a calendar.\n * @param calendar pointer to calendar object\n * @param type which style should be get\n * @return style pointer to the style\n *  */\nconst lv_style_t * lv_calendar_get_style(const lv_obj_t * calendar, lv_calendar_style_t type);\n\n/*=====================\n * Other functions\n *====================*/\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_CALENDAR*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_CALENDAR_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_canvas.h",
    "content": "/**\n * @file lv_canvas.h\n *\n */\n\n#ifndef LV_CANVAS_H\n#define LV_CANVAS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_CANVAS != 0\n\n#include \"../lv_core/lv_obj.h\"\n#include \"../lv_objx/lv_img.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n/*Data of canvas*/\ntypedef struct\n{\n    lv_img_ext_t img; /*Ext. of ancestor*/\n    /*New data for this type */\n    lv_img_dsc_t dsc;\n} lv_canvas_ext_t;\n\n/*Styles*/\nenum {\n    LV_CANVAS_STYLE_MAIN,\n};\ntypedef uint8_t lv_canvas_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a canvas object\n * @param par pointer to an object, it will be the parent of the new canvas\n * @param copy pointer to a canvas object, if not NULL then the new object will be copied from it\n * @return pointer to the created canvas\n */\nlv_obj_t * lv_canvas_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a buffer for the canvas.\n * @param buf a buffer where the content of the canvas will be.\n * The required size is (lv_img_color_format_get_px_size(cf) * w * h) / 8)\n * It can be allocated with `lv_mem_alloc()` or\n * it can be statically allocated array (e.g. static lv_color_t buf[100*50]) or\n * it can be an address in RAM or external SRAM\n * @param canvas pointer to a canvas object\n * @param w width of the canvas\n * @param h height of the canvas\n * @param cf color format. `LV_IMG_CF_...`\n */\nvoid lv_canvas_set_buffer(lv_obj_t * canvas, void * buf, lv_coord_t w, lv_coord_t h, lv_img_cf_t cf);\n\n/**\n * Set the color of a pixel on the canvas\n * @param canvas\n * @param x x coordinate of the point to set\n * @param y x coordinate of the point to set\n * @param c color of the point\n */\nvoid lv_canvas_set_px(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t c);\n\n/**\n * Set the palette color of a canvas with index format. Valid only for `LV_IMG_CF_INDEXED1/2/4/8`\n * @param canvas pointer to canvas object\n * @param id the palette color to set:\n *   - for `LV_IMG_CF_INDEXED1`: 0..1\n *   - for `LV_IMG_CF_INDEXED2`: 0..3\n *   - for `LV_IMG_CF_INDEXED4`: 0..15\n *   - for `LV_IMG_CF_INDEXED8`: 0..255\n * @param c the color to set\n */\nvoid lv_canvas_set_palette(lv_obj_t * canvas, uint8_t id, lv_color_t c);\n\n/**\n * Set a style of a canvas.\n * @param canvas pointer to canvas object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_canvas_set_style(lv_obj_t * canvas, lv_canvas_style_t type, const lv_style_t * style);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the color of a pixel on the canvas\n * @param canvas\n * @param x x coordinate of the point to set\n * @param y x coordinate of the point to set\n * @return color of the point\n */\nlv_color_t lv_canvas_get_px(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y);\n\n/**\n * Get the image of the canvas as a pointer to an `lv_img_dsc_t` variable.\n * @param canvas pointer to a canvas object\n * @return pointer to the image descriptor.\n */\nlv_img_dsc_t * lv_canvas_get_img(lv_obj_t * canvas);\n\n/**\n * Get style of a canvas.\n * @param canvas pointer to canvas object\n * @param type which style should be get\n * @return style pointer to the style\n */\nconst lv_style_t * lv_canvas_get_style(const lv_obj_t * canvas, lv_canvas_style_t type);\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Copy a buffer to the canvas\n * @param canvas pointer to a canvas object\n * @param to_copy buffer to copy. The color format has to match with the canvas's buffer color\n * format\n * @param x left side of the destination position\n * @param y top side of the destination position\n * @param w width of the buffer to copy\n * @param h height of the buffer to copy\n */\nvoid lv_canvas_copy_buf(lv_obj_t * canvas, const void * to_copy, lv_coord_t x, lv_coord_t y, lv_coord_t w,\n                        lv_coord_t h);\n\n/**\n * Rotate and image and store the result on a canvas.\n * @param canvas pointer to a canvas object\n * @param img pointer to an image descriptor.\n *             Can be the image descriptor of an other canvas too (`lv_canvas_get_img()`).\n * @param angle the angle of rotation (0..360);\n * @param offset_x offset X to tell where to put the result data on destination canvas\n * @param offset_y offset X to tell where to put the result data on destination canvas\n * @param pivot_x pivot X of rotation. Relative to the source canvas\n *                Set to `source width / 2` to rotate around the center\n * @param pivot_y pivot Y of rotation. Relative to the source canvas\n *                Set to `source height / 2` to rotate around the center\n */\nvoid lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle, lv_coord_t offset_x, lv_coord_t offset_y,\n                      int32_t pivot_x, int32_t pivot_y);\n\n/**\n * Fill the canvas with color\n * @param canvas pointer to a canvas\n * @param color the background color\n */\nvoid lv_canvas_fill_bg(lv_obj_t * canvas, lv_color_t color);\n\n/**\n * Draw a rectangle on the canvas\n * @param canvas pointer to a canvas object\n * @param x left coordinate of the rectangle\n * @param y top coordinate of the rectangle\n * @param w width of the rectangle\n * @param h height of the rectangle\n * @param style style of the rectangle (`body` properties are used except `padding`)\n */\nvoid lv_canvas_draw_rect(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h,\n                         const lv_style_t * style);\n\n/**\n * Draw a text on the canvas.\n * @param canvas pointer to a canvas object\n * @param x left coordinate of the text\n * @param y top coordinate of the text\n * @param max_w max width of the text. The text will be wrapped to fit into this size\n * @param style style of the text (`text` properties are used)\n * @param txt text to display\n * @param align align of the text (`LV_LABEL_ALIGN_LEFT/RIGHT/CENTER`)\n */\nvoid lv_canvas_draw_text(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t max_w, const lv_style_t * style,\n                         const char * txt, lv_label_align_t align);\n\n/**\n * Draw an image on the canvas\n * @param canvas pointer to a canvas object\n * @param src image source. Can be a pointer an `lv_img_dsc_t` variable or a path an image.\n * @param style style of the image (`image` properties are used)\n */\nvoid lv_canvas_draw_img(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, const void * src, const lv_style_t * style);\n\n/**\n * Draw a line on the canvas\n * @param canvas pointer to a canvas object\n * @param points point of the line\n * @param point_cnt number of points\n * @param style style of the line (`line` properties are used)\n */\nvoid lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t * points, uint32_t point_cnt, const lv_style_t * style);\n\n/**\n * Draw a polygon on the canvas\n * @param canvas pointer to a canvas object\n * @param points point of the polygon\n * @param point_cnt number of points\n * @param style style of the polygon (`body.main_color` and `body.opa` is used)\n */\nvoid lv_canvas_draw_polygon(lv_obj_t * canvas, const lv_point_t * points, uint32_t point_cnt, const lv_style_t * style);\n\n/**\n * Draw an arc on the canvas\n * @param canvas pointer to a canvas object\n * @param x origo x  of the arc\n * @param y origo y of the arc\n * @param r radius of the arc\n * @param start_angle start angle in degrees\n * @param end_angle end angle in degrees\n * @param style style of the polygon (`body.main_color` and `body.opa` is used)\n */\nvoid lv_canvas_draw_arc(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t r, int32_t start_angle,\n                        int32_t end_angle, const lv_style_t * style);\n\n/**********************\n *      MACROS\n **********************/\n#define LV_CANVAS_BUF_SIZE_TRUE_COLOR(w, h) ((LV_COLOR_SIZE / 8) * w * h)\n#define LV_CANVAS_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h) ((LV_COLOR_SIZE / 8) * w * h)\n#define LV_CANVAS_BUF_SIZE_TRUE_COLOR_ALPHA(w, h) (LV_IMG_PX_SIZE_ALPHA_BYTE * w * h)\n\n/*+ 1: to be sure no fractional row*/\n#define LV_CANVAS_BUF_SIZE_ALPHA_1BIT(w, h) ((((w / 8) + 1) * h))\n#define LV_CANVAS_BUF_SIZE_ALPHA_2BIT(w, h) ((((w / 4) + 1) * h))\n#define LV_CANVAS_BUF_SIZE_ALPHA_4BIT(w, h) ((((w / 2) + 1) * h))\n#define LV_CANVAS_BUF_SIZE_ALPHA_8BIT(w, h) ((w * h))\n\n/*4 * X: for palette*/\n#define LV_CANVAS_BUF_SIZE_INDEXED_1BIT(w, h) (LV_CANVAS_BUF_SIZE_ALPHA_1BIT(w, h) + 4 * 2)\n#define LV_CANVAS_BUF_SIZE_INDEXED_2BIT(w, h) (LV_CANVAS_BUF_SIZE_ALPHA_2BIT(w, h) + 4 * 4)\n#define LV_CANVAS_BUF_SIZE_INDEXED_4BIT(w, h) (LV_CANVAS_BUF_SIZE_ALPHA_4BIT(w, h) + 4 * 16)\n#define LV_CANVAS_BUF_SIZE_INDEXED_8BIT(w, h) (LV_CANVAS_BUF_SIZE_ALPHA_8BIT(w, h) + 4 * 256)\n\n#endif /*LV_USE_CANVAS*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_CANVAS_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_cb.h",
    "content": "/**\n * @file lv_cb.h\n *\n */\n\n#ifndef LV_CB_H\n#define LV_CB_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_CB != 0\n\n/*Testing of dependencies*/\n#if LV_USE_BTN == 0\n#error \"lv_cb: lv_btn is required. Enable it in lv_conf.h (LV_USE_BTN  1) \"\n#endif\n\n#if LV_USE_LABEL == 0\n#error \"lv_cb: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL  1) \"\n#endif\n\n#include \"../lv_core/lv_obj.h\"\n#include \"lv_btn.h\"\n#include \"lv_label.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/*Data of check box*/\ntypedef struct\n{\n    lv_btn_ext_t bg_btn; /*Ext. of ancestor*/\n    /*New data for this type */\n    lv_obj_t * bullet; /*Pointer to button*/\n    lv_obj_t * label;  /*Pointer to label*/\n} lv_cb_ext_t;\n\n/** Checkbox styles. */\nenum {\n    LV_CB_STYLE_BG, /**< Style of object background. */\n    LV_CB_STYLE_BOX_REL, /**< Style of box (released). */\n    LV_CB_STYLE_BOX_PR, /**< Style of box (pressed). */\n    LV_CB_STYLE_BOX_TGL_REL, /**< Style of box (released but checked). */\n    LV_CB_STYLE_BOX_TGL_PR, /**< Style of box (pressed and checked). */\n    LV_CB_STYLE_BOX_INA, /**< Style of disabled box */\n};\ntypedef uint8_t lv_cb_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a check box objects\n * @param par pointer to an object, it will be the parent of the new check box\n * @param copy pointer to a check box object, if not NULL then the new object will be copied from it\n * @return pointer to the created check box\n */\nlv_obj_t * lv_cb_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the text of a check box. `txt` will be copied and may be deallocated\n * after this function returns.\n * @param cb pointer to a check box\n * @param txt the text of the check box. NULL to refresh with the current text.\n */\nvoid lv_cb_set_text(lv_obj_t * cb, const char * txt);\n\n/**\n * Set the text of a check box. `txt` must not be deallocated during the life\n * of this checkbox.\n * @param cb pointer to a check box\n * @param txt the text of the check box. NULL to refresh with the current text.\n */\nvoid lv_cb_set_static_text(lv_obj_t * cb, const char * txt);\n\n/**\n * Set the state of the check box\n * @param cb pointer to a check box object\n * @param checked true: make the check box checked; false: make it unchecked\n */\nstatic inline void lv_cb_set_checked(lv_obj_t * cb, bool checked)\n{\n    lv_btn_set_state(cb, checked ? LV_BTN_STATE_TGL_REL : LV_BTN_STATE_REL);\n}\n\n/**\n * Make the check box inactive (disabled)\n * @param cb pointer to a check box object\n */\nstatic inline void lv_cb_set_inactive(lv_obj_t * cb)\n{\n    lv_btn_set_state(cb, LV_BTN_STATE_INA);\n}\n\n/**\n * Set a style of a check box\n * @param cb pointer to check box object\n * @param type which style should be set\n * @param style pointer to a style\n *  */\nvoid lv_cb_set_style(lv_obj_t * cb, lv_cb_style_t type, const lv_style_t * style);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the text of a check box\n * @param cb pointer to check box object\n * @return pointer to the text of the check box\n */\nconst char * lv_cb_get_text(const lv_obj_t * cb);\n\n/**\n * Get the current state of the check box\n * @param cb pointer to a check box object\n * @return true: checked; false: not checked\n */\nstatic inline bool lv_cb_is_checked(const lv_obj_t * cb)\n{\n    return lv_btn_get_state(cb) == LV_BTN_STATE_REL ? false : true;\n}\n\n/**\n * Get whether the check box is inactive or not.\n * @param cb pointer to a check box object\n * @return true: inactive; false: not inactive\n */\nstatic inline bool lv_cb_is_inactive(const lv_obj_t * cb)\n{\n    return lv_btn_get_state(cb) == LV_BTN_STATE_INA ? false : true;\n}\n\n/**\n * Get a style of a button\n * @param cb pointer to check box object\n * @param type which style should be get\n * @return style pointer to the style\n *  */\nconst lv_style_t * lv_cb_get_style(const lv_obj_t * cb, lv_cb_style_t type);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_CB*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_CB_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_chart.h",
    "content": "/**\n * @file lv_chart.h\n *\n */\n\n#ifndef LV_CHART_H\n#define LV_CHART_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_CHART != 0\n\n#include \"../lv_core/lv_obj.h\"\n#include \"lv_line.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**Default value of points. Can be used to not draw a point*/\n#define LV_CHART_POINT_DEF (LV_COORD_MIN)\n\n/**Automatically calculate the tick length*/\n#define LV_CHART_TICK_LENGTH_AUTO 255\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/** Chart types*/\nenum {\n    LV_CHART_TYPE_NONE           = 0x00, /**< Don't draw the series*/\n    LV_CHART_TYPE_LINE          = 0x01, /**< Connect the points with lines*/\n    LV_CHART_TYPE_COLUMN        = 0x02, /**< Draw columns*/\n    LV_CHART_TYPE_POINT         = 0x04, /**< Draw circles on the points*/\n    LV_CHART_TYPE_VERTICAL_LINE = 0x08, /**< Draw vertical lines on points (useful when chart width == point count)*/\n    LV_CHART_TYPE_AREA          = 0x10, /**< Draw area chart*/\n};\ntypedef uint8_t lv_chart_type_t;\n\n/** Chart update mode for `lv_chart_set_next`*/\nenum {\n    LV_CHART_UPDATE_MODE_SHIFT,     /**< Shift old data to the left and add the new one o the right*/\n    LV_CHART_UPDATE_MODE_CIRCULAR,  /**< Add the new data in a circular way*/\n};\ntypedef uint8_t lv_chart_update_mode_t;\n\ntypedef struct\n{\n    lv_coord_t * points;\n    lv_color_t color;\n    uint16_t start_point;\n} lv_chart_series_t;\n\n/** Data of axis */\nenum {\n    LV_CHART_AXIS_SKIP_LAST_TICK = 0x00,    /**< don't draw the last tick */\n    LV_CHART_AXIS_DRAW_LAST_TICK = 0x01     /**< draw the last tick */\n};\ntypedef uint8_t lv_chart_axis_options_t;\n\ntypedef struct\n{\n    const char * list_of_values;\n    lv_chart_axis_options_t options;\n    uint8_t num_tick_marks;\n    uint8_t major_tick_len;\n    uint8_t minor_tick_len;\n} lv_chart_axis_cfg_t;\n\n/*Data of chart */\ntypedef struct\n{\n    /*No inherited ext*/ /*Ext. of ancestor*/\n    /*New data for this type */\n    lv_ll_t series_ll;    /*Linked list for the data line pointers (stores lv_chart_dl_t)*/\n    lv_coord_t ymin;      /*y min value (used to scale the data)*/\n    lv_coord_t ymax;      /*y max value (used to scale the data)*/\n    uint8_t hdiv_cnt;     /*Number of horizontal division lines*/\n    uint8_t vdiv_cnt;     /*Number of vertical division lines*/\n    uint16_t point_cnt;   /*Point number in a data line*/\n    lv_chart_type_t type; /*Line, column or point chart (from 'lv_chart_type_t')*/\n    lv_chart_axis_cfg_t y_axis;\n    lv_chart_axis_cfg_t x_axis;\n    uint16_t margin;\n    uint8_t update_mode : 1;\n    struct\n    {\n        lv_coord_t width; /*Line width or point radius*/\n        uint8_t num;      /*Number of data lines in dl_ll*/\n        lv_opa_t opa;     /*Opacity of data lines*/\n        lv_opa_t dark;    /*Dark level of the point/column bottoms*/\n    } series;\n} lv_chart_ext_t;\n\nenum {\n    LV_CHART_STYLE_MAIN,\n};\ntypedef uint8_t lv_chart_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a chart background objects\n * @param par pointer to an object, it will be the parent of the new chart background\n * @param copy pointer to a chart background object, if not NULL then the new object will be copied\n * from it\n * @return pointer to the created chart background\n */\nlv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/**\n * Allocate and add a data series to the chart\n * @param chart pointer to a chart object\n * @param color color of the data series\n * @return pointer to the allocated data series\n */\nlv_chart_series_t * lv_chart_add_series(lv_obj_t * chart, lv_color_t color);\n\n/**\n * Clear the point of a serie\n * @param chart pointer to a chart object\n * @param serie pointer to the chart's serie to clear\n */\nvoid lv_chart_clear_serie(lv_obj_t * chart, lv_chart_series_t * serie);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the number of horizontal and vertical division lines\n * @param chart pointer to a graph background object\n * @param hdiv number of horizontal division lines\n * @param vdiv number of vertical division lines\n */\nvoid lv_chart_set_div_line_count(lv_obj_t * chart, uint8_t hdiv, uint8_t vdiv);\n\n/**\n * Set the minimal and maximal y values\n * @param chart pointer to a graph background object\n * @param ymin y minimum value\n * @param ymax y maximum value\n */\nvoid lv_chart_set_range(lv_obj_t * chart, lv_coord_t ymin, lv_coord_t ymax);\n\n/**\n * Set a new type for a chart\n * @param chart pointer to a chart object\n * @param type new type of the chart (from 'lv_chart_type_t' enum)\n */\nvoid lv_chart_set_type(lv_obj_t * chart, lv_chart_type_t type);\n\n/**\n * Set the number of points on a data line on a chart\n * @param chart pointer r to chart object\n * @param point_cnt new number of points on the data lines\n */\nvoid lv_chart_set_point_count(lv_obj_t * chart, uint16_t point_cnt);\n\n/**\n * Set the opacity of the data series\n * @param chart pointer to a chart object\n * @param opa opacity of the data series\n */\nvoid lv_chart_set_series_opa(lv_obj_t * chart, lv_opa_t opa);\n\n/**\n * Set the line width or point radius of the data series\n * @param chart pointer to a chart object\n * @param width the new width\n */\nvoid lv_chart_set_series_width(lv_obj_t * chart, lv_coord_t width);\n\n/**\n * Set the dark effect on the bottom of the points or columns\n * @param chart pointer to a chart object\n * @param dark_eff dark effect level (LV_OPA_TRANSP to turn off)\n */\nvoid lv_chart_set_series_darking(lv_obj_t * chart, lv_opa_t dark_eff);\n\n/**\n * Initialize all data points with a value\n * @param chart pointer to chart object\n * @param ser pointer to a data series on 'chart'\n * @param y the new value  for all points\n */\nvoid lv_chart_init_points(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y);\n\n/**\n * Set the value of points from an array\n * @param chart pointer to chart object\n * @param ser pointer to a data series on 'chart'\n * @param y_array array of 'lv_coord_t' points (with 'points count' elements )\n */\nvoid lv_chart_set_points(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y_array[]);\n\n/**\n * Shift all data right and set the most right data on a data line\n * @param chart pointer to chart object\n * @param ser pointer to a data series on 'chart'\n * @param y the new value of the most right data\n */\nvoid lv_chart_set_next(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y);\n\n/**\n * Set update mode of the chart object.\n * @param chart pointer to a chart object\n * @param update mode\n */\nvoid lv_chart_set_update_mode(lv_obj_t * chart, lv_chart_update_mode_t update_mode);\n\n/**\n * Set the style of a chart\n * @param chart pointer to a chart object\n * @param type which style should be set (can be only `LV_CHART_STYLE_MAIN`)\n * @param style pointer to a style\n */\nstatic inline void lv_chart_set_style(lv_obj_t * chart, lv_chart_style_t type, const lv_style_t * style)\n{\n    (void)type; /*Unused*/\n    lv_obj_set_style(chart, style);\n}\n\n/**\n * Set the length of the tick marks on the x axis\n * @param chart pointer to the chart\n * @param major_tick_len the length of the major tick or `LV_CHART_TICK_LENGTH_AUTO` to set automatically\n *                       (where labels are added)\n * @param minor_tick_len the length of the minor tick, `LV_CHART_TICK_LENGTH_AUTO` to set automatically\n *                       (where no labels are added)\n */\nvoid lv_chart_set_x_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_t minor_tick_len);\n\n/**\n * Set the length of the tick marks on the y axis\n * @param chart pointer to the chart\n * @param major_tick_len the length of the major tick or `LV_CHART_TICK_LENGTH_AUTO` to set automatically\n *                       (where labels are added)\n * @param minor_tick_len the length of the minor tick, `LV_CHART_TICK_LENGTH_AUTO` to set automatically\n *                       (where no labels are added)\n */\nvoid lv_chart_set_y_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_t minor_tick_len);\n\n/**\n * Set the x-axis tick count and labels of a chart\n * @param chart             pointer to a chart object\n * @param list_of_values    list of string values, terminated with \\n, except the last\n * @param num_tick_marks    if list_of_values is NULL: total number of ticks per axis\n *                          else number of ticks between two value labels\n * @param options           extra options\n */\nvoid lv_chart_set_x_tick_texts(lv_obj_t * chart, const char * list_of_values, uint8_t num_tick_marks,\n                               lv_chart_axis_options_t options);\n\n/**\n * Set the y-axis tick count and labels of a chart\n * @param chart             pointer to a chart object\n * @param list_of_values    list of string values, terminated with \\n, except the last\n * @param num_tick_marks    if list_of_values is NULL: total number of ticks per axis\n *                          else number of ticks between two value labels\n * @param options           extra options\n */\nvoid lv_chart_set_y_tick_texts(lv_obj_t * chart, const char * list_of_values, uint8_t num_tick_marks,\n                               lv_chart_axis_options_t options);\n\n/**\n * Set the margin around the chart, used for axes value and ticks\n * @param chart     pointer to an chart object\n * @param margin    value of the margin [px]\n */\nvoid lv_chart_set_margin(lv_obj_t * chart, uint16_t margin);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the type of a chart\n * @param chart pointer to chart object\n * @return type of the chart (from 'lv_chart_t' enum)\n */\nlv_chart_type_t lv_chart_get_type(const lv_obj_t * chart);\n\n/**\n * Get the data point number per data line on chart\n * @param chart pointer to chart object\n * @return point number on each data line\n */\nuint16_t lv_chart_get_point_cnt(const lv_obj_t * chart);\n\n/**\n * Get the opacity of the data series\n * @param chart pointer to chart object\n * @return the opacity of the data series\n */\nlv_opa_t lv_chart_get_series_opa(const lv_obj_t * chart);\n\n/**\n * Get the data series width\n * @param chart pointer to chart object\n * @return the width the data series (lines or points)\n */\nlv_coord_t lv_chart_get_series_width(const lv_obj_t * chart);\n\n/**\n * Get the dark effect level on the bottom of the points or columns\n * @param chart pointer to chart object\n * @return dark effect level (LV_OPA_TRANSP to turn off)\n */\nlv_opa_t lv_chart_get_series_darking(const lv_obj_t * chart);\n\n/**\n * Get the style of an chart object\n * @param chart pointer to an chart object\n * @param type which style should be get (can be only `LV_CHART_STYLE_MAIN`)\n * @return pointer to the chart's style\n */\nstatic inline const lv_style_t * lv_chart_get_style(const lv_obj_t * chart, lv_chart_style_t type)\n{\n    (void)type; /*Unused*/\n    return lv_obj_get_style(chart);\n}\n\n/**\n * Get the margin around the chart, used for axes value and labels\n * @param chart pointer to an chart object\n * @param return value of the margin\n */\nuint16_t lv_chart_get_margin(lv_obj_t * chart);\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Refresh a chart if its data line has changed\n * @param chart pointer to chart object\n */\nvoid lv_chart_refresh(lv_obj_t * chart);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_CHART*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_CHART_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_cont.h",
    "content": "/**\n * @file lv_cont.h\n *\n */\n\n#ifndef LV_CONT_H\n#define LV_CONT_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_CONT != 0\n\n#include \"../lv_core/lv_obj.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/** Container layout options*/\nenum {\n    LV_LAYOUT_OFF = 0, /**< No layout */\n    LV_LAYOUT_CENTER, /**< Center objects */\n    LV_LAYOUT_COL_L,  /**< Column left align*/\n    LV_LAYOUT_COL_M,  /**< Column middle align*/\n    LV_LAYOUT_COL_R,  /**< Column right align*/\n    LV_LAYOUT_ROW_T,  /**< Row top align*/\n    LV_LAYOUT_ROW_M,  /**< Row middle align*/\n    LV_LAYOUT_ROW_B,  /**< Row bottom align*/\n    LV_LAYOUT_PRETTY, /**< Put as many object as possible in row and begin a new row*/\n    LV_LAYOUT_GRID,   /**< Align same-sized object into a grid*/\n    _LV_LAYOUT_NUM\n};\ntypedef uint8_t lv_layout_t;\n\n/**\n * How to resize the container around the children.\n */\nenum {\n    LV_FIT_NONE,  /**< Do not change the size automatically*/\n    LV_FIT_TIGHT, /**< Shrink wrap around the children */\n    LV_FIT_FLOOD, /**< Align the size to the parent's edge*/\n    LV_FIT_FILL,  /**< Align the size to the parent's edge first but if there is an object out of it\n                     then get larger */\n    _LV_FIT_NUM\n};\ntypedef uint8_t lv_fit_t;\n\ntypedef struct\n{\n    /*Inherited from 'base_obj' so no inherited ext. */ /*Ext. of ancestor*/\n    /*New data for this type */\n    uint8_t layout : 4;     /*A layout from 'lv_layout_t' enum*/\n    uint8_t fit_left : 2;   /*A fit type from `lv_fit_t` enum */\n    uint8_t fit_right : 2;  /*A fit type from `lv_fit_t` enum */\n    uint8_t fit_top : 2;    /*A fit type from `lv_fit_t` enum */\n    uint8_t fit_bottom : 2; /*A fit type from `lv_fit_t` enum */\n} lv_cont_ext_t;\n\n/*Styles*/\nenum {\n    LV_CONT_STYLE_MAIN,\n};\ntypedef uint8_t lv_cont_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a container objects\n * @param par pointer to an object, it will be the parent of the new container\n * @param copy pointer to a container object, if not NULL then the new object will be copied from it\n * @return pointer to the created container\n */\nlv_obj_t * lv_cont_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a layout on a container\n * @param cont pointer to a container object\n * @param layout a layout from 'lv_cont_layout_t'\n */\nvoid lv_cont_set_layout(lv_obj_t * cont, lv_layout_t layout);\n\n/**\n * Set the fit policy in all 4 directions separately.\n * It tell how to change the container's size automatically.\n * @param cont pointer to a container object\n * @param left left fit policy from `lv_fit_t`\n * @param right right fit policy from `lv_fit_t`\n * @param top top fit policy from `lv_fit_t`\n * @param bottom bottom fit policy from `lv_fit_t`\n */\nvoid lv_cont_set_fit4(lv_obj_t * cont, lv_fit_t left, lv_fit_t right, lv_fit_t top, lv_fit_t bottom);\n\n/**\n * Set the fit policy horizontally and vertically separately.\n * It tells how to change the container's size automatically.\n * @param cont pointer to a container object\n * @param hor horizontal fit policy from `lv_fit_t`\n * @param ver vertical fit policy from `lv_fit_t`\n */\nstatic inline void lv_cont_set_fit2(lv_obj_t * cont, lv_fit_t hor, lv_fit_t ver)\n{\n    lv_cont_set_fit4(cont, hor, hor, ver, ver);\n}\n\n/**\n * Set the fit policy in all 4 direction at once.\n * It tells how to change the container's size automatically.\n * @param cont pointer to a container object\n * @param fit fit policy from `lv_fit_t`\n */\nstatic inline void lv_cont_set_fit(lv_obj_t * cont, lv_fit_t fit)\n{\n    lv_cont_set_fit4(cont, fit, fit, fit, fit);\n}\n\n/**\n * Set the style of a container\n * @param cont pointer to a container object\n * @param type which style should be set (can be only `LV_CONT_STYLE_MAIN`)\n * @param style pointer to the new style\n */\nstatic inline void lv_cont_set_style(lv_obj_t * cont, lv_cont_style_t type, const lv_style_t * style)\n{\n    (void)type; /*Unused*/\n    lv_obj_set_style(cont, style);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the layout of a container\n * @param cont pointer to container object\n * @return the layout from 'lv_cont_layout_t'\n */\nlv_layout_t lv_cont_get_layout(const lv_obj_t * cont);\n\n/**\n * Get left fit mode of a container\n * @param cont pointer to a container object\n * @return an element of `lv_fit_t`\n */\nlv_fit_t lv_cont_get_fit_left(const lv_obj_t * cont);\n\n/**\n * Get right fit mode of a container\n * @param cont pointer to a container object\n * @return an element of `lv_fit_t`\n */\nlv_fit_t lv_cont_get_fit_right(const lv_obj_t * cont);\n\n/**\n * Get top fit mode of a container\n * @param cont pointer to a container object\n * @return an element of `lv_fit_t`\n */\nlv_fit_t lv_cont_get_fit_top(const lv_obj_t * cont);\n\n/**\n * Get bottom fit mode of a container\n * @param cont pointer to a container object\n * @return an element of `lv_fit_t`\n */\nlv_fit_t lv_cont_get_fit_bottom(const lv_obj_t * cont);\n\n/**\n * Get the style of a container\n * @param cont pointer to a container object\n * @param type which style should be get (can be only `LV_CONT_STYLE_MAIN`)\n * @return pointer to the container's style\n */\nstatic inline const lv_style_t * lv_cont_get_style(const lv_obj_t * cont, lv_cont_style_t type)\n{\n    (void)type; /*Unused*/\n    return lv_obj_get_style(cont);\n}\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_CONT*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_CONT_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_ddlist.h",
    "content": "/**\n * @file lv_ddlist.h\n *\n */\n\n#ifndef LV_DDLIST_H\n#define LV_DDLIST_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_DDLIST != 0\n\n/*Testing of dependencies*/\n#if LV_USE_PAGE == 0\n#error \"lv_ddlist: lv_page is required. Enable it in lv_conf.h (LV_USE_PAGE  1) \"\n#endif\n\n#if LV_USE_LABEL == 0\n#error \"lv_ddlist: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL  1) \"\n#endif\n\n#include \"../lv_core/lv_obj.h\"\n#include \"../lv_objx/lv_page.h\"\n#include \"../lv_objx/lv_label.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n/*Data of drop down list*/\ntypedef struct\n{\n    lv_page_ext_t page; /*Ext. of ancestor*/\n    /*New data for this type */\n    lv_obj_t * label;             /*Label for the options*/\n    const lv_style_t * sel_style; /*Style of the selected option*/\n    uint16_t option_cnt;          /*Number of options*/\n    uint16_t sel_opt_id;          /*Index of the current option*/\n    uint16_t sel_opt_id_ori;      /*Store the original index on focus*/\n    uint8_t opened : 1;           /*1: The list is opened (handled by the library)*/\n    uint8_t force_sel : 1;        /*1: Keep the selection highlight even if the list is closed*/\n    uint8_t draw_arrow : 1;       /*1: Draw arrow*/\n    uint8_t stay_open : 1;        /*1: Don't close the list when a new item is selected*/\n    lv_coord_t fix_height;        /*Height of the ddlist when opened. (0: auto-size)*/\n} lv_ddlist_ext_t;\n\nenum {\n    LV_DDLIST_STYLE_BG,\n    LV_DDLIST_STYLE_SEL,\n    LV_DDLIST_STYLE_SB,\n};\ntypedef uint8_t lv_ddlist_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n/**\n * Create a drop down list objects\n * @param par pointer to an object, it will be the parent of the new drop down list\n * @param copy pointer to a drop down list object, if not NULL then the new object will be copied\n * from it\n * @return pointer to the created drop down list\n */\nlv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the options in a drop down list from a string\n * @param ddlist pointer to drop down list object\n * @param options a string with '\\n' separated options. E.g. \"One\\nTwo\\nThree\"\n */\nvoid lv_ddlist_set_options(lv_obj_t * ddlist, const char * options);\n\n/**\n * Set the selected option\n * @param ddlist pointer to drop down list object\n * @param sel_opt id of the selected option (0 ... number of option - 1);\n */\nvoid lv_ddlist_set_selected(lv_obj_t * ddlist, uint16_t sel_opt);\n\n/**\n * Set a fix height for the drop down list\n * If 0 then the opened ddlist will be auto. sized else the set height will be applied.\n * @param ddlist pointer to a drop down list\n * @param h the height when the list is opened (0: auto size)\n */\nvoid lv_ddlist_set_fix_height(lv_obj_t * ddlist, lv_coord_t h);\n\n/**\n * Set a fix width for the drop down list\n * @param ddlist pointer to a drop down list\n * @param w the width when the list is opened (0: auto size)\n */\nvoid lv_ddlist_set_fix_width(lv_obj_t * ddlist, lv_coord_t w);\n\n/**\n * Set arrow draw in a drop down list\n * @param ddlist pointer to drop down list object\n * @param en enable/disable a arrow draw. E.g. \"true\" for draw.\n */\nvoid lv_ddlist_set_draw_arrow(lv_obj_t * ddlist, bool en);\n\n/**\n * Leave the list opened when a new value is selected\n * @param ddlist pointer to drop down list object\n * @param en enable/disable \"stay open\" feature\n */\nvoid lv_ddlist_set_stay_open(lv_obj_t * ddlist, bool en);\n\n/**\n * Set the scroll bar mode of a drop down list\n * @param ddlist pointer to a drop down list object\n * @param sb_mode the new mode from 'lv_page_sb_mode_t' enum\n */\nstatic inline void lv_ddlist_set_sb_mode(lv_obj_t * ddlist, lv_sb_mode_t mode)\n{\n    lv_page_set_sb_mode(ddlist, mode);\n}\n/**\n * Set the open/close animation time.\n * @param ddlist pointer to a drop down list\n * @param anim_time: open/close animation time [ms]\n */\nstatic inline void lv_ddlist_set_anim_time(lv_obj_t * ddlist, uint16_t anim_time)\n{\n    lv_page_set_anim_time(ddlist, anim_time);\n}\n\n/**\n * Set a style of a drop down list\n * @param ddlist pointer to a drop down list object\n * @param type which style should be set\n * @param style pointer to a style\n *  */\nvoid lv_ddlist_set_style(lv_obj_t * ddlist, lv_ddlist_style_t type, const lv_style_t * style);\n\n/**\n * Set the alignment of the labels in a drop down list\n * @param ddlist pointer to a drop down list object\n * @param align alignment of labels\n */\nvoid lv_ddlist_set_align(lv_obj_t * ddlist, lv_label_align_t align);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the options of a drop down list\n * @param ddlist pointer to drop down list object\n * @return the options separated by '\\n'-s (E.g. \"Option1\\nOption2\\nOption3\")\n */\nconst char * lv_ddlist_get_options(const lv_obj_t * ddlist);\n\n/**\n * Get the selected option\n * @param ddlist pointer to drop down list object\n * @return id of the selected option (0 ... number of option - 1);\n */\nuint16_t lv_ddlist_get_selected(const lv_obj_t * ddlist);\n\n/**\n * Get the current selected option as a string\n * @param ddlist pointer to ddlist object\n * @param buf pointer to an array to store the string\n * @param buf_size size of `buf` in bytes. 0: to ignore it.\n */\nvoid lv_ddlist_get_selected_str(const lv_obj_t * ddlist, char * buf, uint16_t buf_size);\n\n/**\n * Get the fix height value.\n * @param ddlist pointer to a drop down list object\n * @return the height if the ddlist is opened (0: auto size)\n */\nlv_coord_t lv_ddlist_get_fix_height(const lv_obj_t * ddlist);\n\n/**\n * Get arrow draw in a drop down list\n * @param ddlist pointer to drop down list object\n */\nbool lv_ddlist_get_draw_arrow(lv_obj_t * ddlist);\n\n/**\n * Get whether the drop down list stay open after selecting a  value or not\n * @param ddlist pointer to drop down list object\n */\nbool lv_ddlist_get_stay_open(lv_obj_t * ddlist);\n\n/**\n * Get the scroll bar mode of a drop down list\n * @param ddlist pointer to a  drop down list object\n * @return scrollbar mode from 'lv_page_sb_mode_t' enum\n */\nstatic inline lv_sb_mode_t lv_ddlist_get_sb_mode(const lv_obj_t * ddlist)\n{\n    return lv_page_get_sb_mode(ddlist);\n}\n\n/**\n * Get the open/close animation time.\n * @param ddlist pointer to a drop down list\n * @return open/close animation time [ms]\n */\nstatic inline uint16_t lv_ddlist_get_anim_time(const lv_obj_t * ddlist)\n{\n    return lv_page_get_anim_time(ddlist);\n}\n\n/**\n * Get a style of a drop down list\n * @param ddlist pointer to a drop down list object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_ddlist_get_style(const lv_obj_t * ddlist, lv_ddlist_style_t type);\n\n/**\n * Get the alignment of the labels in a drop down list\n * @param ddlist pointer to a drop down list object\n * @return alignment of labels\n */\nlv_label_align_t lv_ddlist_get_align(const lv_obj_t * ddlist);\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Open the drop down list with or without animation\n * @param ddlist pointer to drop down list object\n * @param anim_en LV_ANIM_ON: use animation; LV_ANOM_OFF: not use animations\n */\nvoid lv_ddlist_open(lv_obj_t * ddlist, lv_anim_enable_t anim);\n\n/**\n * Close (Collapse) the drop down list\n * @param ddlist pointer to drop down list object\n * @param anim_en LV_ANIM_ON: use animation; LV_ANOM_OFF: not use animations\n */\nvoid lv_ddlist_close(lv_obj_t * ddlist, lv_anim_enable_t anim);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_DDLIST*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_DDLIST_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_gauge.h",
    "content": "/**\n * @file lv_gauge.h\n *\n */\n\n#ifndef LV_GAUGE_H\n#define LV_GAUGE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_GAUGE != 0\n\n/*Testing of dependencies*/\n#if LV_USE_LMETER == 0\n#error \"lv_gauge: lv_lmeter is required. Enable it in lv_conf.h (LV_USE_LMETER  1) \"\n#endif\n\n#include \"../lv_core/lv_obj.h\"\n#include \"lv_lmeter.h\"\n#include \"lv_label.h\"\n#include \"lv_line.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/*Data of gauge*/\ntypedef struct\n{\n    lv_lmeter_ext_t lmeter; /*Ext. of ancestor*/\n    /*New data for this type */\n    int16_t * values;                 /*Array of the set values (for needles) */\n    const lv_color_t * needle_colors; /*Color of the needles (lv_color_t my_colors[needle_num])*/\n    uint8_t needle_count;             /*Number of needles*/\n    uint8_t label_count;              /*Number of labels on the scale*/\n} lv_gauge_ext_t;\n\n/*Styles*/\nenum {\n    LV_GAUGE_STYLE_MAIN,\n};\ntypedef uint8_t lv_gauge_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a gauge objects\n * @param par pointer to an object, it will be the parent of the new gauge\n * @param copy pointer to a gauge object, if not NULL then the new object will be copied from it\n * @return pointer to the created gauge\n */\nlv_obj_t * lv_gauge_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the number of needles\n * @param gauge pointer to gauge object\n * @param needle_cnt new count of needles\n * @param colors an array of colors for needles (with 'num' elements)\n */\nvoid lv_gauge_set_needle_count(lv_obj_t * gauge, uint8_t needle_cnt, const lv_color_t colors[]);\n\n/**\n * Set the value of a needle\n * @param gauge pointer to a gauge\n * @param needle_id the id of the needle\n * @param value the new value\n */\nvoid lv_gauge_set_value(lv_obj_t * gauge, uint8_t needle_id, int16_t value);\n\n/**\n * Set minimum and the maximum values of a gauge\n * @param gauge pointer to he gauge object\n * @param min minimum value\n * @param max maximum value\n */\nstatic inline void lv_gauge_set_range(lv_obj_t * gauge, int16_t min, int16_t max)\n{\n    lv_lmeter_set_range(gauge, min, max);\n}\n\n/**\n * Set a critical value on the scale. After this value 'line.color' scale lines will be drawn\n * @param gauge pointer to a gauge object\n * @param value the critical value\n */\nstatic inline void lv_gauge_set_critical_value(lv_obj_t * gauge, int16_t value)\n{\n    lv_lmeter_set_value(gauge, value);\n}\n\n/**\n * Set the scale settings of a gauge\n * @param gauge pointer to a gauge object\n * @param angle angle of the scale (0..360)\n * @param line_cnt count of scale lines.\n * The get a given \"subdivision\" lines between label, `line_cnt` = (sub_div + 1) * (label_cnt - 1) +\n * 1\n * @param label_cnt count of scale labels.\n */\nvoid lv_gauge_set_scale(lv_obj_t * gauge, uint16_t angle, uint8_t line_cnt, uint8_t label_cnt);\n\n/**\n * Set the styles of a gauge\n * @param gauge pointer to a gauge object\n * @param type which style should be set (can be only `LV_GAUGE_STYLE_MAIN`)\n * @param style set the style of the gauge\n *  */\nstatic inline void lv_gauge_set_style(lv_obj_t * gauge, lv_gauge_style_t type, lv_style_t * style)\n{\n    (void)type; /*Unused*/\n    lv_obj_set_style(gauge, style);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the value of a needle\n * @param gauge pointer to gauge object\n * @param needle the id of the needle\n * @return the value of the needle [min,max]\n */\nint16_t lv_gauge_get_value(const lv_obj_t * gauge, uint8_t needle);\n\n/**\n * Get the count of needles on a gauge\n * @param gauge pointer to gauge\n * @return count of needles\n */\nuint8_t lv_gauge_get_needle_count(const lv_obj_t * gauge);\n\n/**\n * Get the minimum value of a gauge\n * @param gauge pointer to a gauge object\n * @return the minimum value of the gauge\n */\nstatic inline int16_t lv_gauge_get_min_value(const lv_obj_t * lmeter)\n{\n    return lv_lmeter_get_min_value(lmeter);\n}\n\n/**\n * Get the maximum value of a gauge\n * @param gauge pointer to a gauge object\n * @return the maximum value of the gauge\n */\nstatic inline int16_t lv_gauge_get_max_value(const lv_obj_t * lmeter)\n{\n    return lv_lmeter_get_max_value(lmeter);\n}\n\n/**\n * Get a critical value on the scale.\n * @param gauge pointer to a gauge object\n * @return the critical value\n */\nstatic inline int16_t lv_gauge_get_critical_value(const lv_obj_t * gauge)\n{\n    return lv_lmeter_get_value(gauge);\n}\n\n/**\n * Set the number of labels (and the thicker lines too)\n * @param gauge pointer to a gauge object\n * @return count of labels\n */\nuint8_t lv_gauge_get_label_count(const lv_obj_t * gauge);\n\n/**\n * Get the scale number of a gauge\n * @param gauge pointer to a gauge object\n * @return number of the scale units\n */\nstatic inline uint8_t lv_gauge_get_line_count(const lv_obj_t * gauge)\n{\n    return lv_lmeter_get_line_count(gauge);\n}\n\n/**\n * Get the scale angle of a gauge\n * @param gauge pointer to a gauge object\n * @return angle of the scale\n */\nstatic inline uint16_t lv_gauge_get_scale_angle(const lv_obj_t * gauge)\n{\n    return lv_lmeter_get_scale_angle(gauge);\n}\n\n/**\n * Get the style of a gauge\n * @param gauge pointer to a gauge object\n * @param type which style should be get (can be only `LV_GAUGE_STYLE_MAIN`)\n * @return pointer to the gauge's style\n */\nstatic inline const lv_style_t * lv_gauge_get_style(const lv_obj_t * gauge, lv_gauge_style_t type)\n{\n    (void)type; /*Unused*/\n    return lv_obj_get_style(gauge);\n}\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_GAUGE*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_GAUGE_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_img.h",
    "content": "/**\n * @file lv_img.h\n *\n */\n\n#ifndef LV_IMG_H\n#define LV_IMG_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_IMG != 0\n\n#include \"../lv_core/lv_obj.h\"\n#include \"../lv_misc/lv_fs.h\"\n#include \"lv_label.h\"\n#include \"../lv_draw/lv_draw.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n/*Data of image*/\ntypedef struct\n{\n    /*No inherited ext. because inherited from the base object*/ /*Ext. of ancestor*/\n    /*New data for this type */\n    const void * src; /*Image source: Pointer to an array or a file or a symbol*/\n    lv_point_t offset;\n    lv_coord_t w;          /*Width of the image (Handled by the library)*/\n    lv_coord_t h;          /*Height of the image (Handled by the library)*/\n    uint8_t src_type : 2;  /*See: lv_img_src_t*/\n    uint8_t auto_size : 1; /*1: automatically set the object size to the image size*/\n    uint8_t cf : 5;        /*Color format from `lv_img_color_format_t`*/\n} lv_img_ext_t;\n\n/*Styles*/\nenum {\n    LV_IMG_STYLE_MAIN,\n};\ntypedef uint8_t lv_img_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create an image objects\n * @param par pointer to an object, it will be the parent of the new button\n * @param copy pointer to a image object, if not NULL then the new object will be copied from it\n * @return pointer to the created image\n */\nlv_obj_t * lv_img_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the pixel map to display by the image\n * @param img pointer to an image object\n * @param data the image data\n */\nvoid lv_img_set_src(lv_obj_t * img, const void * src_img);\n\n/**\n * Enable the auto size feature.\n * If enabled the object size will be same as the picture size.\n * @param img pointer to an image\n * @param en true: auto size enable, false: auto size disable\n */\nvoid lv_img_set_auto_size(lv_obj_t * img, bool autosize_en);\n\n/**\n * Set an offset for the source of an image.\n * so the image will be displayed from the new origin.\n * @param img pointer to an image\n * @param x: the new offset along x axis.\n */\nvoid lv_img_set_offset_x(lv_obj_t * img, lv_coord_t x);\n\n/**\n * Set an offset for the source of an image.\n * so the image will be displayed from the new origin.\n * @param img pointer to an image\n * @param y: the new offset along y axis.\n */\nvoid lv_img_set_offset_y(lv_obj_t * img, lv_coord_t y);\n\n/**\n * Set the style of an image\n * @param img pointer to an image object\n * @param type which style should be set (can be only `LV_IMG_STYLE_MAIN`)\n * @param style pointer to a style\n */\nstatic inline void lv_img_set_style(lv_obj_t * img, lv_img_style_t type, const lv_style_t * style)\n{\n    (void)type; /*Unused*/\n    lv_obj_set_style(img, style);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the source of the image\n * @param img pointer to an image object\n * @return the image source (symbol, file name or C array)\n */\nconst void * lv_img_get_src(lv_obj_t * img);\n\n/**\n * Get the name of the file set for an image\n * @param img pointer to an image\n * @return file name\n */\nconst char * lv_img_get_file_name(const lv_obj_t * img);\n\n/**\n * Get the auto size enable attribute\n * @param img pointer to an image\n * @return true: auto size is enabled, false: auto size is disabled\n */\nbool lv_img_get_auto_size(const lv_obj_t * img);\n\n/**\n * Get the offset.x attribute of the img object.\n * @param img pointer to an image\n * @return offset.x value.\n */\nlv_coord_t lv_img_get_offset_x(lv_obj_t * img);\n\n/**\n * Get the offset.y attribute of the img object.\n * @param img pointer to an image\n * @return offset.y value.\n */\nlv_coord_t lv_img_get_offset_y(lv_obj_t * img);\n\n/**\n * Get the style of an image object\n * @param img pointer to an image object\n * @param type which style should be get (can be only `LV_IMG_STYLE_MAIN`)\n * @return pointer to the image's style\n */\nstatic inline const lv_style_t * lv_img_get_style(const lv_obj_t * img, lv_img_style_t type)\n{\n    (void)type; /*Unused*/\n    return lv_obj_get_style(img);\n}\n\n/**********************\n *      MACROS\n **********************/\n\n/*Use this macro to declare an image in a c file*/\n#define LV_IMG_DECLARE(var_name) extern const lv_img_dsc_t var_name;\n\n#endif /*LV_USE_IMG*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_IMG_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_imgbtn.h",
    "content": "/**\n * @file lv_imgbtn.h\n *\n */\n\n#ifndef LV_IMGBTN_H\n#define LV_IMGBTN_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_IMGBTN != 0\n\n/*Testing of dependencies*/\n#if LV_USE_BTN == 0\n#error \"lv_imgbtn: lv_btn is required. Enable it in lv_conf.h (LV_USE_BTN  1) \"\n#endif\n\n#include \"../lv_core/lv_obj.h\"\n#include \"lv_btn.h\"\n#include \"../lv_draw/lv_draw_img.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n/*Data of image button*/\ntypedef struct\n{\n    lv_btn_ext_t btn; /*Ext. of ancestor*/\n    /*New data for this type */\n#if LV_IMGBTN_TILED == 0\n    const void * img_src[_LV_BTN_STATE_NUM]; /*Store images to each state*/\n#else\n    const void * img_src_left[_LV_BTN_STATE_NUM];  /*Store left side images to each state*/\n    const void * img_src_mid[_LV_BTN_STATE_NUM];   /*Store center images to each state*/\n    const void * img_src_right[_LV_BTN_STATE_NUM]; /*Store right side images to each state*/\n#endif\n    lv_img_cf_t act_cf; /*Color format of the currently active image*/\n} lv_imgbtn_ext_t;\n\n/*Styles*/\nenum {\n    LV_IMGBTN_STYLE_REL, /**< Same meaning as ordinary button styles. */\n    LV_IMGBTN_STYLE_PR,\n    LV_IMGBTN_STYLE_TGL_REL,\n    LV_IMGBTN_STYLE_TGL_PR,\n    LV_IMGBTN_STYLE_INA,\n};\ntypedef uint8_t lv_imgbtn_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a image button objects\n * @param par pointer to an object, it will be the parent of the new image button\n * @param copy pointer to a image button object, if not NULL then the new object will be copied from\n * it\n * @return pointer to the created image button\n */\nlv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/*=====================\n * Setter functions\n *====================*/\n\n#if LV_IMGBTN_TILED == 0\n/**\n * Set images for a state of the image button\n * @param imgbtn pointer to an image button object\n * @param state for which state set the new image (from `lv_btn_state_t`) `\n * @param src pointer to an image source (a C array or path to a file)\n */\nvoid lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src);\n#else\n/**\n * Set images for a state of the image button\n * @param imgbtn pointer to an image button object\n * @param state for which state set the new image (from `lv_btn_state_t`) `\n * @param src_left pointer to an image source for the left side of the button (a C array or path to\n * a file)\n * @param src_mid pointer to an image source for the middle of the button (ideally 1px wide) (a C\n * array or path to a file)\n * @param src_right pointer to an image source for the right side of the button (a C array or path\n * to a file)\n */\nvoid lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src_left, const void * src_mid,\n                       const void * src_right);\n\n#endif\n\n/**\n * Enable the toggled states. On release the button will change from/to toggled state.\n * @param imgbtn pointer to an image button object\n * @param tgl true: enable toggled states, false: disable\n */\nstatic inline void lv_imgbtn_set_toggle(lv_obj_t * imgbtn, bool tgl)\n{\n    lv_btn_set_toggle(imgbtn, tgl);\n}\n\n/**\n * Set the state of the image button\n * @param imgbtn pointer to an image button object\n * @param state the new state of the button (from lv_btn_state_t enum)\n */\nstatic inline void lv_imgbtn_set_state(lv_obj_t * imgbtn, lv_btn_state_t state)\n{\n    lv_btn_set_state(imgbtn, state);\n}\n\n/**\n * Toggle the state of the image button (ON->OFF, OFF->ON)\n * @param imgbtn pointer to a image button object\n */\nstatic inline void lv_imgbtn_toggle(lv_obj_t * imgbtn)\n{\n    lv_btn_toggle(imgbtn);\n}\n\n/**\n * Set a style of a image button.\n * @param imgbtn pointer to image button object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_imgbtn_set_style(lv_obj_t * imgbtn, lv_imgbtn_style_t type, const lv_style_t * style);\n\n/*=====================\n * Getter functions\n *====================*/\n\n#if LV_IMGBTN_TILED == 0\n/**\n * Get the images in a  given state\n * @param imgbtn pointer to an image button object\n * @param state the state where to get the image (from `lv_btn_state_t`) `\n * @return pointer to an image source (a C array or path to a file)\n */\nconst void * lv_imgbtn_get_src(lv_obj_t * imgbtn, lv_btn_state_t state);\n\n#else\n\n/**\n * Get the left image in a given state\n * @param imgbtn pointer to an image button object\n * @param state the state where to get the image (from `lv_btn_state_t`) `\n * @return pointer to the left image source (a C array or path to a file)\n */\nconst void * lv_imgbtn_get_src_left(lv_obj_t * imgbtn, lv_btn_state_t state);\n\n/**\n * Get the middle image in a given state\n * @param imgbtn pointer to an image button object\n * @param state the state where to get the image (from `lv_btn_state_t`) `\n * @return pointer to the middle image source (a C array or path to a file)\n */\nconst void * lv_imgbtn_get_src_middle(lv_obj_t * imgbtn, lv_btn_state_t state);\n\n/**\n * Get the right image in a given state\n * @param imgbtn pointer to an image button object\n * @param state the state where to get the image (from `lv_btn_state_t`) `\n * @return pointer to the left image source (a C array or path to a file)\n */\nconst void * lv_imgbtn_get_src_right(lv_obj_t * imgbtn, lv_btn_state_t state);\n\n#endif\n/**\n * Get the current state of the image button\n * @param imgbtn pointer to a image button object\n * @return the state of the button (from lv_btn_state_t enum)\n */\nstatic inline lv_btn_state_t lv_imgbtn_get_state(const lv_obj_t * imgbtn)\n{\n    return lv_btn_get_state(imgbtn);\n}\n\n/**\n * Get the toggle enable attribute of the image button\n * @param imgbtn pointer to a image button object\n * @return ture: toggle enabled, false: disabled\n */\nstatic inline bool lv_imgbtn_get_toggle(const lv_obj_t * imgbtn)\n{\n    return lv_btn_get_toggle(imgbtn);\n}\n\n/**\n * Get style of a image button.\n * @param imgbtn pointer to image button object\n * @param type which style should be get\n * @return style pointer to the style\n */\nconst lv_style_t * lv_imgbtn_get_style(const lv_obj_t * imgbtn, lv_imgbtn_style_t type);\n\n/*=====================\n * Other functions\n *====================*/\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_IMGBTN*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_IMGBTN_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_kb.h",
    "content": "/**\n * @file lv_kb.h\n *\n */\n\n#ifndef LV_KB_H\n#define LV_KB_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_KB != 0\n\n/*Testing of dependencies*/\n#if LV_USE_BTNM == 0\n#error \"lv_kb: lv_btnm is required. Enable it in lv_conf.h (LV_USE_BTNM  1) \"\n#endif\n\n#if LV_USE_TA == 0\n#error \"lv_kb: lv_ta is required. Enable it in lv_conf.h (LV_USE_TA  1) \"\n#endif\n\n#include \"../lv_core/lv_obj.h\"\n#include \"lv_btnm.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/** Current keyboard mode. */\nenum {\n    LV_KB_MODE_TEXT,\n    LV_KB_MODE_NUM,\n};\ntypedef uint8_t lv_kb_mode_t;\n\n/*Data of keyboard*/\ntypedef struct\n{\n    lv_btnm_ext_t btnm; /*Ext. of ancestor*/\n    /*New data for this type */\n    lv_obj_t * ta;          /*Pointer to the assigned text area*/\n    lv_kb_mode_t mode;      /*Key map type*/\n    uint8_t cursor_mng : 1; /*1: automatically show/hide cursor when a text area is assigned or left*/\n} lv_kb_ext_t;\n\nenum {\n    LV_KB_STYLE_BG,\n    LV_KB_STYLE_BTN_REL,\n    LV_KB_STYLE_BTN_PR,\n    LV_KB_STYLE_BTN_TGL_REL,\n    LV_KB_STYLE_BTN_TGL_PR,\n    LV_KB_STYLE_BTN_INA,\n};\ntypedef uint8_t lv_kb_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a keyboard objects\n * @param par pointer to an object, it will be the parent of the new keyboard\n * @param copy pointer to a keyboard object, if not NULL then the new object will be copied from it\n * @return pointer to the created keyboard\n */\nlv_obj_t * lv_kb_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Assign a Text Area to the Keyboard. The pressed characters will be put there.\n * @param kb pointer to a Keyboard object\n * @param ta pointer to a Text Area object to write there\n */\nvoid lv_kb_set_ta(lv_obj_t * kb, lv_obj_t * ta);\n\n/**\n * Set a new a mode (text or number map)\n * @param kb pointer to a Keyboard object\n * @param mode the mode from 'lv_kb_mode_t'\n */\nvoid lv_kb_set_mode(lv_obj_t * kb, lv_kb_mode_t mode);\n\n/**\n * Automatically hide or show the cursor of the current Text Area\n * @param kb pointer to a Keyboard object\n * @param en true: show cursor on the current text area, false: hide cursor\n */\nvoid lv_kb_set_cursor_manage(lv_obj_t * kb, bool en);\n\n/**\n * Set a new map for the keyboard\n * @param kb pointer to a Keyboard object\n * @param map pointer to a string array to describe the map.\n *            See 'lv_btnm_set_map()' for more info.\n */\nstatic inline void lv_kb_set_map(lv_obj_t * kb, const char * map[])\n{\n    lv_btnm_set_map(kb, map);\n}\n\n/**\n * Set the button control map (hidden, disabled etc.) for the keyboard. The\n * control map array will be copied and so may be deallocated after this\n * function returns.\n * @param kb pointer to a keyboard object\n * @param ctrl_map pointer to an array of `lv_btn_ctrl_t` control bytes.\n *                 See: `lv_btnm_set_ctrl_map` for more details.\n */\nstatic inline void lv_kb_set_ctrl_map(lv_obj_t * kb, const lv_btnm_ctrl_t ctrl_map[])\n{\n    lv_btnm_set_ctrl_map(kb, ctrl_map);\n}\n\n/**\n * Set a style of a keyboard\n * @param kb pointer to a keyboard object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_kb_set_style(lv_obj_t * kb, lv_kb_style_t type, const lv_style_t * style);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Assign a Text Area to the Keyboard. The pressed characters will be put there.\n * @param kb pointer to a Keyboard object\n * @return pointer to the assigned Text Area object\n */\nlv_obj_t * lv_kb_get_ta(const lv_obj_t * kb);\n\n/**\n * Set a new a mode (text or number map)\n * @param kb pointer to a Keyboard object\n * @return the current mode from 'lv_kb_mode_t'\n */\nlv_kb_mode_t lv_kb_get_mode(const lv_obj_t * kb);\n\n/**\n * Get the current cursor manage mode.\n * @param kb pointer to a Keyboard object\n * @return true: show cursor on the current text area, false: hide cursor\n */\nbool lv_kb_get_cursor_manage(const lv_obj_t * kb);\n\n/**\n * Get the current map of a keyboard\n * @param kb pointer to a keyboard object\n * @return the current map\n */\nstatic inline const char ** lv_kb_get_map_array(const lv_obj_t * kb)\n{\n    return lv_btnm_get_map_array(kb);\n}\n\n/**\n * Get a style of a keyboard\n * @param kb pointer to a keyboard object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_kb_get_style(const lv_obj_t * kb, lv_kb_style_t type);\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Default keyboard event to add characters to the Text area and change the map.\n * If a custom `event_cb` is added to the keyboard this function be called from it to handle the\n * button clicks\n * @param kb pointer to a  keyboard\n * @param event the triggering event\n */\nvoid lv_kb_def_event_cb(lv_obj_t * kb, lv_event_t event);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_KB*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_KB_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_label.h",
    "content": "/**\n * @file lv_rect.h\n *\n */\n\n#ifndef LV_LABEL_H\n#define LV_LABEL_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_LABEL != 0\n\n#include \"../lv_core/lv_obj.h\"\n#include \"../lv_font/lv_font.h\"\n#include \"../lv_font/lv_symbol_def.h\"\n#include \"../lv_misc/lv_txt.h\"\n#include \"../lv_draw/lv_draw.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_LABEL_DOT_NUM 3\n#define LV_LABEL_POS_LAST 0xFFFF\n#define LV_LABEL_TEXT_SEL_OFF 0xFFFF\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/** Long mode behaviors. Used in 'lv_label_ext_t' */\nenum {\n    LV_LABEL_LONG_EXPAND,    /**< Expand the object size to the text size*/\n    LV_LABEL_LONG_BREAK,     /**< Keep the object width, break the too long lines and expand the object\n                                height*/\n    LV_LABEL_LONG_DOT,       /**< Keep the size and write dots at the end if the text is too long*/\n    LV_LABEL_LONG_SROLL,      /**< Keep the size and roll the text back and forth*/\n    LV_LABEL_LONG_SROLL_CIRC, /**< Keep the size and roll the text circularly*/\n    LV_LABEL_LONG_CROP,      /**< Keep the size and crop the text out of it*/\n};\ntypedef uint8_t lv_label_long_mode_t;\n\n/** Label align policy*/\nenum {\n    LV_LABEL_ALIGN_LEFT, /**< Align text to left */\n    LV_LABEL_ALIGN_CENTER, /**< Align text to center */\n    LV_LABEL_ALIGN_RIGHT, /**< Align text to right */\n};\ntypedef uint8_t lv_label_align_t;\n\n/** Data of label*/\ntypedef struct\n{\n    /*Inherited from 'base_obj' so no inherited ext.*/ /*Ext. of ancestor*/\n    /*New data for this type */\n    char * text; /*Text of the label*/\n    union\n    {\n        char * tmp_ptr; /* Pointer to the allocated memory containing the character which are replaced by dots (Handled\n                           by the library)*/\n        char tmp[sizeof(char *)]; /* Directly store the characters if <=4 characters */\n    } dot;\n    uint16_t dot_end;  /*The text end position in dot mode (Handled by the library)*/\n    lv_point_t offset; /*Text draw position offset*/\n#if LV_LABEL_LONG_TXT_HINT\n    lv_draw_label_hint_t hint; /*Used to buffer info about large text*/\n#endif\n\n#if LV_USE_ANIMATION\n    uint16_t anim_speed; /*Speed of scroll and roll animation in px/sec unit*/\n#endif\n\n#if LV_LABEL_TEXT_SEL\n    uint16_t txt_sel_start; /*Left-most selection character*/\n    uint16_t txt_sel_end;   /*Right-most selection character*/\n#endif\n\n    lv_label_long_mode_t long_mode : 3; /*Determinate what to do with the long texts*/\n    uint8_t static_txt : 1;             /*Flag to indicate the text is static*/\n    uint8_t align : 2;                  /*Align type from 'lv_label_align_t'*/\n    uint8_t recolor : 1;                /*Enable in-line letter re-coloring*/\n    uint8_t expand : 1;                 /*Ignore real width (used by the library with LV_LABEL_LONG_ROLL)*/\n    uint8_t body_draw : 1;              /*Draw background body*/\n    uint8_t dot_tmp_alloc : 1; /*True if dot_tmp has been allocated. False if dot_tmp directly holds up to 4 bytes of\n                                  characters */\n} lv_label_ext_t;\n\n/** Label styles*/\nenum {\n    LV_LABEL_STYLE_MAIN,\n};\ntypedef uint8_t lv_label_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a label objects\n * @param par pointer to an object, it will be the parent of the new label\n * @param copy pointer to a button object, if not NULL then the new object will be copied from it\n * @return pointer to the created button\n */\nlv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a new text for a label. Memory will be allocated to store the text by the label.\n * @param label pointer to a label object\n * @param text '\\0' terminated character string. NULL to refresh with the current text.\n */\nvoid lv_label_set_text(lv_obj_t * label, const char * text);\n\n/**\n * Set a new text for a label from a character array. The array don't has to be '\\0' terminated.\n * Memory will be allocated to store the array by the label.\n * @param label pointer to a label object\n * @param array array of characters or NULL to refresh the label\n * @param size the size of 'array' in bytes\n */\nvoid lv_label_set_array_text(lv_obj_t * label, const char * array, uint16_t size);\n\n/**\n * Set a static text. It will not be saved by the label so the 'text' variable\n * has to be 'alive' while the label exist.\n * @param label pointer to a label object\n * @param text pointer to a text. NULL to refresh with the current text.\n */\nvoid lv_label_set_static_text(lv_obj_t * label, const char * text);\n\n/**\n * Set the behavior of the label with longer text then the object size\n * @param label pointer to a label object\n * @param long_mode the new mode from 'lv_label_long_mode' enum.\n *                  In LV_LONG_BREAK/LONG/ROLL the size of the label should be set AFTER this\n * function\n */\nvoid lv_label_set_long_mode(lv_obj_t * label, lv_label_long_mode_t long_mode);\n\n/**\n * Set the align of the label (left or center)\n * @param label pointer to a label object\n * @param align 'LV_LABEL_ALIGN_LEFT' or 'LV_LABEL_ALIGN_LEFT'\n */\nvoid lv_label_set_align(lv_obj_t * label, lv_label_align_t align);\n\n/**\n * Enable the recoloring by in-line commands\n * @param label pointer to a label object\n * @param en true: enable recoloring, false: disable\n */\nvoid lv_label_set_recolor(lv_obj_t * label, bool en);\n\n/**\n * Set the label to draw (or not draw) background specified in its style's body\n * @param label pointer to a label object\n * @param en true: draw body; false: don't draw body\n */\nvoid lv_label_set_body_draw(lv_obj_t * label, bool en);\n\n/**\n * Set the label's animation speed in LV_LABEL_LONG_SROLL/SCROLL_CIRC modes\n * @param label pointer to a label object\n * @param anim_speed speed of animation in px/sec unit\n */\nvoid lv_label_set_anim_speed(lv_obj_t * label, uint16_t anim_speed);\n\n/**\n * Set the style of an label\n * @param label pointer to an label object\n * @param type which style should be get (can be only `LV_LABEL_STYLE_MAIN`)\n * @param style pointer to a style\n */\nstatic inline void lv_label_set_style(lv_obj_t * label, lv_label_style_t type, const lv_style_t * style)\n{\n    (void)type; /*Unused*/\n    lv_obj_set_style(label, style);\n}\n\n/**\n * @brief Set the selection start index.\n * @param label pointer to a label object.\n * @param index index to set. `LV_LABEL_TXT_SEL_OFF` to select nothing.\n */\nvoid lv_label_set_text_sel_start(lv_obj_t * label, uint16_t index);\n\n/**\n * @brief Set the selection end index.\n * @param label pointer to a label object.\n * @param index index to set. `LV_LABEL_TXT_SEL_OFF` to select nothing.\n */\nvoid lv_label_set_text_sel_end(lv_obj_t * label, uint16_t index);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the text of a label\n * @param label pointer to a label object\n * @return the text of the label\n */\nchar * lv_label_get_text(const lv_obj_t * label);\n\n/**\n * Get the long mode of a label\n * @param label pointer to a label object\n * @return the long mode\n */\nlv_label_long_mode_t lv_label_get_long_mode(const lv_obj_t * label);\n\n/**\n * Get the align attribute\n * @param label pointer to a label object\n * @return LV_LABEL_ALIGN_LEFT or LV_LABEL_ALIGN_CENTER\n */\nlv_label_align_t lv_label_get_align(const lv_obj_t * label);\n\n/**\n * Get the recoloring attribute\n * @param label pointer to a label object\n * @return true: recoloring is enabled, false: disable\n */\nbool lv_label_get_recolor(const lv_obj_t * label);\n\n/**\n * Get the body draw attribute\n * @param label pointer to a label object\n * @return true: draw body; false: don't draw body\n */\nbool lv_label_get_body_draw(const lv_obj_t * label);\n\n/**\n * Get the label's animation speed in LV_LABEL_LONG_ROLL and SCROLL modes\n * @param label pointer to a label object\n * @return speed of animation in px/sec unit\n */\nuint16_t lv_label_get_anim_speed(const lv_obj_t * label);\n\n/**\n * Get the relative x and y coordinates of a letter\n * @param label pointer to a label object\n * @param index index of the letter [0 ... text length]. Expressed in character index, not byte\n * index (different in UTF-8)\n * @param pos store the result here (E.g. index = 0 gives 0;0 coordinates)\n */\nvoid lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t * pos);\n\n/**\n * Get the index of letter on a relative point of a label\n * @param label pointer to label object\n * @param pos pointer to point with coordinates on a the label\n * @return the index of the letter on the 'pos_p' point (E.g. on 0;0 is the 0. letter)\n * Expressed in character index and not byte index (different in UTF-8)\n */\nuint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos);\n\n/**\n * Check if a character is drawn under a point.\n * @param label Label object\n * @param pos Point to check for characte under\n * @return whether a character is drawn under the point\n */\nbool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos);\n\n/**\n * Get the style of an label object\n * @param label pointer to an label object\n * @param type which style should be get (can be only `LV_LABEL_STYLE_MAIN`)\n * @return pointer to the label's style\n */\nstatic inline const lv_style_t * lv_label_get_style(const lv_obj_t * label, lv_label_style_t type)\n{\n    (void)type; /*Unused*/\n    return lv_obj_get_style(label);\n}\n\n/**\n * @brief Get the selection start index.\n * @param label pointer to a label object.\n * @return selection start index. `LV_LABEL_TXT_SEL_OFF` if nothing is selected.\n */\nuint16_t lv_label_get_text_sel_start(const lv_obj_t * label);\n\n/**\n * @brief Get the selection end index.\n * @param label pointer to a label object.\n * @return selection end index. `LV_LABEL_TXT_SEL_OFF` if nothing is selected.\n */\nuint16_t lv_label_get_text_sel_end(const lv_obj_t * label);\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Insert a text to the label. The label text can not be static.\n * @param label pointer to a label object\n * @param pos character index to insert. Expressed in character index and not byte index (Different\n * in UTF-8) 0: before first char. LV_LABEL_POS_LAST: after last char.\n * @param txt pointer to the text to insert\n */\nvoid lv_label_ins_text(lv_obj_t * label, uint32_t pos, const char * txt);\n\n/**\n * Delete characters from a label. The label text can not be static.\n * @param label pointer to a label object\n * @param pos character index to insert. Expressed in character index and not byte index (Different\n * in UTF-8) 0: before first char.\n * @param cnt number of characters to cut\n */\nvoid lv_label_cut_text(lv_obj_t * label, uint32_t pos, uint32_t cnt);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_LABEL*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_LABEL_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_led.h",
    "content": "/**\n * @file lv_led.h\n *\n */\n\n#ifndef LV_LED_H\n#define LV_LED_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_LED != 0\n\n#include \"../lv_core/lv_obj.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/*Data of led*/\ntypedef struct\n{\n    /*No inherited ext.*/\n    /*New data for this type */\n    uint8_t bright; /*Current brightness of the LED (0..255)*/\n} lv_led_ext_t;\n\n/*Styles*/\nenum {\n    LV_LED_STYLE_MAIN,\n};\ntypedef uint8_t lv_led_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a led objects\n * @param par pointer to an object, it will be the parent of the new led\n * @param copy pointer to a led object, if not NULL then the new object will be copied from it\n * @return pointer to the created led\n */\nlv_obj_t * lv_led_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/**\n * Set the brightness of a LED object\n * @param led pointer to a LED object\n * @param bright 0 (max. dark) ... 255 (max. light)\n */\nvoid lv_led_set_bright(lv_obj_t * led, uint8_t bright);\n\n/**\n * Light on a LED\n * @param led pointer to a LED object\n */\nvoid lv_led_on(lv_obj_t * led);\n\n/**\n * Light off a LED\n * @param led pointer to a LED object\n */\nvoid lv_led_off(lv_obj_t * led);\n\n/**\n * Toggle the state of a LED\n * @param led pointer to a LED object\n */\nvoid lv_led_toggle(lv_obj_t * led);\n\n/**\n * Set the style of a led\n * @param led pointer to a led object\n * @param type which style should be set (can be only `LV_LED_STYLE_MAIN`)\n * @param style pointer to a style\n */\nstatic inline void lv_led_set_style(lv_obj_t * led, lv_led_style_t type, const lv_style_t * style)\n{\n    (void)type; /*Unused*/\n    lv_obj_set_style(led, style);\n}\n\n/**\n * Get the brightness of a LEd object\n * @param led pointer to LED object\n * @return bright 0 (max. dark) ... 255 (max. light)\n */\nuint8_t lv_led_get_bright(const lv_obj_t * led);\n\n/**\n * Get the style of an led object\n * @param led pointer to an led object\n * @param type which style should be get (can be only `LV_CHART_STYLE_MAIN`)\n * @return pointer to the led's style\n */\nstatic inline const lv_style_t * lv_led_get_style(const lv_obj_t * led, lv_led_style_t type)\n{\n    (void)type; /*Unused*/\n    return lv_obj_get_style(led);\n}\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_LED*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_LED_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_line.h",
    "content": "/**\n * @file lv_line.h\n *\n */\n\n#ifndef LV_LINE_H\n#define LV_LINE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_LINE != 0\n\n#include \"../lv_core/lv_obj.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/*Data of line*/\ntypedef struct\n{\n    /*Inherited from 'base_obj' so no inherited ext.*/ /*Ext. of ancestor*/\n    const lv_point_t * point_array;                    /*Pointer to an array with the points of the line*/\n    uint16_t point_num;                                /*Number of points in 'point_array' */\n    uint8_t auto_size : 1;                             /*1: set obj. width to x max and obj. height to y max */\n    uint8_t y_inv : 1;                                 /*1: y == 0 will be on the bottom*/\n} lv_line_ext_t;\n\n/*Styles*/\nenum {\n    LV_LINE_STYLE_MAIN,\n};\ntypedef uint8_t lv_line_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a line objects\n * @param par pointer to an object, it will be the parent of the new line\n * @return pointer to the created line\n */\nlv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set an array of points. The line object will connect these points.\n * @param line pointer to a line object\n * @param point_a an array of points. Only the address is saved,\n * so the array can NOT be a local variable which will be destroyed\n * @param point_num number of points in 'point_a'\n */\nvoid lv_line_set_points(lv_obj_t * line, const lv_point_t point_a[], uint16_t point_num);\n\n/**\n * Enable (or disable) the auto-size option. The size of the object will fit to its points.\n * (set width to x max and height to y max)\n * @param line pointer to a line object\n * @param en true: auto size is enabled, false: auto size is disabled\n */\nvoid lv_line_set_auto_size(lv_obj_t * line, bool en);\n\n/**\n * Enable (or disable) the y coordinate inversion.\n * If enabled then y will be subtracted from the height of the object,\n * therefore the y=0 coordinate will be on the bottom.\n * @param line pointer to a line object\n * @param en true: enable the y inversion, false:disable the y inversion\n */\nvoid lv_line_set_y_invert(lv_obj_t * line, bool en);\n\n#define lv_line_set_y_inv                                                                                              \\\n    lv_line_set_y_invert /*The name was inconsistent. In v.6.0 only `lv_line_set_y_invert`will                         \\\n                            work */\n\n/**\n * Set the style of a line\n * @param line pointer to a line object\n * @param type which style should be set (can be only `LV_LINE_STYLE_MAIN`)\n * @param style pointer to a style\n */\nstatic inline void lv_line_set_style(lv_obj_t * line, lv_line_style_t type, const lv_style_t * style)\n{\n    (void)type; /*Unused*/\n    lv_obj_set_style(line, style);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the auto size attribute\n * @param line pointer to a line object\n * @return true: auto size is enabled, false: disabled\n */\nbool lv_line_get_auto_size(const lv_obj_t * line);\n\n/**\n * Get the y inversion attribute\n * @param line pointer to a line object\n * @return true: y inversion is enabled, false: disabled\n */\nbool lv_line_get_y_invert(const lv_obj_t * line);\n\n/**\n * Get the style of an line object\n * @param line pointer to an line object\n * @param type which style should be get (can be only `LV_LINE_STYLE_MAIN`)\n * @return pointer to the line's style\n */\nstatic inline const lv_style_t * lv_line_get_style(const lv_obj_t * line, lv_line_style_t type)\n{\n    (void)type; /*Unused*/\n    return lv_obj_get_style(line);\n}\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_LINE*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_LINE_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_list.h",
    "content": "/**\n * @file lv_list.h\n *\n */\n\n#ifndef LV_LIST_H\n#define LV_LIST_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_LIST != 0\n\n/*Testing of dependencies*/\n#if LV_USE_PAGE == 0\n#error \"lv_list: lv_page is required. Enable it in lv_conf.h (LV_USE_PAGE  1) \"\n#endif\n\n#if LV_USE_BTN == 0\n#error \"lv_list: lv_btn is required. Enable it in lv_conf.h (LV_USE_BTN  1) \"\n#endif\n\n#if LV_USE_LABEL == 0\n#error \"lv_list: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL  1) \"\n#endif\n\n#include \"../lv_core/lv_obj.h\"\n#include \"lv_page.h\"\n#include \"lv_btn.h\"\n#include \"lv_label.h\"\n#include \"lv_img.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n/*Data of list*/\ntypedef struct\n{\n    lv_page_ext_t page; /*Ext. of ancestor*/\n    /*New data for this type */\n    const lv_style_t * styles_btn[_LV_BTN_STATE_NUM]; /*Styles of the list element buttons*/\n    const lv_style_t * style_img;                     /*Style of the list element images on buttons*/\n    uint16_t size;                                    /*the number of items(buttons) in the list*/\n\n    uint8_t single_mode : 1; /* whether single selected mode is enabled */\n\n#if LV_USE_GROUP\n    lv_obj_t * last_sel;     /* The last selected button. It will be reverted when the list is focused again */\n    lv_obj_t * selected_btn; /* The button is currently being selected*/\n#endif\n} lv_list_ext_t;\n\n/** List styles. */\nenum {\n    LV_LIST_STYLE_BG, /**< List background style */\n    LV_LIST_STYLE_SCRL, /**< List scrollable area style. */\n    LV_LIST_STYLE_SB, /**< List scrollbar style. */\n    LV_LIST_STYLE_EDGE_FLASH, /**< List edge flash style. */\n    LV_LIST_STYLE_BTN_REL, /**< Same meaning as the ordinary button styles. */\n    LV_LIST_STYLE_BTN_PR,\n    LV_LIST_STYLE_BTN_TGL_REL,\n    LV_LIST_STYLE_BTN_TGL_PR,\n    LV_LIST_STYLE_BTN_INA,\n};\ntypedef uint8_t lv_list_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a list objects\n * @param par pointer to an object, it will be the parent of the new list\n * @param copy pointer to a list object, if not NULL then the new object will be copied from it\n * @return pointer to the created list\n */\nlv_obj_t * lv_list_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/**\n * Delete all children of the scrl object, without deleting scrl child.\n * @param obj pointer to an object\n */\nvoid lv_list_clean(lv_obj_t * obj);\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/**\n * Add a list element to the list\n * @param list pointer to list object\n * @param img_fn file name of an image before the text (NULL if unused)\n * @param txt text of the list element (NULL if unused)\n * @return pointer to the new list element which can be customized (a button)\n */\nlv_obj_t * lv_list_add_btn(lv_obj_t * list, const void * img_src, const char * txt);\n\n/**\n * Remove the index of the button in the list\n * @param list pointer to a list object\n * @param index pointer to a the button's index in the list, index must be 0 <= index <\n * lv_list_ext_t.size\n * @return true: successfully deleted\n */\nbool lv_list_remove(const lv_obj_t * list, uint16_t index);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set single button selected mode, only one button will be selected if enabled.\n * @param list pointer to the currently pressed list object\n * @param mode enable(true)/disable(false) single selected mode.\n */\nvoid lv_list_set_single_mode(lv_obj_t * list, bool mode);\n\n#if LV_USE_GROUP\n\n/**\n * Make a button selected\n * @param list pointer to a list object\n * @param btn pointer to a button to select\n *            NULL to not select any buttons\n */\nvoid lv_list_set_btn_selected(lv_obj_t * list, lv_obj_t * btn);\n#endif\n\n/**\n * Set the scroll bar mode of a list\n * @param list pointer to a list object\n * @param sb_mode the new mode from 'lv_page_sb_mode_t' enum\n */\nstatic inline void lv_list_set_sb_mode(lv_obj_t * list, lv_sb_mode_t mode)\n{\n    lv_page_set_sb_mode(list, mode);\n}\n\n/**\n * Enable the scroll propagation feature. If enabled then the List will move its parent if there is\n * no more space to scroll.\n * @param list pointer to a List\n * @param en true or false to enable/disable scroll propagation\n */\nstatic inline void lv_list_set_scroll_propagation(lv_obj_t * list, bool en)\n{\n    lv_page_set_scroll_propagation(list, en);\n}\n\n/**\n * Enable the edge flash effect. (Show an arc when the an edge is reached)\n * @param list pointer to a List\n * @param en true or false to enable/disable end flash\n */\nstatic inline void lv_list_set_edge_flash(lv_obj_t * list, bool en)\n{\n    lv_page_set_edge_flash(list, en);\n}\n\n/**\n * Set scroll animation duration on 'list_up()' 'list_down()' 'list_focus()'\n * @param list pointer to a list object\n * @param anim_time duration of animation [ms]\n */\nstatic inline void lv_list_set_anim_time(lv_obj_t * list, uint16_t anim_time)\n{\n    lv_page_set_anim_time(list, anim_time);\n}\n\n/**\n * Set a style of a list\n * @param list pointer to a list object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_list_set_style(lv_obj_t * list, lv_list_style_t type, const lv_style_t * style);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get single button selected mode.\n * @param list pointer to the currently pressed list object.\n */\nbool lv_list_get_single_mode(lv_obj_t * list);\n\n/**\n * Get the text of a list element\n * @param btn pointer to list element\n * @return pointer to the text\n */\nconst char * lv_list_get_btn_text(const lv_obj_t * btn);\n/**\n * Get the label object from a list element\n * @param btn pointer to a list element (button)\n * @return pointer to the label from the list element or NULL if not found\n */\nlv_obj_t * lv_list_get_btn_label(const lv_obj_t * btn);\n\n/**\n * Get the image object from a list element\n * @param btn pointer to a list element (button)\n * @return pointer to the image from the list element or NULL if not found\n */\nlv_obj_t * lv_list_get_btn_img(const lv_obj_t * btn);\n\n/**\n * Get the next button from list. (Starts from the bottom button)\n * @param list pointer to a list object\n * @param prev_btn pointer to button. Search the next after it.\n * @return pointer to the next button or NULL when no more buttons\n */\nlv_obj_t * lv_list_get_prev_btn(const lv_obj_t * list, lv_obj_t * prev_btn);\n\n/**\n * Get the previous button from list. (Starts from the top button)\n * @param list pointer to a list object\n * @param prev_btn pointer to button. Search the previous before it.\n * @return pointer to the previous button or NULL when no more buttons\n */\nlv_obj_t * lv_list_get_next_btn(const lv_obj_t * list, lv_obj_t * prev_btn);\n\n/**\n * Get the index of the button in the list\n * @param list pointer to a list object. If NULL, assumes btn is part of a list.\n * @param btn pointer to a list element (button)\n * @return the index of the button in the list, or -1 of the button not in this list\n */\nint32_t lv_list_get_btn_index(const lv_obj_t * list, const lv_obj_t * btn);\n\n/**\n * Get the number of buttons in the list\n * @param list pointer to a list object\n * @return the number of buttons in the list\n */\nuint16_t lv_list_get_size(const lv_obj_t * list);\n\n#if LV_USE_GROUP\n/**\n * Get the currently selected button. Can be used while navigating in the list with a keypad.\n * @param list pointer to a list object\n * @return pointer to the selected button\n */\nlv_obj_t * lv_list_get_btn_selected(const lv_obj_t * list);\n#endif\n\n/**\n * Get the scroll bar mode of a list\n * @param list pointer to a list object\n * @return scrollbar mode from 'lv_page_sb_mode_t' enum\n */\nstatic inline lv_sb_mode_t lv_list_get_sb_mode(const lv_obj_t * list)\n{\n    return lv_page_get_sb_mode(list);\n}\n\n/**\n * Get the scroll propagation property\n * @param list pointer to a List\n * @return true or false\n */\nstatic inline bool lv_list_get_scroll_propagation(lv_obj_t * list)\n{\n    return lv_page_get_scroll_propagation(list);\n}\n\n/**\n * Get the scroll propagation property\n * @param list pointer to a List\n * @return true or false\n */\nstatic inline bool lv_list_get_edge_flash(lv_obj_t * list)\n{\n    return lv_page_get_edge_flash(list);\n}\n\n/**\n * Get scroll animation duration\n * @param list pointer to a list object\n * @return duration of animation [ms]\n */\nstatic inline uint16_t lv_list_get_anim_time(const lv_obj_t * list)\n{\n    return lv_page_get_anim_time(list);\n}\n\n/**\n * Get a style of a list\n * @param list pointer to a list object\n * @param type which style should be get\n * @return style pointer to a style\n *  */\nconst lv_style_t * lv_list_get_style(const lv_obj_t * list, lv_list_style_t type);\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Move the list elements up by one\n * @param list pointer a to list object\n */\nvoid lv_list_up(const lv_obj_t * list);\n/**\n * Move the list elements down by one\n * @param list pointer to a list object\n */\nvoid lv_list_down(const lv_obj_t * list);\n\n/**\n * Focus on a list button. It ensures that the button will be visible on the list.\n * @param btn pointer to a list button to focus\n * @param anim LV_ANOM_ON: scroll with animation, LV_ANIM_OFF: without animation\n */\nvoid lv_list_focus(const lv_obj_t * btn, lv_anim_enable_t anim);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_LIST*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_LIST_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_lmeter.h",
    "content": "/**\n * @file lv_lmeter.h\n *\n */\n\n#ifndef LV_LMETER_H\n#define LV_LMETER_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_LMETER != 0\n\n#include \"../lv_core/lv_obj.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n/*Data of line meter*/\ntypedef struct\n{\n    /*No inherited ext.*/ /*Ext. of ancestor*/\n    /*New data for this type */\n    uint16_t scale_angle; /*Angle of the scale in deg. (0..360)*/\n    uint8_t line_cnt;     /*Count of lines */\n    int16_t cur_value;\n    int16_t min_value;\n    int16_t max_value;\n} lv_lmeter_ext_t;\n\n/*Styles*/\nenum {\n    LV_LMETER_STYLE_MAIN,\n};\ntypedef uint8_t lv_lmeter_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a line meter objects\n * @param par pointer to an object, it will be the parent of the new line meter\n * @param copy pointer to a line meter object, if not NULL then the new object will be copied from\n * it\n * @return pointer to the created line meter\n */\nlv_obj_t * lv_lmeter_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a new value on the line meter\n * @param lmeter pointer to a line meter object\n * @param value new value\n */\nvoid lv_lmeter_set_value(lv_obj_t * lmeter, int16_t value);\n\n/**\n * Set minimum and the maximum values of a line meter\n * @param lmeter pointer to he line meter object\n * @param min minimum value\n * @param max maximum value\n */\nvoid lv_lmeter_set_range(lv_obj_t * lmeter, int16_t min, int16_t max);\n\n/**\n * Set the scale settings of a line meter\n * @param lmeter pointer to a line meter object\n * @param angle angle of the scale (0..360)\n * @param line_cnt number of lines\n */\nvoid lv_lmeter_set_scale(lv_obj_t * lmeter, uint16_t angle, uint8_t line_cnt);\n\n/**\n * Set the styles of a line meter\n * @param lmeter pointer to a line meter object\n * @param type which style should be set (can be only `LV_LMETER_STYLE_MAIN`)\n * @param style set the style of the line meter\n */\nstatic inline void lv_lmeter_set_style(lv_obj_t * lmeter, lv_lmeter_style_t type, lv_style_t * style)\n{\n    (void)type; /*Unused*/\n    lv_obj_set_style(lmeter, style);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the value of a line meter\n * @param lmeter pointer to a line meter object\n * @return the value of the line meter\n */\nint16_t lv_lmeter_get_value(const lv_obj_t * lmeter);\n\n/**\n * Get the minimum value of a line meter\n * @param lmeter pointer to a line meter object\n * @return the minimum value of the line meter\n */\nint16_t lv_lmeter_get_min_value(const lv_obj_t * lmeter);\n\n/**\n * Get the maximum value of a line meter\n * @param lmeter pointer to a line meter object\n * @return the maximum value of the line meter\n */\nint16_t lv_lmeter_get_max_value(const lv_obj_t * lmeter);\n\n/**\n * Get the scale number of a line meter\n * @param lmeter pointer to a line meter object\n * @return number of the scale units\n */\nuint8_t lv_lmeter_get_line_count(const lv_obj_t * lmeter);\n\n/**\n * Get the scale angle of a line meter\n * @param lmeter pointer to a line meter object\n * @return angle of the scale\n */\nuint16_t lv_lmeter_get_scale_angle(const lv_obj_t * lmeter);\n\n/**\n * Get the style of a line meter\n * @param lmeter pointer to a line meter object\n * @param type which style should be get (can be only `LV_LMETER_STYLE_MAIN`)\n * @return pointer to the line meter's style\n */\nstatic inline const lv_style_t * lv_lmeter_get_style(const lv_obj_t * lmeter, lv_lmeter_style_t type)\n{\n    (void)type; /*Unused*/\n    return lv_obj_get_style(lmeter);\n}\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_LMETER*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_LMETER_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_mbox.h",
    "content": "/**\n * @file lv_mbox.h\n *\n */\n\n#ifndef LV_MBOX_H\n#define LV_MBOX_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_MBOX != 0\n\n/*Testing of dependencies*/\n#if LV_USE_CONT == 0\n#error \"lv_mbox: lv_cont is required. Enable it in lv_conf.h (LV_USE_CONT  1) \"\n#endif\n\n#if LV_USE_BTNM == 0\n#error \"lv_mbox: lv_btnm is required. Enable it in lv_conf.h (LV_USE_BTNM  1) \"\n#endif\n\n#if LV_USE_LABEL == 0\n#error \"lv_mbox: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL  1) \"\n#endif\n\n#include \"../lv_core/lv_obj.h\"\n#include \"lv_cont.h\"\n#include \"lv_btnm.h\"\n#include \"lv_label.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/*Data of message box*/\ntypedef struct\n{\n    lv_cont_ext_t bg; /*Ext. of ancestor*/\n    /*New data for this type */\n    lv_obj_t * text; /*Text of the message box*/\n    lv_obj_t * btnm; /*Button matrix for the buttons*/\n#if LV_USE_ANIMATION\n    uint16_t anim_time; /*Duration of close animation [ms] (0: no animation)*/\n#endif\n} lv_mbox_ext_t;\n\n/** Message box styles. */\nenum {\n    LV_MBOX_STYLE_BG,\n    LV_MBOX_STYLE_BTN_BG, /**< Same meaning as ordinary button styles. */\n    LV_MBOX_STYLE_BTN_REL,\n    LV_MBOX_STYLE_BTN_PR,\n    LV_MBOX_STYLE_BTN_TGL_REL,\n    LV_MBOX_STYLE_BTN_TGL_PR,\n    LV_MBOX_STYLE_BTN_INA,\n};\ntypedef uint8_t lv_mbox_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a message box objects\n * @param par pointer to an object, it will be the parent of the new message box\n * @param copy pointer to a message box object, if not NULL then the new object will be copied from\n * it\n * @return pointer to the created message box\n */\nlv_obj_t * lv_mbox_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/**\n * Add button to the message box\n * @param mbox pointer to message box object\n * @param btn_map button descriptor (button matrix map).\n *                E.g.  a const char *txt[] = {\"ok\", \"close\", \"\"} (Can not be local variable)\n */\nvoid lv_mbox_add_btns(lv_obj_t * mbox, const char ** btn_mapaction);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the text of the message box\n * @param mbox pointer to a message box\n * @param txt a '\\0' terminated character string which will be the message box text\n */\nvoid lv_mbox_set_text(lv_obj_t * mbox, const char * txt);\n\n/**\n * Set animation duration\n * @param mbox pointer to a message box object\n * @param anim_time animation length in  milliseconds (0: no animation)\n */\nvoid lv_mbox_set_anim_time(lv_obj_t * mbox, uint16_t anim_time);\n\n/**\n * Automatically delete the message box after a given time\n * @param mbox pointer to a message box object\n * @param delay a time (in milliseconds) to wait before delete the message box\n */\nvoid lv_mbox_start_auto_close(lv_obj_t * mbox, uint16_t delay);\n\n/**\n * Stop the auto. closing of message box\n * @param mbox pointer to a message box object\n */\nvoid lv_mbox_stop_auto_close(lv_obj_t * mbox);\n\n/**\n * Set a style of a message box\n * @param mbox pointer to a message box object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_mbox_set_style(lv_obj_t * mbox, lv_mbox_style_t type, const lv_style_t * style);\n\n/**\n * Set whether recoloring is enabled. Must be called after `lv_mbox_add_btns`.\n * @param btnm pointer to button matrix object\n * @param en whether recoloring is enabled\n */\nvoid lv_mbox_set_recolor(lv_obj_t * mbox, bool en);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the text of the message box\n * @param mbox pointer to a message box object\n * @return pointer to the text of the message box\n */\nconst char * lv_mbox_get_text(const lv_obj_t * mbox);\n\n/**\n * Get the index of the lastly \"activated\" button by the user (pressed, released etc)\n * Useful in the the `event_cb`.\n * @param btnm pointer to button matrix object\n * @return  index of the last released button (LV_BTNM_BTN_NONE: if unset)\n */\nuint16_t lv_mbox_get_active_btn(lv_obj_t * mbox);\n\n/**\n * Get the text of the lastly \"activated\" button by the user (pressed, released etc)\n * Useful in the the `event_cb`.\n * @param btnm pointer to button matrix object\n * @return text of the last released button (NULL: if unset)\n */\nconst char * lv_mbox_get_active_btn_text(lv_obj_t * mbox);\n\n/**\n * Get the animation duration (close animation time)\n * @param mbox pointer to a message box object\n * @return animation length in  milliseconds (0: no animation)\n */\nuint16_t lv_mbox_get_anim_time(const lv_obj_t * mbox);\n\n/**\n * Get a style of a message box\n * @param mbox pointer to a message box object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_mbox_get_style(const lv_obj_t * mbox, lv_mbox_style_t type);\n\n/**\n * Get whether recoloring is enabled\n * @param mbox pointer to a message box object\n * @return whether recoloring is enabled\n */\nbool lv_mbox_get_recolor(const lv_obj_t * mbox);\n\n/**\n * Get message box button matrix\n * @param mbox pointer to a message box object\n * @return pointer to button matrix object\n * @remarks return value will be NULL unless `lv_mbox_add_btns` has been already called\n */\nlv_obj_t * lv_mbox_get_btnm(lv_obj_t * mbox);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_MBOX*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_MBOX_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_objx.mk",
    "content": "CSRCS += lv_arc.c\nCSRCS += lv_bar.c\nCSRCS += lv_cb.c\nCSRCS += lv_ddlist.c\nCSRCS += lv_kb.c\nCSRCS += lv_line.c\nCSRCS += lv_mbox.c\nCSRCS += lv_preload.c\nCSRCS += lv_roller.c\nCSRCS += lv_table.c\nCSRCS += lv_tabview.c\nCSRCS += lv_tileview.c\nCSRCS += lv_btn.c\nCSRCS += lv_calendar.c\nCSRCS += lv_chart.c\nCSRCS += lv_canvas.c\nCSRCS += lv_gauge.c\nCSRCS += lv_label.c\nCSRCS += lv_list.c\nCSRCS += lv_slider.c\nCSRCS += lv_ta.c\nCSRCS += lv_spinbox.c\nCSRCS += lv_btnm.c\nCSRCS += lv_cont.c\nCSRCS += lv_img.c\nCSRCS += lv_imgbtn.c\nCSRCS += lv_led.c\nCSRCS += lv_lmeter.c\nCSRCS += lv_page.c\nCSRCS += lv_sw.c\nCSRCS += lv_win.c\n\nDEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_objx\nVPATH += :$(LVGL_DIR)/lvgl/src/lv_objx\n\nCFLAGS += \"-I$(LVGL_DIR)/lvgl/src/lv_objx\"\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_objx_templ.h",
    "content": "/**\n * @file lv_templ.h\n *\n */\n\n/* TODO Remove these instructions\n * Search an replace: template -> object normal name with lower case (e.g. button, label etc.)\n *                    templ -> object short name with lower case(e.g. btn, label etc)\n *                    TEMPL -> object short name with upper case (e.g. BTN, LABEL etc.)\n *\n */\n\n#ifndef LV_TEMPL_H\n#define LV_TEMPL_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_TEMPL != 0\n\n#include \"../lv_core/lv_obj.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n/*Data of template*/\ntypedef struct\n{\n    lv_ANCESTOR_ext_t ANCESTOR; /*Ext. of ancestor*/\n    /*New data for this type */\n} lv_templ_ext_t;\n\n/*Styles*/\nenum {\n    LV_TEMPL_STYLE_X,\n    LV_TEMPL_STYLE_Y,\n};\ntypedef uint8_t lv_templ_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a template objects\n * @param par pointer to an object, it will be the parent of the new template\n * @param copy pointer to a template object, if not NULL then the new object will be copied from it\n * @return pointer to the created template\n */\nlv_obj_t * lv_templ_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a style of a template.\n * @param templ pointer to template object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_templ_set_style(lv_obj_t * templ, lv_templ_style_t type, const lv_style_t * style);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get style of a template.\n * @param templ pointer to template object\n * @param type which style should be get\n * @return style pointer to the style\n */\nlv_style_t * lv_templ_get_style(const lv_obj_t * templ, lv_templ_style_t type);\n\n/*=====================\n * Other functions\n *====================*/\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_TEMPL*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_TEMPL_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_page.h",
    "content": "/**\n * @file lv_page.h\n *\n */\n\n#ifndef LV_PAGE_H\n#define LV_PAGE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_PAGE != 0\n\n/*Testing of dependencies*/\n#if LV_USE_CONT == 0\n#error \"lv_page: lv_cont is required. Enable it in lv_conf.h (LV_USE_CONT  1) \"\n#endif\n\n#include \"lv_cont.h\"\n#include \"../lv_core/lv_indev.h\"\n#include \"../lv_misc/lv_anim.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/** Scrollbar modes: shows when should the scrollbars be visible*/\nenum {\n    LV_SB_MODE_OFF    = 0x0, /**< Never show scrollbars*/\n    LV_SB_MODE_ON     = 0x1, /**< Always show scrollbars*/\n    LV_SB_MODE_DRAG   = 0x2, /**< Show scrollbars when page is being dragged*/\n    LV_SB_MODE_AUTO   = 0x3, /**< Show scrollbars when the scrollable container is large enough to be scrolled*/\n    LV_SB_MODE_HIDE   = 0x4, /**< Hide the scroll bar temporally*/\n    LV_SB_MODE_UNHIDE = 0x5, /**< Unhide the previously hidden scrollbar. Recover it's type too*/\n};\ntypedef uint8_t lv_sb_mode_t;\n\n/** Edges: describes the four edges of the page*/\nenum { LV_PAGE_EDGE_LEFT = 0x1, LV_PAGE_EDGE_TOP = 0x2, LV_PAGE_EDGE_RIGHT = 0x4, LV_PAGE_EDGE_BOTTOM = 0x8 };\ntypedef uint8_t lv_page_edge_t;\n\n/*Data of page*/\ntypedef struct\n{\n    lv_cont_ext_t bg; /*Ext. of ancestor*/\n    /*New data for this type */\n    lv_obj_t * scrl; /*The scrollable object on the background*/\n    struct\n    {\n        const lv_style_t * style; /*Style of scrollbars*/\n        lv_area_t hor_area;       /*Horizontal scrollbar area relative to the page. (Handled by the library) */\n        lv_area_t ver_area;       /*Vertical scrollbar area relative to the page (Handled by the library)*/\n        uint8_t hor_draw : 1;     /*1: horizontal scrollbar is visible now (Handled by the library)*/\n        uint8_t ver_draw : 1;     /*1: vertical scrollbar is visible now (Handled by the library)*/\n        lv_sb_mode_t mode : 3;    /*Scrollbar visibility from 'lv_page_sb_mode_t'*/\n    } sb;\n#if LV_USE_ANIMATION\n    struct\n    {\n        lv_anim_value_t state;    /*Store the current size of the edge flash effect*/\n        const lv_style_t * style; /*Style of edge flash effect (usually homogeneous circle)*/\n        uint8_t enabled : 1;      /*1: Show a flash animation on the edge*/\n        uint8_t top_ip : 1;       /*Used internally to show that top most position is reached (flash is In\n                                     Progress)*/\n        uint8_t bottom_ip : 1;    /*Used internally to show that bottom most position is reached (flash\n                                     is In Progress)*/\n        uint8_t right_ip : 1;     /*Used internally to show that right most position is reached (flash\n                                     is In Progress)*/\n        uint8_t left_ip : 1;      /*Used internally to show that left most position is reached (flash is\n                                     In Progress)*/\n    } edge_flash;\n\n    uint16_t anim_time; /*Scroll animation time*/\n#endif\n\n    uint8_t scroll_prop : 1;    /*1: Propagate the scrolling the the parent if the edge is reached*/\n    uint8_t scroll_prop_ip : 1; /*1: Scroll propagation is in progress (used by the library)*/\n} lv_page_ext_t;\n\nenum {\n    LV_PAGE_STYLE_BG,\n    LV_PAGE_STYLE_SCRL,\n    LV_PAGE_STYLE_SB,\n    LV_PAGE_STYLE_EDGE_FLASH,\n};\ntypedef uint8_t lv_page_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a page objects\n * @param par pointer to an object, it will be the parent of the new page\n * @param copy pointer to a page object, if not NULL then the new object will be copied from it\n * @return pointer to the created page\n */\nlv_obj_t * lv_page_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/**\n * Delete all children of the scrl object, without deleting scrl child.\n * @param obj pointer to an object\n */\nvoid lv_page_clean(lv_obj_t * obj);\n\n/**\n * Get the scrollable object of a page\n * @param page pointer to a page object\n * @return pointer to a container which is the scrollable part of the page\n */\nlv_obj_t * lv_page_get_scrl(const lv_obj_t * page);\n\n/**\n * Get the animation time\n * @param page pointer to a page object\n * @return the animation time in milliseconds\n */\nuint16_t lv_page_get_anim_time(const lv_obj_t * page);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the scroll bar mode on a page\n * @param page pointer to a page object\n * @param sb_mode the new mode from 'lv_page_sb.mode_t' enum\n */\nvoid lv_page_set_sb_mode(lv_obj_t * page, lv_sb_mode_t sb_mode);\n\n/**\n * Set the animation time for the page\n * @param page pointer to a page object\n * @param anim_time animation time in milliseconds\n */\nvoid lv_page_set_anim_time(lv_obj_t * page, uint16_t anim_time);\n\n/**\n * Enable the scroll propagation feature. If enabled then the page will move its parent if there is\n * no more space to scroll.\n * @param page pointer to a Page\n * @param en true or false to enable/disable scroll propagation\n */\nvoid lv_page_set_scroll_propagation(lv_obj_t * page, bool en);\n\n/**\n * Enable the edge flash effect. (Show an arc when the an edge is reached)\n * @param page pointer to a Page\n * @param en true or false to enable/disable end flash\n */\nvoid lv_page_set_edge_flash(lv_obj_t * page, bool en);\n\n/**\n * Set the fit policy in all 4 directions separately.\n * It tell how to change the page size automatically.\n * @param page pointer to a page object\n * @param left left fit policy from `lv_fit_t`\n * @param right right fit policy from `lv_fit_t`\n * @param top bottom fit policy from `lv_fit_t`\n * @param bottom bottom fit policy from `lv_fit_t`\n */\nstatic inline void lv_page_set_scrl_fit4(lv_obj_t * page, lv_fit_t left, lv_fit_t right, lv_fit_t top, lv_fit_t bottom)\n{\n    lv_cont_set_fit4(lv_page_get_scrl(page), left, right, top, bottom);\n}\n\n/**\n * Set the fit policy horizontally and vertically separately.\n * It tell how to change the page size automatically.\n * @param page pointer to a page object\n * @param hot horizontal fit policy from `lv_fit_t`\n * @param ver vertical fit policy from `lv_fit_t`\n */\nstatic inline void lv_page_set_scrl_fit2(lv_obj_t * page, lv_fit_t hor, lv_fit_t ver)\n{\n    lv_cont_set_fit2(lv_page_get_scrl(page), hor, ver);\n}\n\n/**\n * Set the fit policyin all 4 direction at once.\n * It tell how to change the page size automatically.\n * @param page pointer to a button object\n * @param fit fit policy from `lv_fit_t`\n */\nstatic inline void lv_page_set_scrl_fit(lv_obj_t * page, lv_fit_t fit)\n{\n    lv_cont_set_fit(lv_page_get_scrl(page), fit);\n}\n\n/**\n * Set width of the scrollable part of a page\n * @param page pointer to a page object\n * @param w the new width of the scrollable (it ha no effect is horizontal fit is enabled)\n */\nstatic inline void lv_page_set_scrl_width(lv_obj_t * page, lv_coord_t w)\n{\n    lv_obj_set_width(lv_page_get_scrl(page), w);\n}\n\n/**\n * Set height of the scrollable part of a page\n * @param page pointer to a page object\n * @param h the new height of the scrollable (it ha no effect is vertical fit is enabled)\n */\nstatic inline void lv_page_set_scrl_height(lv_obj_t * page, lv_coord_t h)\n{\n    lv_obj_set_height(lv_page_get_scrl(page), h);\n}\n\n/**\n * Set the layout of the scrollable part of the page\n * @param page pointer to a page object\n * @param layout a layout from 'lv_cont_layout_t'\n */\nstatic inline void lv_page_set_scrl_layout(lv_obj_t * page, lv_layout_t layout)\n{\n    lv_cont_set_layout(lv_page_get_scrl(page), layout);\n}\n\n/**\n * Set a style of a page\n * @param page pointer to a page object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_page_set_style(lv_obj_t * page, lv_page_style_t type, const lv_style_t * style);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Set the scroll bar mode on a page\n * @param page pointer to a page object\n * @return the mode from 'lv_page_sb.mode_t' enum\n */\nlv_sb_mode_t lv_page_get_sb_mode(const lv_obj_t * page);\n\n/**\n * Get the scroll propagation property\n * @param page pointer to a Page\n * @return true or false\n */\nbool lv_page_get_scroll_propagation(lv_obj_t * page);\n\n/**\n * Get the edge flash effect property.\n * @param page pointer to a Page\n * return true or false\n */\nbool lv_page_get_edge_flash(lv_obj_t * page);\n\n/**\n * Get that width which can be set to the children to still not cause overflow (show scrollbars)\n * @param page pointer to a page object\n * @return the width which still fits into the page\n */\nlv_coord_t lv_page_get_fit_width(lv_obj_t * page);\n\n/**\n * Get that height which can be set to the children to still not cause overflow (show scrollbars)\n * @param page pointer to a page object\n * @return the height which still fits into the page\n */\nlv_coord_t lv_page_get_fit_height(lv_obj_t * page);\n\n/**\n * Get width of the scrollable part of a page\n * @param page pointer to a page object\n * @return the width of the scrollable\n */\nstatic inline lv_coord_t lv_page_get_scrl_width(const lv_obj_t * page)\n{\n    return lv_obj_get_width(lv_page_get_scrl(page));\n}\n\n/**\n * Get height of the scrollable part of a page\n * @param page pointer to a page object\n * @return the height of the scrollable\n */\nstatic inline lv_coord_t lv_page_get_scrl_height(const lv_obj_t * page)\n{\n    return lv_obj_get_height(lv_page_get_scrl(page));\n}\n\n/**\n * Get the layout of the scrollable part of a page\n * @param page pointer to page object\n * @return the layout from 'lv_cont_layout_t'\n */\nstatic inline lv_layout_t lv_page_get_scrl_layout(const lv_obj_t * page)\n{\n    return lv_cont_get_layout(lv_page_get_scrl(page));\n}\n\n/**\n * Get the left fit mode\n * @param page pointer to a page object\n * @return an element of `lv_fit_t`\n */\nstatic inline lv_fit_t lv_page_get_scrl_fit_left(const lv_obj_t * page)\n{\n    return lv_cont_get_fit_left(lv_page_get_scrl(page));\n}\n\n/**\n * Get the right fit mode\n * @param page pointer to a page object\n * @return an element of `lv_fit_t`\n */\nstatic inline lv_fit_t lv_page_get_scrl_fit_right(const lv_obj_t * page)\n{\n    return lv_cont_get_fit_right(lv_page_get_scrl(page));\n}\n\n/**\n * Get the top fit mode\n * @param page pointer to a page object\n * @return an element of `lv_fit_t`\n */\nstatic inline lv_fit_t lv_page_get_scrl_fit_top(const lv_obj_t * page)\n{\n    return lv_cont_get_fit_top(lv_page_get_scrl(page));\n}\n\n/**\n * Get the bottom fit mode\n * @param page pointer to a page object\n * @return an element of `lv_fit_t`\n */\nstatic inline lv_fit_t lv_page_get_scrl_fit_bottom(const lv_obj_t * page)\n{\n    return lv_cont_get_fit_bottom(lv_page_get_scrl(page));\n}\n\n/**\n * Get a style of a page\n * @param page pointer to page object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_page_get_style(const lv_obj_t * page, lv_page_style_t type);\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Find whether the page has been scrolled to a certain edge.\n * @param page Page object\n * @param edge Edge to check\n * @return true if the page is on the specified edge\n */\nbool lv_page_on_edge(lv_obj_t * page, lv_page_edge_t edge);\n\n/**\n * Glue the object to the page. After it the page can be moved (dragged) with this object too.\n * @param obj pointer to an object on a page\n * @param glue true: enable glue, false: disable glue\n */\nvoid lv_page_glue_obj(lv_obj_t * obj, bool glue);\n\n/**\n * Focus on an object. It ensures that the object will be visible on the page.\n * @param page pointer to a page object\n * @param obj pointer to an object to focus (must be on the page)\n * @param anim_en LV_ANIM_ON to focus with animation; LV_ANIM_OFF to focus without animation\n */\nvoid lv_page_focus(lv_obj_t * page, const lv_obj_t * obj, lv_anim_enable_t anim_en);\n\n/**\n * Scroll the page horizontally\n * @param page pointer to a page object\n * @param dist the distance to scroll (< 0: scroll left; > 0 scroll right)\n */\nvoid lv_page_scroll_hor(lv_obj_t * page, lv_coord_t dist);\n\n/**\n * Scroll the page vertically\n * @param page pointer to a page object\n * @param dist the distance to scroll (< 0: scroll down; > 0 scroll up)\n */\nvoid lv_page_scroll_ver(lv_obj_t * page, lv_coord_t dist);\n\n/**\n * Not intended to use directly by the user but by other object types internally.\n * Start an edge flash animation. Exactly one `ext->edge_flash.xxx_ip` should be set\n * @param page\n */\nvoid lv_page_start_edge_flash(lv_obj_t * page);\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_PAGE*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_PAGE_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_preload.h",
    "content": "/**\n * @file lv_preload.h\n *\n */\n\n#ifndef LV_PRELOAD_H\n#define LV_PRELOAD_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_PRELOAD != 0\n\n/*Testing of dependencies*/\n#if LV_USE_ARC == 0\n#error \"lv_preload: lv_arc is required. Enable it in lv_conf.h (LV_USE_ARC  1) \"\n#endif\n\n#if LV_USE_ANIMATION == 0\n#error \"lv_preload: animations are required. Enable it in lv_conf.h (LV_USE_ANIMATION  1) \"\n#endif\n\n#include \"../lv_core/lv_obj.h\"\n#include \"../lv_misc/lv_anim.h\"\n#include \"lv_arc.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**\n * Type of preloader.\n */\nenum {\n    LV_PRELOAD_TYPE_SPINNING_ARC,\n    LV_PRELOAD_TYPE_FILLSPIN_ARC,\n};\ntypedef uint8_t lv_preload_type_t;\n\n/**\n * Direction the preloader should spin.\n */\nenum {\n    LV_PRELOAD_DIR_FORWARD,\n    LV_PRELOAD_DIR_BACKWARD,\n};\ntypedef uint8_t lv_preload_dir_t;\n\n/*Data of pre loader*/\ntypedef struct\n{\n    lv_arc_ext_t arc; /*Ext. of ancestor*/\n    /*New data for this type */\n    lv_anim_value_t arc_length;      /*Length of the spinning indicator in degree*/\n    uint16_t time;                   /*Time of one round*/\n    lv_preload_type_t anim_type : 1; /*Type of the arc animation*/\n    lv_preload_dir_t anim_dir : 1;   /*Animation Direction*/\n} lv_preload_ext_t;\n\n/*Styles*/\nenum {\n    LV_PRELOAD_STYLE_MAIN,\n};\ntypedef uint8_t lv_preload_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a pre loader objects\n * @param par pointer to an object, it will be the parent of the new pre loader\n * @param copy pointer to a pre loader object, if not NULL then the new object will be copied from\n * it\n * @return pointer to the created pre loader\n */\nlv_obj_t * lv_preload_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/**\n * Set the length of the spinning  arc in degrees\n * @param preload pointer to a preload object\n * @param deg length of the arc\n */\nvoid lv_preload_set_arc_length(lv_obj_t * preload, lv_anim_value_t deg);\n\n/**\n * Set the spin time of the arc\n * @param preload pointer to a preload object\n * @param time time of one round in milliseconds\n */\nvoid lv_preload_set_spin_time(lv_obj_t * preload, uint16_t time);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a style of a pre loader.\n * @param preload pointer to pre loader object\n * @param type which style should be set\n * @param style pointer to a style\n *  */\nvoid lv_preload_set_style(lv_obj_t * preload, lv_preload_style_t type, const lv_style_t * style);\n\n/**\n * Set the animation type of a preloader.\n * @param preload pointer to pre loader object\n * @param type animation type of the preload\n *  */\nvoid lv_preload_set_type(lv_obj_t * preload, lv_preload_type_t type);\n\n/**\n * Set the animation direction of a preloader\n * @param preload pointer to pre loader object\n * @param direction animation direction of the preload\n */\nvoid lv_preload_set_dir(lv_obj_t * preload, lv_preload_dir_t dir);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the arc length [degree] of the a pre loader\n * @param preload pointer to a pre loader object\n */\nlv_anim_value_t lv_preload_get_arc_length(const lv_obj_t * preload);\n\n/**\n * Get the spin time of the arc\n * @param preload pointer to a pre loader object [milliseconds]\n */\nuint16_t lv_preload_get_spin_time(const lv_obj_t * preload);\n\n/**\n * Get style of a pre loader.\n * @param preload pointer to pre loader object\n * @param type which style should be get\n * @return style pointer to the style\n *  */\nconst lv_style_t * lv_preload_get_style(const lv_obj_t * preload, lv_preload_style_t type);\n\n/**\n * Get the animation type of a preloader.\n * @param preload pointer to pre loader object\n * @return animation type\n *  */\nlv_preload_type_t lv_preload_get_type(lv_obj_t * preload);\n\n/**\n * Get the animation direction of a preloader\n * @param preload pointer to pre loader object\n * @return animation direction\n */\nlv_preload_dir_t lv_preload_get_dir(lv_obj_t * preload);\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Animator function  (exec_cb) to rotate the arc of spinner.\n * @param ptr pointer to preloader\n * @param val the current desired value [0..360]\n */\nvoid lv_preload_spinner_anim(void * ptr, lv_anim_value_t val);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_PRELOAD*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_PRELOAD_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_roller.h",
    "content": "/**\n * @file lv_roller.h\n *\n */\n\n#ifndef LV_ROLLER_H\n#define LV_ROLLER_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_ROLLER != 0\n\n/*Testing of dependencies*/\n#if LV_USE_DDLIST == 0\n#error \"lv_roller: lv_ddlist is required. Enable it in lv_conf.h (LV_USE_DDLIST  1) \"\n#endif\n\n#include \"../lv_core/lv_obj.h\"\n#include \"lv_ddlist.h\"\n#include \"lv_label.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/** Roller mode. */\nenum {\n    LV_ROLLER_MODE_NORMAL, /**< Normal mode (roller ends at the end of the options). */\n    LV_ROLLER_MODE_INIFINITE, /**< Infinite mode (roller can be scrolled forever). */\n};\n\ntypedef uint8_t lv_roller_mode_t;\n\n\n\n/*Data of roller*/\ntypedef struct\n{\n    lv_ddlist_ext_t ddlist; /*Ext. of ancestor*/\n    /*New data for this type */\n    lv_roller_mode_t mode : 1;\n} lv_roller_ext_t;\n\nenum {\n    LV_ROLLER_STYLE_BG,\n    LV_ROLLER_STYLE_SEL,\n};\ntypedef uint8_t lv_roller_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a roller object\n * @param par pointer to an object, it will be the parent of the new roller\n * @param copy pointer to a roller object, if not NULL then the new object will be copied from it\n * @return pointer to the created roller\n */\nlv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the options on a roller\n * @param roller pointer to roller object\n * @param options a string with '\\n' separated options. E.g. \"One\\nTwo\\nThree\"\n * @param mode `LV_ROLLER_MODE_NORMAL` or `LV_ROLLER_MODE_INFINITE`\n */\nvoid lv_roller_set_options(lv_obj_t * roller, const char * options, lv_roller_mode_t mode);\n\n/**\n * Set the align of the roller's options (left, right or center[default])\n * @param roller - pointer to a roller object\n * @param align - one of lv_label_align_t values (left, right, center)\n */\nvoid lv_roller_set_align(lv_obj_t * roller, lv_label_align_t align);\n\n/**\n * Set the selected option\n * @param roller pointer to a roller object\n * @param sel_opt id of the selected option (0 ... number of option - 1);\n * @param anim LV_ANOM_ON: set with animation; LV_ANIM_OFF set immediately\n */\nvoid lv_roller_set_selected(lv_obj_t * roller, uint16_t sel_opt, lv_anim_enable_t anim);\n\n/**\n * Set the height to show the given number of rows (options)\n * @param roller pointer to a roller object\n * @param row_cnt number of desired visible rows\n */\nvoid lv_roller_set_visible_row_count(lv_obj_t * roller, uint8_t row_cnt);\n\n/**\n * Set a fix width for the drop down list\n * @param roller pointer to a roller obejct\n * @param w the width when the list is opened (0: auto size)\n */\nstatic inline void lv_roller_set_fix_width(lv_obj_t * roller, lv_coord_t w)\n{\n    lv_ddlist_set_fix_width(roller, w);\n}\n\n/**\n * Set the open/close animation time.\n * @param roller pointer to a roller object\n * @param anim_time: open/close animation time [ms]\n */\nstatic inline void lv_roller_set_anim_time(lv_obj_t * roller, uint16_t anim_time)\n{\n    lv_ddlist_set_anim_time(roller, anim_time);\n}\n\n/**\n * Set a style of a roller\n * @param roller pointer to a roller object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_roller_set_style(lv_obj_t * roller, lv_roller_style_t type, const lv_style_t * style);\n\n/*=====================\n * Getter functions\n *====================*/\n/**\n * Get the id of the selected option\n * @param roller pointer to a roller object\n * @return id of the selected option (0 ... number of option - 1);\n */\nuint16_t lv_roller_get_selected(const lv_obj_t * roller);\n\n/**\n * Get the current selected option as a string\n * @param roller pointer to roller object\n * @param buf pointer to an array to store the string\n * @param buf_size size of `buf` in bytes. 0: to ignore it.\n */\nstatic inline void lv_roller_get_selected_str(const lv_obj_t * roller, char * buf, uint16_t buf_size)\n{\n    lv_ddlist_get_selected_str(roller, buf, buf_size);\n}\n\n/**\n * Get the align attribute. Default alignment after _create is LV_LABEL_ALIGN_CENTER\n * @param roller pointer to a roller object\n * @return LV_LABEL_ALIGN_LEFT, LV_LABEL_ALIGN_RIGHT or LV_LABEL_ALIGN_CENTER\n */\nlv_label_align_t lv_roller_get_align(const lv_obj_t * roller);\n\n/**\n * Get the options of a roller\n * @param roller pointer to roller object\n * @return the options separated by '\\n'-s (E.g. \"Option1\\nOption2\\nOption3\")\n */\nstatic inline const char * lv_roller_get_options(const lv_obj_t * roller)\n{\n    return lv_ddlist_get_options(roller);\n}\n\n/**\n * Get the open/close animation time.\n * @param roller pointer to a roller\n * @return open/close animation time [ms]\n */\nstatic inline uint16_t lv_roller_get_anim_time(const lv_obj_t * roller)\n{\n    return lv_ddlist_get_anim_time(roller);\n}\n\n/**\n * Get the auto width set attribute\n * @param roller pointer to a roller object\n * @return true: auto size enabled; false: manual width settings enabled\n */\nbool lv_roller_get_hor_fit(const lv_obj_t * roller);\n\n/**\n * Get a style of a roller\n * @param roller pointer to a roller object\n * @param type which style should be get\n * @return style pointer to a style\n *  */\nconst lv_style_t * lv_roller_get_style(const lv_obj_t * roller, lv_roller_style_t type);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_ROLLER*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_ROLLER_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_slider.h",
    "content": "/**\n * @file lv_slider.h\n *\n */\n\n#ifndef LV_SLIDER_H\n#define LV_SLIDER_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_SLIDER != 0\n\n/*Testing of dependencies*/\n#if LV_USE_BAR == 0\n#error \"lv_slider: lv_bar is required. Enable it in lv_conf.h (LV_USE_BAR  1) \"\n#endif\n\n#include \"../lv_core/lv_obj.h\"\n#include \"lv_bar.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n/*Data of slider*/\ntypedef struct\n{\n    lv_bar_ext_t bar; /*Ext. of ancestor*/\n    /*New data for this type */\n    const lv_style_t * style_knob; /*Style of the knob*/\n    int16_t drag_value;            /*Store a temporal value during press until release (Handled by the library)*/\n    uint8_t knob_in : 1;           /*1: Draw the knob inside the bar*/\n} lv_slider_ext_t;\n\n/** Built-in styles of slider*/\nenum {\n    LV_SLIDER_STYLE_BG, /** Slider background style. */\n    LV_SLIDER_STYLE_INDIC, /** Slider indicator (filled area) style. */\n    LV_SLIDER_STYLE_KNOB, /** Slider knob style. */\n};\ntypedef uint8_t lv_slider_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a slider objects\n * @param par pointer to an object, it will be the parent of the new slider\n * @param copy pointer to a slider object, if not NULL then the new object will be copied from it\n * @return pointer to the created slider\n */\nlv_obj_t * lv_slider_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a new value on the slider\n * @param slider pointer to a slider object\n * @param value new value\n * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately\n */\nstatic inline void lv_slider_set_value(lv_obj_t * slider, int16_t value, lv_anim_enable_t anim)\n{\n    lv_bar_set_value(slider, value, anim);\n}\n\n/**\n * Set minimum and the maximum values of a bar\n * @param slider pointer to the slider object\n * @param min minimum value\n * @param max maximum value\n */\nstatic inline void lv_slider_set_range(lv_obj_t * slider, int16_t min, int16_t max)\n{\n    lv_bar_set_range(slider, min, max);\n}\n\n/**\n * Set the animation time of the slider\n * @param slider pointer to a bar object\n * @param anim_time the animation time in milliseconds.\n */\nstatic inline void lv_slider_set_anim_time(lv_obj_t * slider, uint16_t anim_time)\n{\n    lv_bar_set_anim_time(slider, anim_time);\n}\n\n/**\n * Set the 'knob in' attribute of a slider\n * @param slider pointer to slider object\n * @param in true: the knob is drawn always in the slider;\n *           false: the knob can be out on the edges\n */\nvoid lv_slider_set_knob_in(lv_obj_t * slider, bool in);\n\n/**\n * Set a style of a slider\n * @param slider pointer to a slider object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_slider_set_style(lv_obj_t * slider, lv_slider_style_t type, const lv_style_t * style);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the value of a slider\n * @param slider pointer to a slider object\n * @return the value of the slider\n */\nint16_t lv_slider_get_value(const lv_obj_t * slider);\n\n/**\n * Get the minimum value of a slider\n * @param slider pointer to a slider object\n * @return the minimum value of the slider\n */\nstatic inline int16_t lv_slider_get_min_value(const lv_obj_t * slider)\n{\n    return lv_bar_get_min_value(slider);\n}\n\n/**\n * Get the maximum value of a slider\n * @param slider pointer to a slider object\n * @return the maximum value of the slider\n */\nstatic inline int16_t lv_slider_get_max_value(const lv_obj_t * slider)\n{\n    return lv_bar_get_max_value(slider);\n}\n\n/**\n * Give the slider is being dragged or not\n * @param slider pointer to a slider object\n * @return true: drag in progress false: not dragged\n */\nbool lv_slider_is_dragged(const lv_obj_t * slider);\n\n/**\n * Get the 'knob in' attribute of a slider\n * @param slider pointer to slider object\n * @return true: the knob is drawn always in the slider;\n *         false: the knob can be out on the edges\n */\nbool lv_slider_get_knob_in(const lv_obj_t * slider);\n\n/**\n * Get a style of a slider\n * @param slider pointer to a slider object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_slider_get_style(const lv_obj_t * slider, lv_slider_style_t type);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_SLIDER*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_SLIDER_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_spinbox.h",
    "content": "/**\n * @file lv_spinbox.h\n *\n */\n\n#ifndef LV_SPINBOX_H\n#define LV_SPINBOX_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_SPINBOX != 0\n\n/*Testing of dependencies*/\n#if LV_USE_TA == 0\n#error \"lv_spinbox: lv_ta is required. Enable it in lv_conf.h (LV_USE_TA  1) \"\n#endif\n\n#include \"../lv_core/lv_obj.h\"\n#include \"../lv_objx/lv_ta.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_SPINBOX_MAX_DIGIT_COUNT 16\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/*Data of spinbox*/\ntypedef struct\n{\n    lv_ta_ext_t ta; /*Ext. of ancestor*/\n    /*New data for this type */\n    int32_t value;\n    int32_t range_max;\n    int32_t range_min;\n    int32_t step;\n    uint16_t digit_count : 4;\n    uint16_t dec_point_pos : 4; /*if 0, there is no separator and the number is an integer*/\n    uint16_t digit_padding_left : 4;\n} lv_spinbox_ext_t;\n\n/*Styles*/\nenum {\n    LV_SPINBOX_STYLE_BG,\n    LV_SPINBOX_STYLE_SB,\n    LV_SPINBOX_STYLE_CURSOR,\n};\ntypedef uint8_t lv_spinbox_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a spinbox objects\n * @param par pointer to an object, it will be the parent of the new spinbox\n * @param copy pointer to a spinbox object, if not NULL then the new object will be copied from it\n * @return pointer to the created spinbox\n */\nlv_obj_t * lv_spinbox_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a style of a spinbox.\n * @param templ pointer to template object\n * @param type which style should be set\n * @param style pointer to a style\n */\nstatic inline void lv_spinbox_set_style(lv_obj_t * spinbox, lv_spinbox_style_t type, lv_style_t * style)\n{\n    lv_ta_set_style(spinbox, type, style);\n}\n\n/**\n * Set spinbox value\n * @param spinbox pointer to spinbox\n * @param i value to be set\n */\nvoid lv_spinbox_set_value(lv_obj_t * spinbox, int32_t i);\n\n/**\n * Set spinbox digit format (digit count and decimal format)\n * @param spinbox pointer to spinbox\n * @param digit_count number of digit excluding the decimal separator and the sign\n * @param separator_position number of digit before the decimal point. If 0, decimal point is not\n * shown\n */\nvoid lv_spinbox_set_digit_format(lv_obj_t * spinbox, uint8_t digit_count, uint8_t separator_position);\n\n/**\n * Set spinbox step\n * @param spinbox pointer to spinbox\n * @param step steps on increment/decrement\n */\nvoid lv_spinbox_set_step(lv_obj_t * spinbox, uint32_t step);\n\n/**\n * Set spinbox value range\n * @param spinbox pointer to spinbox\n * @param range_min maximum value, inclusive\n * @param range_max minimum value, inclusive\n */\nvoid lv_spinbox_set_range(lv_obj_t * spinbox, int32_t range_min, int32_t range_max);\n\n/**\n * Set spinbox left padding in digits count (added between sign and first digit)\n * @param spinbox pointer to spinbox\n * @param cb Callback function called on value change event\n */\nvoid lv_spinbox_set_padding_left(lv_obj_t * spinbox, uint8_t padding);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get style of a spinbox.\n * @param templ pointer to template object\n * @param type which style should be get\n * @return style pointer to the style\n */\nstatic inline const lv_style_t * lv_spinbox_get_style(lv_obj_t * spinbox, lv_spinbox_style_t type)\n{\n    return lv_ta_get_style(spinbox, type);\n}\n\n/**\n * Get the spinbox numeral value (user has to convert to float according to its digit format)\n * @param spinbox pointer to spinbox\n * @return value integer value of the spinbox\n */\nint32_t lv_spinbox_get_value(lv_obj_t * spinbox);\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Select next lower digit for edition by dividing the step by 10\n * @param spinbox pointer to spinbox\n */\nvoid lv_spinbox_step_next(lv_obj_t * spinbox);\n\n/**\n * Select next higher digit for edition by multiplying the step by 10\n * @param spinbox pointer to spinbox\n */\nvoid lv_spinbox_step_prev(lv_obj_t * spinbox);\n\n/**\n * Increment spinbox value by one step\n * @param spinbox pointer to spinbox\n */\nvoid lv_spinbox_increment(lv_obj_t * spinbox);\n\n/**\n * Decrement spinbox value by one step\n * @param spinbox pointer to spinbox\n */\nvoid lv_spinbox_decrement(lv_obj_t * spinbox);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_SPINBOX*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_SPINBOX_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_sw.h",
    "content": "/**\n * @file lv_sw.h\n *\n */\n\n#ifndef LV_SW_H\n#define LV_SW_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_SW != 0\n\n/*Testing of dependencies*/\n#if LV_USE_SLIDER == 0\n#error \"lv_sw: lv_slider is required. Enable it in lv_conf.h (LV_USE_SLIDER  1)\"\n#endif\n\n#include \"../lv_core/lv_obj.h\"\n#include \"lv_slider.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_SW_MAX_VALUE 100\n\n/**********************\n *      TYPEDEFS\n **********************/\n/*Data of switch*/\ntypedef struct\n{\n    lv_slider_ext_t slider; /*Ext. of ancestor*/\n    /*New data for this type */\n    const lv_style_t * style_knob_off; /**< Style of the knob when the switch is OFF*/\n    const lv_style_t * style_knob_on;  /**< Style of the knob when the switch is ON (NULL to use the same as OFF)*/\n    lv_coord_t start_x;\n    uint8_t changed : 1; /*Indicates the switch state explicitly changed by drag*/\n    uint8_t slided : 1;\n#if LV_USE_ANIMATION\n    uint16_t anim_time; /*switch animation time */\n#endif\n} lv_sw_ext_t;\n\n/**\n * Switch styles.\n */\nenum {\n    LV_SW_STYLE_BG, /**< Switch background. */\n    LV_SW_STYLE_INDIC, /**< Switch fill area. */\n    LV_SW_STYLE_KNOB_OFF, /**< Switch knob (when off). */\n    LV_SW_STYLE_KNOB_ON, /**< Switch knob (when on). */\n};\ntypedef uint8_t lv_sw_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a switch objects\n * @param par pointer to an object, it will be the parent of the new switch\n * @param copy pointer to a switch object, if not NULL then the new object will be copied from it\n * @return pointer to the created switch\n */\nlv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Turn ON the switch\n * @param sw pointer to a switch object\n * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately\n */\nvoid lv_sw_on(lv_obj_t * sw, lv_anim_enable_t anim);\n\n/**\n * Turn OFF the switch\n * @param sw pointer to a switch object\n * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately\n */\nvoid lv_sw_off(lv_obj_t * sw, lv_anim_enable_t anim);\n\n/**\n * Toggle the position of the switch\n * @param sw pointer to a switch object\n * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately\n * @return resulting state of the switch.\n */\nbool lv_sw_toggle(lv_obj_t * sw, lv_anim_enable_t anim);\n\n/**\n * Set a style of a switch\n * @param sw pointer to a switch object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_sw_set_style(lv_obj_t * sw, lv_sw_style_t type, const lv_style_t * style);\n\n/**\n * Set the animation time of the switch\n * @param sw pointer to a  switch object\n * @param anim_time animation time\n * @return style pointer to a style\n */\nvoid lv_sw_set_anim_time(lv_obj_t * sw, uint16_t anim_time);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the state of a switch\n * @param sw pointer to a switch object\n * @return false: OFF; true: ON\n */\nstatic inline bool lv_sw_get_state(const lv_obj_t * sw)\n{\n    return lv_bar_get_value(sw) < LV_SW_MAX_VALUE / 2 ? false : true;\n}\n\n/**\n * Get a style of a switch\n * @param sw pointer to a  switch object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_sw_get_style(const lv_obj_t * sw, lv_sw_style_t type);\n\n/**\n * Get the animation time of the switch\n * @param sw pointer to a  switch object\n * @return style pointer to a style\n */\nuint16_t lv_sw_get_anim_time(const lv_obj_t * sw);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_SW*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_SW_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_ta.h",
    "content": "/**\n * @file lv_ta.h\n *\n */\n\n#ifndef LV_TA_H\n#define LV_TA_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_TA != 0\n\n/*Testing of dependencies*/\n#if LV_USE_PAGE == 0\n#error \"lv_ta: lv_page is required. Enable it in lv_conf.h (LV_USE_PAGE  1) \"\n#endif\n\n#if LV_USE_LABEL == 0\n#error \"lv_ta: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL  1) \"\n#endif\n\n#include \"../lv_core/lv_obj.h\"\n#include \"lv_page.h\"\n#include \"lv_label.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_TA_CURSOR_LAST (0x7FFF) /*Put the cursor after the last character*/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/** Style of text area's cursor. */\nenum {\n    LV_CURSOR_NONE, /**< No cursor */\n    LV_CURSOR_LINE, /**< Vertical line */\n    LV_CURSOR_BLOCK, /**< Rectangle */\n    LV_CURSOR_OUTLINE, /**< Outline around character */\n    LV_CURSOR_UNDERLINE, /**< Horizontal line under character */\n    LV_CURSOR_HIDDEN = 0x08, /**< This flag can be ORed to any of the other values to temporarily hide the cursor */\n};\ntypedef uint8_t lv_cursor_type_t;\n\n/*Data of text area*/\ntypedef struct\n{\n    lv_page_ext_t page; /*Ext. of ancestor*/\n    /*New data for this type */\n    lv_obj_t * label;            /*Label of the text area*/\n    lv_obj_t * placeholder;      /*Place holder label. only visible if text is an empty string*/\n    char * pwd_tmp;              /*Used to store the original text in password mode*/\n    const char * accapted_chars; /*Only these characters will be accepted. NULL: accept all*/\n    uint16_t max_length;         /*The max. number of characters. 0: no limit*/\n    uint16_t pwd_show_time;      /*Time to show characters in password mode before change them to '*' */\n    struct\n    {\n        const lv_style_t * style;  /* Style of the cursor (NULL to use label's style)*/\n        lv_coord_t valid_x;        /* Used when stepping up/down to a shorter line.\n                                    * (Used by the library)*/\n        uint16_t pos;              /* The current cursor position\n                                    * (0: before 1st letter; 1: before 2nd letter ...)*/\n        uint16_t blink_time;       /*Blink period*/\n        lv_area_t area;            /* Cursor area relative to the Text Area*/\n        uint16_t txt_byte_pos;     /* Byte index of the letter after (on) the cursor*/\n        lv_cursor_type_t type : 4; /* Shape of the cursor*/\n        uint8_t state : 1;         /*Cursor is visible now or not (Handled by the library)*/\n        uint8_t click_pos : 1;     /*1: Enable positioning the cursor by clicking the text area*/\n    } cursor;\n#if LV_LABEL_TEXT_SEL\n    uint16_t tmp_sel_start;       /*Temporary value*/\n    uint16_t tmp_sel_end;         /*Temporary value*/\n    uint8_t text_sel_in_prog : 1; /*User is in process of selecting */\n    uint8_t text_sel_en : 1;      /*Text can be selected on this text area*/\n#endif\n    uint8_t pwd_mode : 1; /*Replace characters with '*' */\n    uint8_t one_line : 1; /*One line mode (ignore line breaks)*/\n} lv_ta_ext_t;\n\n/** Possible text areas tyles. */\nenum {\n    LV_TA_STYLE_BG, /**< Text area background style */\n    LV_TA_STYLE_SB, /**< Scrollbar style */\n    LV_TA_STYLE_CURSOR, /**< Cursor style */\n    LV_TA_STYLE_EDGE_FLASH, /**< Edge flash style */\n    LV_TA_STYLE_PLACEHOLDER, /**< Placeholder style */\n};\ntypedef uint8_t lv_ta_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a text area objects\n * @param par pointer to an object, it will be the parent of the new text area\n * @param copy pointer to a text area object, if not NULL then the new object will be copied from it\n * @return pointer to the created text area\n */\nlv_obj_t * lv_ta_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/**\n * Insert a character to the current cursor position.\n * To add a wide char, e.g. 'Á' use `lv_txt_encoded_conv_wc('Á')`\n * @param ta pointer to a text area object\n * @param c a character (e.g. 'a')\n */\nvoid lv_ta_add_char(lv_obj_t * ta, uint32_t c);\n\n/**\n * Insert a text to the current cursor position\n * @param ta pointer to a text area object\n * @param txt a '\\0' terminated string to insert\n */\nvoid lv_ta_add_text(lv_obj_t * ta, const char * txt);\n\n/**\n * Delete a the left character from the current cursor position\n * @param ta pointer to a text area object\n */\nvoid lv_ta_del_char(lv_obj_t * ta);\n\n/**\n * Delete the right character from the current cursor position\n * @param ta pointer to a text area object\n */\nvoid lv_ta_del_char_forward(lv_obj_t * ta);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the text of a text area\n * @param ta pointer to a text area\n * @param txt pointer to the text\n */\nvoid lv_ta_set_text(lv_obj_t * ta, const char * txt);\n\n/**\n * Set the placeholder text of a text area\n * @param ta pointer to a text area\n * @param txt pointer to the text\n */\nvoid lv_ta_set_placeholder_text(lv_obj_t * ta, const char * txt);\n\n/**\n * Set the cursor position\n * @param obj pointer to a text area object\n * @param pos the new cursor position in character index\n *             < 0 : index from the end of the text\n *             LV_TA_CURSOR_LAST: go after the last character\n */\nvoid lv_ta_set_cursor_pos(lv_obj_t * ta, int16_t pos);\n\n/**\n * Set the cursor type.\n * @param ta pointer to a text area object\n * @param cur_type: element of 'lv_cursor_type_t'\n */\nvoid lv_ta_set_cursor_type(lv_obj_t * ta, lv_cursor_type_t cur_type);\n\n/**\n * Enable/Disable the positioning of the the cursor by clicking the text on the text area.\n * @param ta pointer to a text area object\n * @param en true: enable click positions; false: disable\n */\nvoid lv_ta_set_cursor_click_pos(lv_obj_t * ta, bool en);\n\n/**\n * Enable/Disable password mode\n * @param ta pointer to a text area object\n * @param en true: enable, false: disable\n */\nvoid lv_ta_set_pwd_mode(lv_obj_t * ta, bool en);\n\n/**\n * Configure the text area to one line or back to normal\n * @param ta pointer to a Text area object\n * @param en true: one line, false: normal\n */\nvoid lv_ta_set_one_line(lv_obj_t * ta, bool en);\n\n/**\n * Set the alignment of the text area.\n * In one line mode the text can be scrolled only with `LV_LABEL_ALIGN_LEFT`.\n * This function should be called if the size of text area changes.\n * @param ta pointer to a text are object\n * @param align the desired alignment from `lv_label_align_t`. (LV_LABEL_ALIGN_LEFT/CENTER/RIGHT)\n */\nvoid lv_ta_set_text_align(lv_obj_t * ta, lv_label_align_t align);\n\n/**\n * Set a list of characters. Only these characters will be accepted by the text area\n * @param ta pointer to  Text Area\n * @param list list of characters. Only the pointer is saved. E.g. \"+-.,0123456789\"\n */\nvoid lv_ta_set_accepted_chars(lv_obj_t * ta, const char * list);\n\n/**\n * Set max length of a Text Area.\n * @param ta pointer to  Text Area\n * @param num the maximal number of characters can be added (`lv_ta_set_text` ignores it)\n */\nvoid lv_ta_set_max_length(lv_obj_t * ta, uint16_t num);\n\n/**\n * In `LV_EVENT_INSERT` the text which planned to be inserted can be replaced by an other text.\n * It can be used to add automatic formatting to the text area.\n * @param ta pointer to a text area.\n * @param txt pointer to a new string to insert. If `\"\"` no text will be added.\n *            The variable must be live after the `event_cb` exists. (Should be `global` or\n * `static`)\n */\nvoid lv_ta_set_insert_replace(lv_obj_t * ta, const char * txt);\n\n/**\n * Set the scroll bar mode of a text area\n * @param ta pointer to a text area object\n * @param sb_mode the new mode from 'lv_page_sb_mode_t' enum\n */\nstatic inline void lv_ta_set_sb_mode(lv_obj_t * ta, lv_sb_mode_t mode)\n{\n    lv_page_set_sb_mode(ta, mode);\n}\n\n/**\n * Enable the scroll propagation feature. If enabled then the Text area will move its parent if\n * there is no more space to scroll.\n * @param ta pointer to a Text area\n * @param en true or false to enable/disable scroll propagation\n */\nstatic inline void lv_ta_set_scroll_propagation(lv_obj_t * ta, bool en)\n{\n    lv_page_set_scroll_propagation(ta, en);\n}\n\n/**\n * Enable the edge flash effect. (Show an arc when the an edge is reached)\n * @param page pointer to a Text Area\n * @param en true or false to enable/disable end flash\n */\nstatic inline void lv_ta_set_edge_flash(lv_obj_t * ta, bool en)\n{\n    lv_page_set_edge_flash(ta, en);\n}\n\n/**\n * Set a style of a text area\n * @param ta pointer to a text area object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_ta_set_style(lv_obj_t * ta, lv_ta_style_t type, const lv_style_t * style);\n\n/**\n * Enable/disable selection mode.\n * @param ta pointer to a text area object\n * @param en true or false to enable/disable selection mode\n */\nvoid lv_ta_set_text_sel(lv_obj_t * ta, bool en);\n\n/**\n * Set how long show the password before changing it to '*'\n * @param ta pointer to Text area\n * @param time show time in milliseconds. 0: hide immediately.\n */\nvoid lv_ta_set_pwd_show_time(lv_obj_t * ta, uint16_t time);\n\n/**\n * Set cursor blink animation time\n * @param ta pointer to Text area\n * @param time blink period. 0: disable blinking\n */\nvoid lv_ta_set_cursor_blink_time(lv_obj_t * ta, uint16_t time);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the text of a text area. In password mode it gives the real text (not '*'s).\n * @param ta pointer to a text area object\n * @return pointer to the text\n */\nconst char * lv_ta_get_text(const lv_obj_t * ta);\n\n/**\n * Get the placeholder text of a text area\n * @param ta pointer to a text area object\n * @return pointer to the text\n */\nconst char * lv_ta_get_placeholder_text(lv_obj_t * ta);\n\n/**\n * Get the label of a text area\n * @param ta pointer to a text area object\n * @return pointer to the label object\n */\nlv_obj_t * lv_ta_get_label(const lv_obj_t * ta);\n\n/**\n * Get the current cursor position in character index\n * @param ta pointer to a text area object\n * @return the cursor position\n */\nuint16_t lv_ta_get_cursor_pos(const lv_obj_t * ta);\n\n/**\n * Get the current cursor type.\n * @param ta pointer to a text area object\n * @return element of 'lv_cursor_type_t'\n */\nlv_cursor_type_t lv_ta_get_cursor_type(const lv_obj_t * ta);\n\n/**\n * Get whether the cursor click positioning is enabled or not.\n * @param ta pointer to a text area object\n * @return true: enable click positions; false: disable\n */\nbool lv_ta_get_cursor_click_pos(lv_obj_t * ta);\n\n/**\n * Get the password mode attribute\n * @param ta pointer to a text area object\n * @return true: password mode is enabled, false: disabled\n */\nbool lv_ta_get_pwd_mode(const lv_obj_t * ta);\n\n/**\n * Get the one line configuration attribute\n * @param ta pointer to a text area object\n * @return true: one line configuration is enabled, false: disabled\n */\nbool lv_ta_get_one_line(const lv_obj_t * ta);\n\n/**\n * Get a list of accepted characters.\n * @param ta pointer to  Text Area\n * @return list of accented characters.\n */\nconst char * lv_ta_get_accepted_chars(lv_obj_t * ta);\n\n/**\n * Set max length of a Text Area.\n * @param ta pointer to  Text Area\n * @return the maximal number of characters to be add\n */\nuint16_t lv_ta_get_max_length(lv_obj_t * ta);\n\n/**\n * Get the scroll bar mode of a text area\n * @param ta pointer to a text area object\n * @return scrollbar mode from 'lv_page_sb_mode_t' enum\n */\nstatic inline lv_sb_mode_t lv_ta_get_sb_mode(const lv_obj_t * ta)\n{\n    return lv_page_get_sb_mode(ta);\n}\n\n/**\n * Get the scroll propagation property\n * @param ta pointer to a Text area\n * @return true or false\n */\nstatic inline bool lv_ta_get_scroll_propagation(lv_obj_t * ta)\n{\n    return lv_page_get_scroll_propagation(ta);\n}\n\n/**\n * Get the scroll propagation property\n * @param ta pointer to a Text area\n * @return true or false\n */\nstatic inline bool lv_ta_get_edge_flash(lv_obj_t * ta)\n{\n    return lv_page_get_edge_flash(ta);\n}\n\n/**\n * Get a style of a text area\n * @param ta pointer to a text area object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_ta_get_style(const lv_obj_t * ta, lv_ta_style_t type);\n\n/**\n * Find whether text is selected or not.\n * @param ta Text area object\n * @return whether text is selected or not\n */\nbool lv_ta_text_is_selected(const lv_obj_t * ta);\n\n/**\n * Find whether selection mode is enabled.\n * @param ta pointer to a text area object\n * @return true: selection mode is enabled, false: disabled\n */\nbool lv_ta_get_text_sel_en(lv_obj_t * ta);\n\n/**\n * Set how long show the password before changing it to '*'\n * @param ta pointer to Text area\n * @return show time in milliseconds. 0: hide immediately.\n */\nuint16_t lv_ta_get_pwd_show_time(lv_obj_t * ta);\n\n/**\n * Set cursor blink animation time\n * @param ta pointer to Text area\n * @return time blink period. 0: disable blinking\n */\nuint16_t lv_ta_get_cursor_blink_time(lv_obj_t * ta);\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Clear the selection on the text area.\n * @param ta Text area object\n */\nvoid lv_ta_clear_selection(lv_obj_t * ta);\n\n/**\n * Move the cursor one character right\n * @param ta pointer to a text area object\n */\nvoid lv_ta_cursor_right(lv_obj_t * ta);\n\n/**\n * Move the cursor one character left\n * @param ta pointer to a text area object\n */\nvoid lv_ta_cursor_left(lv_obj_t * ta);\n\n/**\n * Move the cursor one line down\n * @param ta pointer to a text area object\n */\nvoid lv_ta_cursor_down(lv_obj_t * ta);\n\n/**\n * Move the cursor one line up\n * @param ta pointer to a text area object\n */\nvoid lv_ta_cursor_up(lv_obj_t * ta);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_TA_H*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_TA_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_table.h",
    "content": "/**\n * @file lv_table.h\n *\n */\n\n#ifndef LV_TABLE_H\n#define LV_TABLE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_TABLE != 0\n\n/*Testing of dependencies*/\n#if LV_USE_LABEL == 0\n#error \"lv_table: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL  1) \"\n#endif\n\n#include \"../lv_core/lv_obj.h\"\n#include \"lv_label.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#ifndef LV_TABLE_COL_MAX\n#define LV_TABLE_COL_MAX 12\n#endif\n\n#define LV_TABLE_CELL_STYLE_CNT 4\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**\n * Internal table cell format structure.\n * \n * Use the `lv_table` APIs instead.\n */\ntypedef union\n{\n    struct\n    {\n        uint8_t align : 2;\n        uint8_t right_merge : 1;\n        uint8_t type : 2;\n        uint8_t crop : 1;\n    } s;\n    uint8_t format_byte;\n} lv_table_cell_format_t;\n\n/*Data of table*/\ntypedef struct\n{\n    /*New data for this type */\n    uint16_t col_cnt;\n    uint16_t row_cnt;\n    char ** cell_data;\n    const lv_style_t * cell_style[LV_TABLE_CELL_STYLE_CNT];\n    lv_coord_t col_w[LV_TABLE_COL_MAX];\n} lv_table_ext_t;\n\n/*Styles*/\nenum {\n    LV_TABLE_STYLE_BG,\n    LV_TABLE_STYLE_CELL1,\n    LV_TABLE_STYLE_CELL2,\n    LV_TABLE_STYLE_CELL3,\n    LV_TABLE_STYLE_CELL4,\n};\ntypedef uint8_t lv_table_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a table object\n * @param par pointer to an object, it will be the parent of the new table\n * @param copy pointer to a table object, if not NULL then the new object will be copied from it\n * @return pointer to the created table\n */\nlv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the value of a cell.\n * @param table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @param txt text to display in the cell. It will be copied and saved so this variable is not\n * required after this function call.\n */\nvoid lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const char * txt);\n\n/**\n * Set the number of rows\n * @param table table pointer to a Table object\n * @param row_cnt number of rows\n */\nvoid lv_table_set_row_cnt(lv_obj_t * table, uint16_t row_cnt);\n\n/**\n * Set the number of columns\n * @param table table pointer to a Table object\n * @param col_cnt number of columns. Must be < LV_TABLE_COL_MAX\n */\nvoid lv_table_set_col_cnt(lv_obj_t * table, uint16_t col_cnt);\n\n/**\n * Set the width of a column\n * @param table table pointer to a Table object\n * @param col_id id of the column [0 .. LV_TABLE_COL_MAX -1]\n * @param w width of the column\n */\nvoid lv_table_set_col_width(lv_obj_t * table, uint16_t col_id, lv_coord_t w);\n\n/**\n * Set the text align in a cell\n * @param table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @param align LV_LABEL_ALIGN_LEFT or LV_LABEL_ALIGN_CENTER or LV_LABEL_ALIGN_RIGHT\n */\nvoid lv_table_set_cell_align(lv_obj_t * table, uint16_t row, uint16_t col, lv_label_align_t align);\n\n/**\n * Set the type of a cell.\n * @param table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @param type 1,2,3 or 4. The cell style will be chosen accordingly.\n */\nvoid lv_table_set_cell_type(lv_obj_t * table, uint16_t row, uint16_t col, uint8_t type);\n\n/**\n * Set the cell crop. (Don't adjust the height of the cell according to its content)\n * @param table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @param crop true: crop the cell content; false: set the cell height to the content.\n */\nvoid lv_table_set_cell_crop(lv_obj_t * table, uint16_t row, uint16_t col, bool crop);\n\n/**\n * Merge a cell with the right neighbor. The value of the cell to the right won't be displayed.\n * @param table table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @param en true: merge right; false: don't merge right\n */\nvoid lv_table_set_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col, bool en);\n\n/**\n * Set a style of a table.\n * @param table pointer to table object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_table_set_style(lv_obj_t * table, lv_table_style_t type, const lv_style_t * style);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the value of a cell.\n * @param table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @return text in the cell\n */\nconst char * lv_table_get_cell_value(lv_obj_t * table, uint16_t row, uint16_t col);\n\n/**\n * Get the number of rows.\n * @param table table pointer to a Table object\n * @return number of rows.\n */\nuint16_t lv_table_get_row_cnt(lv_obj_t * table);\n\n/**\n * Get the number of columns.\n * @param table table pointer to a Table object\n * @return number of columns.\n */\nuint16_t lv_table_get_col_cnt(lv_obj_t * table);\n\n/**\n * Get the width of a column\n * @param table table pointer to a Table object\n * @param col_id id of the column [0 .. LV_TABLE_COL_MAX -1]\n * @return width of the column\n */\nlv_coord_t lv_table_get_col_width(lv_obj_t * table, uint16_t col_id);\n\n/**\n * Get the text align of a cell\n * @param table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @return LV_LABEL_ALIGN_LEFT (default in case of error) or LV_LABEL_ALIGN_CENTER or\n * LV_LABEL_ALIGN_RIGHT\n */\nlv_label_align_t lv_table_get_cell_align(lv_obj_t * table, uint16_t row, uint16_t col);\n\n/**\n * Get the type of a cell\n * @param table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @return 1,2,3 or 4\n */\nlv_label_align_t lv_table_get_cell_type(lv_obj_t * table, uint16_t row, uint16_t col);\n\n/**\n * Get the crop property of a cell\n * @param table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @return true: text crop enabled; false: disabled\n */\nlv_label_align_t lv_table_get_cell_crop(lv_obj_t * table, uint16_t row, uint16_t col);\n\n/**\n * Get the cell merge attribute.\n * @param table table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @return true: merge right; false: don't merge right\n */\nbool lv_table_get_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col);\n\n/**\n * Get style of a table.\n * @param table pointer to table object\n * @param type which style should be get\n * @return style pointer to the style\n */\nconst lv_style_t * lv_table_get_style(const lv_obj_t * table, lv_table_style_t type);\n\n/*=====================\n * Other functions\n *====================*/\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_TABLE*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_TABLE_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_tabview.h",
    "content": "/**\n * @file lv_tabview.h\n *\n */\n\n#ifndef LV_TABVIEW_H\n#define LV_TABVIEW_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_TABVIEW != 0\n\n/*Testing of dependencies*/\n#if LV_USE_BTNM == 0\n#error \"lv_tabview: lv_btnm is required. Enable it in lv_conf.h (LV_USE_BTNM  1) \"\n#endif\n\n#if LV_USE_PAGE == 0\n#error \"lv_tabview: lv_page is required. Enable it in lv_conf.h (LV_USE_PAGE  1) \"\n#endif\n\n#include \"../lv_core/lv_obj.h\"\n#include \"../lv_objx/lv_win.h\"\n#include \"../lv_objx/lv_page.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/** Position of tabview buttons. */\nenum { LV_TABVIEW_BTNS_POS_TOP, LV_TABVIEW_BTNS_POS_BOTTOM, LV_TABVIEW_BTNS_POS_LEFT, LV_TABVIEW_BTNS_POS_RIGHT };\ntypedef uint8_t lv_tabview_btns_pos_t;\n\n/*Data of tab*/\ntypedef struct\n{\n    /*Ext. of ancestor*/\n    /*New data for this type */\n    lv_obj_t * btns;\n    lv_obj_t * indic;\n    lv_obj_t * content; /*A rectangle to show the current tab*/\n    const char ** tab_name_ptr;\n    lv_point_t point_last;\n    uint16_t tab_cur;\n    uint16_t tab_cnt;\n#if LV_USE_ANIMATION\n    uint16_t anim_time;\n#endif\n    uint8_t slide_enable : 1; /*1: enable horizontal sliding by touch pad*/\n    uint8_t draging : 1;\n    uint8_t drag_hor : 1;\n    uint8_t scroll_ver : 1;\n    uint8_t btns_hide : 1;\n    lv_tabview_btns_pos_t btns_pos : 2;\n} lv_tabview_ext_t;\n\nenum {\n    LV_TABVIEW_STYLE_BG,\n    LV_TABVIEW_STYLE_INDIC,\n    LV_TABVIEW_STYLE_BTN_BG,\n    LV_TABVIEW_STYLE_BTN_REL,\n    LV_TABVIEW_STYLE_BTN_PR,\n    LV_TABVIEW_STYLE_BTN_TGL_REL,\n    LV_TABVIEW_STYLE_BTN_TGL_PR,\n};\ntypedef uint8_t lv_tabview_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a Tab view object\n * @param par pointer to an object, it will be the parent of the new tab\n * @param copy pointer to a tab object, if not NULL then the new object will be copied from it\n * @return pointer to the created tab\n */\nlv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/**\n * Delete all children of the scrl object, without deleting scrl child.\n * @param obj pointer to an object\n */\nvoid lv_tabview_clean(lv_obj_t * obj);\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/**\n * Add a new tab with the given name\n * @param tabview pointer to Tab view object where to ass the new tab\n * @param name the text on the tab button\n * @return pointer to the created page object (lv_page). You can create your content here\n */\nlv_obj_t * lv_tabview_add_tab(lv_obj_t * tabview, const char * name);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a new tab\n * @param tabview pointer to Tab view object\n * @param id index of a tab to load\n * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately\n */\nvoid lv_tabview_set_tab_act(lv_obj_t * tabview, uint16_t id, lv_anim_enable_t anim);\n\n/**\n * Enable horizontal sliding with touch pad\n * @param tabview pointer to Tab view object\n * @param en true: enable sliding; false: disable sliding\n */\nvoid lv_tabview_set_sliding(lv_obj_t * tabview, bool en);\n\n/**\n * Set the animation time of tab view when a new tab is loaded\n * @param tabview pointer to Tab view object\n * @param anim_time time of animation in milliseconds\n */\nvoid lv_tabview_set_anim_time(lv_obj_t * tabview, uint16_t anim_time);\n\n/**\n * Set the style of a tab view\n * @param tabview pointer to a tan view object\n * @param type which style should be set\n * @param style pointer to the new style\n */\nvoid lv_tabview_set_style(lv_obj_t * tabview, lv_tabview_style_t type, const lv_style_t * style);\n\n/**\n * Set the position of tab select buttons\n * @param tabview pointer to a tab view object\n * @param btns_pos which button position\n */\nvoid lv_tabview_set_btns_pos(lv_obj_t * tabview, lv_tabview_btns_pos_t btns_pos);\n\n/**\n * Set whether tab buttons are hidden\n * @param tabview pointer to a tab view object\n * @param en whether tab buttons are hidden\n */\nvoid lv_tabview_set_btns_hidden(lv_obj_t * tabview, bool en);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the index of the currently active tab\n * @param tabview pointer to Tab view object\n * @return the active tab index\n */\nuint16_t lv_tabview_get_tab_act(const lv_obj_t * tabview);\n\n/**\n * Get the number of tabs\n * @param tabview pointer to Tab view object\n * @return tab count\n */\nuint16_t lv_tabview_get_tab_count(const lv_obj_t * tabview);\n/**\n * Get the page (content area) of a tab\n * @param tabview pointer to Tab view object\n * @param id index of the tab (>= 0)\n * @return pointer to page (lv_page) object\n */\nlv_obj_t * lv_tabview_get_tab(const lv_obj_t * tabview, uint16_t id);\n\n/**\n * Get horizontal sliding is enabled or not\n * @param tabview pointer to Tab view object\n * @return true: enable sliding; false: disable sliding\n */\nbool lv_tabview_get_sliding(const lv_obj_t * tabview);\n\n/**\n * Get the animation time of tab view when a new tab is loaded\n * @param tabview pointer to Tab view object\n * @return time of animation in milliseconds\n */\nuint16_t lv_tabview_get_anim_time(const lv_obj_t * tabview);\n\n/**\n * Get a style of a tab view\n * @param tabview pointer to a ab view object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_tabview_get_style(const lv_obj_t * tabview, lv_tabview_style_t type);\n\n/**\n * Get position of tab select buttons\n * @param tabview pointer to a ab view object\n */\nlv_tabview_btns_pos_t lv_tabview_get_btns_pos(const lv_obj_t * tabview);\n\n/**\n * Get whether tab buttons are hidden\n * @param tabview pointer to a tab view object\n * @return whether tab buttons are hidden\n */\nbool lv_tabview_get_btns_hidden(const lv_obj_t * tabview);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_TABVIEW*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_TABVIEW_H*/"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_tileview.h",
    "content": "/**\n * @file lv_tileview.h\n *\n */\n\n#ifndef LV_TILEVIEW_H\n#define LV_TILEVIEW_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_TILEVIEW != 0\n\n#include \"../lv_objx/lv_page.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/*Data of tileview*/\ntypedef struct\n{\n    lv_page_ext_t page;\n    /*New data for this type */\n    const lv_point_t * valid_pos;\n    uint16_t valid_pos_cnt;\n#if LV_USE_ANIMATION\n    uint16_t anim_time;\n#endif\n    lv_point_t act_id;\n    uint8_t drag_top_en : 1;\n    uint8_t drag_bottom_en : 1;\n    uint8_t drag_left_en : 1;\n    uint8_t drag_right_en : 1;\n    uint8_t drag_hor : 1;\n    uint8_t drag_ver : 1;\n} lv_tileview_ext_t;\n\n/*Styles*/\nenum {\n    LV_TILEVIEW_STYLE_MAIN,\n};\ntypedef uint8_t lv_tileview_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a tileview objects\n * @param par pointer to an object, it will be the parent of the new tileview\n * @param copy pointer to a tileview object, if not NULL then the new object will be copied from it\n * @return pointer to the created tileview\n */\nlv_obj_t * lv_tileview_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/**\n * Register an object on the tileview. The register object will able to slide the tileview\n * @param tileview pointer to a Tileview object\n * @param element pointer to an object\n */\nvoid lv_tileview_add_element(lv_obj_t * tileview, lv_obj_t * element);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the valid position's indices. The scrolling will be possible only to these positions.\n * @param tileview pointer to a Tileview object\n * @param valid_pos array width the indices. E.g. `lv_point_t p[] = {{0,0}, {1,0}, {1,1}`. Only the\n * pointer is saved so can't be a local variable.\n * @param valid_pos_cnt numner of elements in `valid_pos` array\n */\nvoid lv_tileview_set_valid_positions(lv_obj_t * tileview, const lv_point_t * valid_pos, uint16_t valid_pos_cnt);\n\n/**\n * Set the tile to be shown\n * @param tileview pointer to a tileview object\n * @param x column id (0, 1, 2...)\n * @param y line id (0, 1, 2...)\n * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately\n */\nvoid lv_tileview_set_tile_act(lv_obj_t * tileview, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim);\n\n/**\n * Enable the edge flash effect. (Show an arc when the an edge is reached)\n * @param tileview pointer to a Tileview\n * @param en true or false to enable/disable end flash\n */\nstatic inline void lv_tileview_set_edge_flash(lv_obj_t * tileview, bool en)\n{\n    lv_page_set_edge_flash(tileview, en);\n}\n\n/**\n * Set the animation time for the Tile view\n * @param tileview pointer to a page object\n * @param anim_time animation time in milliseconds\n */\nstatic inline void lv_tileview_set_anim_time(lv_obj_t * tileview, uint16_t anim_time)\n{\n    lv_page_set_anim_time(tileview, anim_time);\n}\n\n/**\n * Set a style of a tileview.\n * @param tileview pointer to tileview object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_tileview_set_style(lv_obj_t * tileview, lv_tileview_style_t type, const lv_style_t * style);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the scroll propagation property\n * @param tileview pointer to a Tileview\n * @return true or false\n */\nstatic inline bool lv_tileview_get_edge_flash(lv_obj_t * tileview)\n{\n    return lv_page_get_edge_flash(tileview);\n}\n\n/**\n * Get the animation time for the Tile view\n * @param tileview pointer to a page object\n * @return animation time in milliseconds\n */\nstatic inline uint16_t lv_tileview_get_anim_time(lv_obj_t * tileview)\n{\n    return lv_page_get_anim_time(tileview);\n}\n\n/**\n * Get style of a tileview.\n * @param tileview pointer to tileview object\n * @param type which style should be get\n * @return style pointer to the style\n */\nconst lv_style_t * lv_tileview_get_style(const lv_obj_t * tileview, lv_tileview_style_t type);\n\n/*=====================\n * Other functions\n *====================*/\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_TILEVIEW*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_TILEVIEW_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_objx/lv_win.h",
    "content": "/**\n * @file lv_win.h\n *\n */\n\n#ifndef LV_WIN_H\n#define LV_WIN_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_WIN != 0\n\n/*Testing of dependencies*/\n#if LV_USE_BTN == 0\n#error \"lv_win: lv_btn is required. Enable it in lv_conf.h (LV_USE_BTN  1) \"\n#endif\n\n#if LV_USE_LABEL == 0\n#error \"lv_win: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL  1) \"\n#endif\n\n#if LV_USE_IMG == 0\n#error \"lv_win: lv_img is required. Enable it in lv_conf.h (LV_USE_IMG  1) \"\n#endif\n\n#if LV_USE_PAGE == 0\n#error \"lv_win: lv_page is required. Enable it in lv_conf.h (LV_USE_PAGE  1) \"\n#endif\n\n#include \"../lv_core/lv_obj.h\"\n#include \"lv_cont.h\"\n#include \"lv_btn.h\"\n#include \"lv_label.h\"\n#include \"lv_img.h\"\n#include \"lv_page.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/*Data of window*/\ntypedef struct\n{\n    /*Ext. of ancestor*/\n    /*New data for this type */\n    lv_obj_t * page;                  /*Pointer to a page which holds the content*/\n    lv_obj_t * header;                /*Pointer to the header container of the window*/\n    lv_obj_t * title;                 /*Pointer to the title label of the window*/\n    const lv_style_t * style_btn_rel; /*Control button releases style*/\n    const lv_style_t * style_btn_pr;  /*Control button pressed style*/\n    lv_coord_t btn_size;              /*Size of the control buttons (square)*/\n} lv_win_ext_t;\n\n/** Window styles. */\nenum {\n    LV_WIN_STYLE_BG, /**< Window object background style. */\n    LV_WIN_STYLE_CONTENT, /**< Window content style. */\n    LV_WIN_STYLE_SB, /**< Window scrollbar style. */\n    LV_WIN_STYLE_HEADER, /**< Window titlebar background style. */\n    LV_WIN_STYLE_BTN_REL, /**< Same meaning as ordinary button styles. */\n    LV_WIN_STYLE_BTN_PR,\n};\ntypedef uint8_t lv_win_style_t;\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Create a window objects\n * @param par pointer to an object, it will be the parent of the new window\n * @param copy pointer to a window object, if not NULL then the new object will be copied from it\n * @return pointer to the created window\n */\nlv_obj_t * lv_win_create(lv_obj_t * par, const lv_obj_t * copy);\n\n/**\n * Delete all children of the scrl object, without deleting scrl child.\n * @param obj pointer to an object\n */\nvoid lv_win_clean(lv_obj_t * obj);\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/**\n * Add control button to the header of the window\n * @param win pointer to a window object\n * @param img_src an image source ('lv_img_t' variable, path to file or a symbol)\n * @return pointer to the created button object\n */\nlv_obj_t * lv_win_add_btn(lv_obj_t * win, const void * img_src);\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Can be assigned to a window control button to close the window\n * @param btn pointer to the control button on teh widows header\n * @param evet the event type\n */\nvoid lv_win_close_event_cb(lv_obj_t * btn, lv_event_t event);\n\n/**\n * Set the title of a window\n * @param win pointer to a window object\n * @param title string of the new title\n */\nvoid lv_win_set_title(lv_obj_t * win, const char * title);\n\n/**\n * Set the control button size of a window\n * @param win pointer to a window object\n * @return control button size\n */\nvoid lv_win_set_btn_size(lv_obj_t * win, lv_coord_t size);\n\n/**\n * Set the layout of the window\n * @param win pointer to a window object\n * @param layout the layout from 'lv_layout_t'\n */\nvoid lv_win_set_layout(lv_obj_t * win, lv_layout_t layout);\n\n/**\n * Set the scroll bar mode of a window\n * @param win pointer to a window object\n * @param sb_mode the new scroll bar mode from  'lv_sb_mode_t'\n */\nvoid lv_win_set_sb_mode(lv_obj_t * win, lv_sb_mode_t sb_mode);\n\n/**\n * Set focus animation duration on `lv_win_focus()`\n * @param win pointer to a window object\n * @param anim_time duration of animation [ms]\n */\nvoid lv_win_set_anim_time(lv_obj_t * win, uint16_t anim_time);\n\n/**\n * Set a style of a window\n * @param win pointer to a window object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_win_set_style(lv_obj_t * win, lv_win_style_t type, const lv_style_t * style);\n\n/**\n * Set drag status of a window. If set to 'true' window can be dragged like on a PC.\n * @param win pointer to a window object\n * @param en whether dragging is enabled\n */\nvoid lv_win_set_drag(lv_obj_t * win, bool en);\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the title of a window\n * @param win pointer to a window object\n * @return title string of the window\n */\nconst char * lv_win_get_title(const lv_obj_t * win);\n\n/**\n * Get the content holder object of window (`lv_page`) to allow additional customization\n * @param win pointer to a window object\n * @return the Page object where the window's content is\n */\nlv_obj_t * lv_win_get_content(const lv_obj_t * win);\n\n/**\n * Get the control button size of a window\n * @param win pointer to a window object\n * @return control button size\n */\nlv_coord_t lv_win_get_btn_size(const lv_obj_t * win);\n\n/**\n * Get the pointer of a widow from one of  its control button.\n * It is useful in the action of the control buttons where only button is known.\n * @param ctrl_btn pointer to a control button of a window\n * @return pointer to the window of 'ctrl_btn'\n */\nlv_obj_t * lv_win_get_from_btn(const lv_obj_t * ctrl_btn);\n\n/**\n * Get the layout of a window\n * @param win pointer to a window object\n * @return the layout of the window (from 'lv_layout_t')\n */\nlv_layout_t lv_win_get_layout(lv_obj_t * win);\n\n/**\n * Get the scroll bar mode of a window\n * @param win pointer to a window object\n * @return the scroll bar mode of the window (from 'lv_sb_mode_t')\n */\nlv_sb_mode_t lv_win_get_sb_mode(lv_obj_t * win);\n\n/**\n * Get focus animation duration\n * @param win pointer to a window object\n * @return duration of animation [ms]\n */\nuint16_t lv_win_get_anim_time(const lv_obj_t * win);\n\n/**\n * Get width of the content area (page scrollable) of the window\n * @param win pointer to a window object\n * @return the width of the content area\n */\nlv_coord_t lv_win_get_width(lv_obj_t * win);\n\n/**\n * Get a style of a window\n * @param win pointer to a button object\n * @param type which style window be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_win_get_style(const lv_obj_t * win, lv_win_style_t type);\n\n/**\n * Get drag status of a window. If set to 'true' window can be dragged like on a PC.\n * @param win pointer to a window object\n * @return whether window is draggable\n */\nstatic inline bool lv_win_get_drag(const lv_obj_t * win)\n{\n    return lv_obj_get_drag(win);\n}\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Focus on an object. It ensures that the object will be visible in the window.\n * @param win pointer to a window object\n * @param obj pointer to an object to focus (must be in the window)\n * @param anim_en LV_ANIM_ON focus with an animation; LV_ANIM_OFF focus without animation\n */\nvoid lv_win_focus(lv_obj_t * win, lv_obj_t * obj, lv_anim_enable_t anim_en);\n\n/**\n * Scroll the window horizontally\n * @param win pointer to a window object\n * @param dist the distance to scroll (< 0: scroll right; > 0 scroll left)\n */\nstatic inline void lv_win_scroll_hor(lv_obj_t * win, lv_coord_t dist)\n{\n    lv_win_ext_t * ext = (lv_win_ext_t *)lv_obj_get_ext_attr(win);\n    lv_page_scroll_hor(ext->page, dist);\n}\n/**\n * Scroll the window vertically\n * @param win pointer to a window object\n * @param dist the distance to scroll (< 0: scroll down; > 0 scroll up)\n */\nstatic inline void lv_win_scroll_ver(lv_obj_t * win, lv_coord_t dist)\n{\n    lv_win_ext_t * ext = (lv_win_ext_t *)lv_obj_get_ext_attr(win);\n    lv_page_scroll_ver(ext->page, dist);\n}\n\n/**********************\n *      MACROS\n **********************/\n\n#endif /*LV_USE_WIN*/\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_WIN_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_themes/lv_theme.h",
    "content": "/**\n *@file lv_themes.h\n *\n */\n\n#ifndef LV_THEMES_H\n#define LV_THEMES_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *    INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#include \"../lv_core/lv_style.h\"\n#include \"../lv_core/lv_group.h\"\n\n/*********************\n *    DEFINES\n *********************/\n\n/**********************\n *    TYPEDEFS\n **********************/\n\n/**\n * A theme in LittlevGL consists of many styles bound together.\n * \n * There is a style for each object type, as well as a generic style for\n * backgrounds and panels.\n */\ntypedef struct\n{\n    struct\n    {\n        lv_style_t * scr;\n        lv_style_t * bg;\n        lv_style_t * panel;\n\n#if LV_USE_CONT != 0\n        lv_style_t * cont;\n#endif\n\n#if LV_USE_BTN != 0\n        struct\n        {\n            lv_style_t * rel;\n            lv_style_t * pr;\n            lv_style_t * tgl_rel;\n            lv_style_t * tgl_pr;\n            lv_style_t * ina;\n        } btn;\n#endif\n\n#if LV_USE_IMGBTN != 0\n        struct\n        {\n            lv_style_t * rel;\n            lv_style_t * pr;\n            lv_style_t * tgl_rel;\n            lv_style_t * tgl_pr;\n            lv_style_t * ina;\n        } imgbtn;\n#endif\n\n#if LV_USE_LABEL != 0\n        struct\n        {\n            lv_style_t * prim;\n            lv_style_t * sec;\n            lv_style_t * hint;\n        } label;\n#endif\n\n#if LV_USE_IMG != 0\n        struct\n        {\n            lv_style_t * light;\n            lv_style_t * dark;\n        } img;\n#endif\n\n#if LV_USE_LINE != 0\n        struct\n        {\n            lv_style_t * decor;\n        } line;\n#endif\n\n#if LV_USE_LED != 0\n        lv_style_t * led;\n#endif\n\n#if LV_USE_BAR != 0\n        struct\n        {\n            lv_style_t * bg;\n            lv_style_t * indic;\n        } bar;\n#endif\n\n#if LV_USE_SLIDER != 0\n        struct\n        {\n            lv_style_t * bg;\n            lv_style_t * indic;\n            lv_style_t * knob;\n        } slider;\n#endif\n\n#if LV_USE_LMETER != 0\n        lv_style_t * lmeter;\n#endif\n\n#if LV_USE_GAUGE != 0\n        lv_style_t * gauge;\n#endif\n\n#if LV_USE_ARC != 0\n        lv_style_t * arc;\n#endif\n\n#if LV_USE_PRELOAD != 0\n        lv_style_t * preload;\n#endif\n\n#if LV_USE_SW != 0\n        struct\n        {\n            lv_style_t * bg;\n            lv_style_t * indic;\n            lv_style_t * knob_off;\n            lv_style_t * knob_on;\n        } sw;\n#endif\n\n#if LV_USE_CHART != 0\n        lv_style_t * chart;\n#endif\n\n#if LV_USE_CALENDAR != 0\n        struct\n        {\n            lv_style_t * bg;\n            lv_style_t * header;\n            lv_style_t * header_pr;\n            lv_style_t * day_names;\n            lv_style_t * highlighted_days;\n            lv_style_t * inactive_days;\n            lv_style_t * week_box;\n            lv_style_t * today_box;\n        } calendar;\n#endif\n\n#if LV_USE_CB != 0\n        struct\n        {\n            lv_style_t * bg;\n            struct\n            {\n                lv_style_t * rel;\n                lv_style_t * pr;\n                lv_style_t * tgl_rel;\n                lv_style_t * tgl_pr;\n                lv_style_t * ina;\n            } box;\n        } cb;\n#endif\n\n#if LV_USE_BTNM != 0\n        struct\n        {\n            lv_style_t * bg;\n            struct\n            {\n                lv_style_t * rel;\n                lv_style_t * pr;\n                lv_style_t * tgl_rel;\n                lv_style_t * tgl_pr;\n                lv_style_t * ina;\n            } btn;\n        } btnm;\n#endif\n\n#if LV_USE_KB != 0\n        struct\n        {\n            lv_style_t * bg;\n            struct\n            {\n                lv_style_t * rel;\n                lv_style_t * pr;\n                lv_style_t * tgl_rel;\n                lv_style_t * tgl_pr;\n                lv_style_t * ina;\n            } btn;\n        } kb;\n#endif\n\n#if LV_USE_MBOX != 0\n        struct\n        {\n            lv_style_t * bg;\n            struct\n            {\n                lv_style_t * bg;\n                lv_style_t * rel;\n                lv_style_t * pr;\n            } btn;\n        } mbox;\n#endif\n\n#if LV_USE_PAGE != 0\n        struct\n        {\n            lv_style_t * bg;\n            lv_style_t * scrl;\n            lv_style_t * sb;\n        } page;\n#endif\n\n#if LV_USE_TA != 0\n        struct\n        {\n            lv_style_t * area;\n            lv_style_t * oneline;\n            lv_style_t * cursor;\n            lv_style_t * sb;\n        } ta;\n#endif\n\n#if LV_USE_SPINBOX != 0\n        struct\n        {\n            lv_style_t * bg;\n            lv_style_t * cursor;\n            lv_style_t * sb;\n        } spinbox;\n#endif\n\n#if LV_USE_LIST\n        struct\n        {\n            lv_style_t * bg;\n            lv_style_t * scrl;\n            lv_style_t * sb;\n            struct\n            {\n                lv_style_t * rel;\n                lv_style_t * pr;\n                lv_style_t * tgl_rel;\n                lv_style_t * tgl_pr;\n                lv_style_t * ina;\n            } btn;\n        } list;\n#endif\n\n#if LV_USE_DDLIST != 0\n        struct\n        {\n            lv_style_t * bg;\n            lv_style_t * sel;\n            lv_style_t * sb;\n        } ddlist;\n#endif\n\n#if LV_USE_ROLLER != 0\n        struct\n        {\n            lv_style_t * bg;\n            lv_style_t * sel;\n        } roller;\n#endif\n\n#if LV_USE_TABVIEW != 0\n        struct\n        {\n            lv_style_t * bg;\n            lv_style_t * indic;\n            struct\n            {\n                lv_style_t * bg;\n                lv_style_t * rel;\n                lv_style_t * pr;\n                lv_style_t * tgl_rel;\n                lv_style_t * tgl_pr;\n            } btn;\n        } tabview;\n#endif\n\n#if LV_USE_TILEVIEW != 0\n        struct\n        {\n            lv_style_t * bg;\n            lv_style_t * scrl;\n            lv_style_t * sb;\n        } tileview;\n#endif\n\n#if LV_USE_TABLE != 0\n        struct\n        {\n            lv_style_t * bg;\n            lv_style_t * cell;\n        } table;\n#endif\n\n#if LV_USE_WIN != 0\n        struct\n        {\n            lv_style_t * bg;\n            lv_style_t * sb;\n            lv_style_t * header;\n            lv_style_t * content;\n            struct\n            {\n                lv_style_t * rel;\n                lv_style_t * pr;\n            } btn;\n        } win;\n#endif\n    } style;\n\n#if LV_USE_GROUP\n    struct\n    {\n        /* The `x` in the names inidicates that inconsistence becasue\n         * the group related function are stored in the theme.*/\n        lv_group_style_mod_cb_t style_mod_xcb;\n        lv_group_style_mod_cb_t style_mod_edit_xcb;\n    } group;\n#endif\n} lv_theme_t;\n\n/**********************\n *  GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Set a theme for the system.\n * From now, all the created objects will use styles from this theme by default\n * @param th pointer to theme (return value of: 'lv_theme_init_xxx()')\n */\nvoid lv_theme_set_current(lv_theme_t * th);\n\n/**\n * Get the current system theme.\n * @return pointer to the current system theme. NULL if not set.\n */\nlv_theme_t * lv_theme_get_current(void);\n\n/**********************\n *    MACROS\n **********************/\n\n/* Returns number of styles within the `lv_theme_t` structure. */\n#define LV_THEME_STYLE_COUNT (sizeof(((lv_theme_t *)0)->style) / sizeof(lv_style_t *))\n\n/**********************\n *     POST INCLUDE\n *********************/\n#include \"lv_theme_default.h\"\n#include \"lv_theme_argon.h\"\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_THEMES_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_themes/lv_theme_argon.h",
    "content": "/**\n * @file lv_theme_argon.h\n *\n */\n\n#ifndef LV_THEME_ARGON_H\n#define LV_THEME_ARGON_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_THEME_ARGON\n\n/*********************\n *      DEFINES\n *********************/\n#define GRAD_1 LV_COLOR_MAKE(0xD3, 0x83, 0x12)\n#define GRAD_2 LV_COLOR_MAKE(0xA8, 0x32, 0x79)\n\n#define GUN_METAL           lv_color_hex(0x293132)\n#define ARGON_ORANGE        lv_color_hex(0xEB8258)\n#define ONYX                lv_color_hex(0x3A2E39)\n#define ARGON_PINK          lv_color_hex(0xB74F6F)\n#define ARGON_DARK_ORANGE   lv_color_hex(0xAD6A5A)\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Initialize the argon theme\n * @param hue [0..360] hue value from HSV color space to define the theme's base color\n * @param font pointer to a font (NULL to use the default)\n * @return pointer to the initialized theme\n */\nlv_theme_t * lv_theme_argon_init(uint16_t hue, lv_font_t * font);\n\n/**\n * Get a pointer to the theme\n * @return pointer to the theme\n */\nlv_theme_t * lv_theme_get_argon(void);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_THEME_ARGON_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_themes/lv_theme_default.h",
    "content": "/**\n * @file lv_theme_default.h\n *\n */\n\n#ifndef LV_THEME_DEFAULT_H\n#define LV_THEME_DEFAULT_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"../lv_conf.h\"\n#endif\n\n#if LV_USE_THEME_DEFAULT\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**\n * Initialize the default theme\n * @param hue [0..360] hue value from HSV color space to define the theme's base color\n * @param font pointer to a font (NULL to use the default)\n * @return pointer to the initialized theme\n */\nlv_theme_t * lv_theme_default_init(uint16_t hue, lv_font_t * font);\n\n/**\n * Get a pointer to the theme\n * @return pointer to the theme\n */\nlv_theme_t * lv_theme_get_default(void);\n\n/**********************\n *      MACROS\n **********************/\n\n#endif\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_THEME_TEMPL_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_themes/lv_themes.mk",
    "content": "CSRCS += lv_theme.c\nCSRCS += lv_theme_default.c\nCSRCS += lv_theme_argon.c\n\nDEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_themes\nVPATH += :$(LVGL_DIR)/lvgl/src/lv_themes\n\nCFLAGS += \"-I$(LVGL_DIR)/lvgl/src/lv_themes\"\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lv_version.h",
    "content": "/**\n * @file lv_version.h\n *\n */\n\n#ifndef LV_VERSION_H\n#define LV_VERSION_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n/*Current version of LittlevGL*/\n#define LVGL_VERSION_MAJOR   6\n#define LVGL_VERSION_MINOR   0\n#define LVGL_VERSION_PATCH   0\n#define LVGL_VERSION_INFO    \"\"\n\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n/** Gives 1 if the x.y.z version is supported in the current version\n * Usage:\n *\n * - Require v6\n * #if LV_VERSION_CHECK(6,0,0)\n *   new_func_in_v6();\n * #endif\n *\n *\n * - Require at least v5.3\n * #if LV_VERSION_CHECK(5,3,0)\n *   new_feature_from_v5_3();\n * #endif\n *\n *\n * - Require v5.3.2 bugfixes\n * #if LV_VERSION_CHECK(5,3,2)\n *   bugfix_in_v5_3_2();\n * #endif\n *\n * */\n#define LV_VERSION_CHECK(x,y,z) (x == LVGL_VERSION_MAJOR && (y < LVGL_VERSION_MINOR || (y == LVGL_VERSION_MINOR && z <= LVGL_VERSION_PATCH)))\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /*LV_VERSION_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lvgl.h",
    "content": "/**\n * @file lvgl.h\n * Include all LittleV GL related headers\n */\n\n#ifndef LVGL_H\n#define LVGL_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*********************\n *      INCLUDES\n *********************/\n\n#include \"lv_version.h\"\n\n#include \"lv_misc/lv_log.h\"\n#include \"lv_misc/lv_task.h\"\n#include \"lv_misc/lv_math.h\"\n#include \"lv_misc/lv_async.h\"\n\n#include \"lv_hal/lv_hal.h\"\n\n#include \"lv_core/lv_obj.h\"\n#include \"lv_core/lv_group.h\"\n\n#include \"lv_core/lv_refr.h\"\n#include \"lv_core/lv_disp.h\"\n\n#include \"lv_themes/lv_theme.h\"\n\n#include \"lv_font/lv_font.h\"\n#include \"lv_font/lv_font_fmt_txt.h\"\n\n#include \"lv_objx/lv_btn.h\"\n#include \"lv_objx/lv_imgbtn.h\"\n#include \"lv_objx/lv_img.h\"\n#include \"lv_objx/lv_label.h\"\n#include \"lv_objx/lv_line.h\"\n#include \"lv_objx/lv_page.h\"\n#include \"lv_objx/lv_cont.h\"\n#include \"lv_objx/lv_list.h\"\n#include \"lv_objx/lv_chart.h\"\n#include \"lv_objx/lv_table.h\"\n#include \"lv_objx/lv_cb.h\"\n#include \"lv_objx/lv_bar.h\"\n#include \"lv_objx/lv_slider.h\"\n#include \"lv_objx/lv_led.h\"\n#include \"lv_objx/lv_btnm.h\"\n#include \"lv_objx/lv_kb.h\"\n#include \"lv_objx/lv_ddlist.h\"\n#include \"lv_objx/lv_roller.h\"\n#include \"lv_objx/lv_ta.h\"\n#include \"lv_objx/lv_canvas.h\"\n#include \"lv_objx/lv_win.h\"\n#include \"lv_objx/lv_tabview.h\"\n#include \"lv_objx/lv_tileview.h\"\n#include \"lv_objx/lv_mbox.h\"\n#include \"lv_objx/lv_gauge.h\"\n#include \"lv_objx/lv_lmeter.h\"\n#include \"lv_objx/lv_sw.h\"\n#include \"lv_objx/lv_kb.h\"\n#include \"lv_objx/lv_arc.h\"\n#include \"lv_objx/lv_preload.h\"\n#include \"lv_objx/lv_calendar.h\"\n#include \"lv_objx/lv_spinbox.h\"\n\n#include \"lv_draw/lv_img_cache.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /*LVGL_H*/\n"
  },
  {
    "path": "argon-nx-gui/include/libs/lvgl/lvgl.mk",
    "content": "include $(LVGL_DIR)/lvgl/src/lv_core/lv_core.mk\ninclude $(LVGL_DIR)/lvgl/src/lv_hal/lv_hal.mk\ninclude $(LVGL_DIR)/lvgl/src/lv_objx/lv_objx.mk\ninclude $(LVGL_DIR)/lvgl/src/lv_font/lv_font.mk\ninclude $(LVGL_DIR)/lvgl/src/lv_misc/lv_misc.mk\ninclude $(LVGL_DIR)/lvgl/src/lv_themes/lv_themes.mk\ninclude $(LVGL_DIR)/lvgl/src/lv_draw/lv_draw.mk\n\n"
  },
  {
    "path": "argon-nx-gui/include/mem/emc.h",
    "content": "/*\n * arch/arm/mach-tegra/tegra21_emc.h\n *\n * Copyright (c) 2014-2015, NVIDIA CORPORATION.  All rights reserved.\n * Copyright (c) 2018 Atmosphère-NX\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\n *\n */\n \n#ifndef FUSEE_EMC_H_\n#define FUSEE_EMC_H_\n\n#define EMC_BASE 0x7001B000\n#define EMC0_BASE 0x7001E000\n#define EMC1_BASE 0x7001F000\n#define MAKE_EMC_REG(n) MAKE_REG32(EMC_BASE + n)\n#define MAKE_EMC0_REG(n) MAKE_REG32(EMC0_BASE + n)\n#define MAKE_EMC1_REG(n) MAKE_REG32(EMC1_BASE + n)\n\n#define EMC_INTSTATUS                       0x0\n#define EMC_INTSTATUS_MRR_DIVLD                 (0x1 << 5)\n#define EMC_INTSTATUS_CLKCHANGE_COMPLETE            (0x1 << 4)\n\n#define EMC_INTMASK                     0x4\n#define EMC_DBG                         0x8\n#define EMC_DBG_WRITE_MUX_ACTIVE                (1 << 1)\n#define EMC_DBG_CFG_SWAP_SHIFT                  26\n#define EMC_DBG_CFG_SWAP_MASK                   \\\n    (0x3 << EMC_DBG_CFG_SWAP_SHIFT)\n#define EMC_DBG_WRITE_ACTIVE_ONLY               (1 << 30)\n\n#define EMC_CONFIG_SAMPLE_DELAY                 0x5f0\n#define EMC_CFG_UPDATE                      0x5f4\n#define EMC_CFG_UPDATE_UPDATE_DLL_IN_UPDATE_SHIFT       9\n#define EMC_CFG_UPDATE_UPDATE_DLL_IN_UPDATE_MASK        \\\n    (0x3 << EMC_CFG_UPDATE_UPDATE_DLL_IN_UPDATE_SHIFT)\n#define EMC_CFG                         0xc\n#define EMC_CFG_DRAM_CLKSTOP_PD                 (1 << 31)\n#define EMC_CFG_DRAM_CLKSTOP_SR                 (1 << 30)\n#define EMC_CFG_DRAM_ACPD                   (1 << 29)\n#define EMC_CFG_DYN_SELF_REF                    (1 << 28)\n#define EMC_CFG_REQACT_ASYNC                    (1 << 26)\n#define EMC_CFG_AUTO_PRE_WR                 (1 << 25)\n#define EMC_CFG_AUTO_PRE_RD                 (1 << 24)\n#define EMC_CFG_MAM_PRE_WR                  (1 << 23)\n#define EMC_CFG_MAN_PRE_RD                  (1 << 22)\n#define EMC_CFG_PERIODIC_QRST                   (1 << 21)\n#define EMC_CFG_PERIODIC_QRST_SHIFT             (21)\n#define EMC_CFG_EN_DYNAMIC_PUTERM               (1 << 20)\n#define EMC_CFG_DLY_WR_DQ_HALF_CLOCK                (1 << 19)\n#define EMC_CFG_DSR_VTTGEN_DRV_EN               (1 << 18)\n#define EMC_CFG_EMC2MC_CLK_RATIO                (3 << 16)\n#define EMC_CFG_WAIT_FOR_ISP2B_READY_B4_CC          (1 << 9)\n#define EMC_CFG_WAIT_FOR_VI2_READY_B4_CC            (1 << 8)\n#define EMC_CFG_WAIT_FOR_ISP2_READY_B4_CC           (1 << 7)\n#define EMC_CFG_INVERT_DQM                  (1 << 6)\n#define EMC_CFG_WAIT_FOR_DISPLAYB_READY_B4_CC           (1 << 5)\n#define EMC_CFG_WAIT_FOR_DISPLAY_READY_B4_CC            (1 << 4)\n#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE2         (1 << 3)\n#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE1         (1 << 2)\n#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_ADDRPIPE          (1 << 1)\n\n#define EMC_ADR_CFG                     0x10\n#define EMC_REFCTRL                     0x20\n#define EMC_REFCTRL_DEV_SEL_SHIFT               0\n#define EMC_REFCTRL_DEV_SEL_MASK                \\\n    (0x3 << EMC_REFCTRL_DEV_SEL_SHIFT)\n#define EMC_REFCTRL_ENABLE                  (0x1 << 31)\n#define EMC_REFCTRL_ENABLE_ALL(num)             \\\n    (((((num) > 1) ? 0 : 2) << EMC_REFCTRL_DEV_SEL_SHIFT)   \\\n     | EMC_REFCTRL_ENABLE)\n#define EMC_REFCTRL_DISABLE_ALL(num)                \\\n    ((((num) > 1) ? 0 : 2) << EMC_REFCTRL_DEV_SEL_SHIFT)\n\n#define EMC_PIN                         0x24\n#define EMC_PIN_PIN_CKE_PER_DEV                 (1 << 2)\n#define EMC_PIN_PIN_CKEB                    (1 << 1)\n#define EMC_PIN_PIN_CKE                     (1 << 0)\n\n#define EMC_CLK_FORCE_CC_TRIGGER                (1 << 27)\n\n#define EMC_TIMING_CONTROL                  0x28\n#define EMC_RC                          0x2c\n#define EMC_RFC                         0x30\n#define EMC_RFCPB                       0x590\n#define EMC_RAS                         0x34\n#define EMC_RP                          0x38\n#define EMC_R2W                         0x3c\n#define EMC_W2R                         0x40\n#define EMC_R2P                         0x44\n#define EMC_W2P                         0x48\n#define EMC_CCDMW                       0x5c0\n#define EMC_RD_RCD                      0x4c\n#define EMC_WR_RCD                      0x50\n#define EMC_RRD                         0x54\n#define EMC_REXT                        0x58\n#define EMC_WDV                         0x5c\n#define EMC_QUSE                        0x60\n#define EMC_QRST                        0x64\n#define EMC_ISSUE_QRST                      0x428\n#define EMC_QSAFE                       0x68\n#define EMC_RDV                         0x6c\n#define EMC_REFRESH                     0x70\n#define EMC_BURST_REFRESH_NUM                   0x74\n#define EMC_PDEX2WR                     0x78\n#define EMC_PDEX2RD                     0x7c\n#define EMC_PDEX2CKE                        0x118\n#define EMC_PCHG2PDEN                       0x80\n#define EMC_ACT2PDEN                        0x84\n#define EMC_AR2PDEN                     0x88\n#define EMC_RW2PDEN                     0x8c\n#define EMC_CKE2PDEN                        0x11c\n#define EMC_TXSR                        0x90\n#define EMC_TCKE                        0x94\n#define EMC_TFAW                        0x98\n#define EMC_TRPAB                       0x9c\n#define EMC_TCLKSTABLE                      0xa0\n#define EMC_TCLKSTOP                        0xa4\n#define EMC_TREFBW                      0xa8\n#define EMC_TPPD                        0xac\n#define EMC_PDEX2MRR                        0xb4\n#define EMC_ODT_WRITE                       0xb0\n#define EMC_WEXT                        0xb8\n#define EMC_RFC_SLR                     0xc0\n#define EMC_MRS_WAIT_CNT2                   0xc4\n#define EMC_MRS_WAIT_CNT2_MRS_EXT2_WAIT_CNT_SHIFT       16\n#define EMC_MRS_WAIT_CNT2_MRS_EXT2_WAIT_CNT_MASK        \\\n    (0x7ff << EMC_MRS_WAIT_CNT2_MRS_EXT2_WAIT_CNT_SHIFT)\n#define EMC_MRS_WAIT_CNT2_MRS_EXT1_WAIT_CNT_SHIFT       0\n#define EMC_MRS_WAIT_CNT2_MRS_EXT1_WAIT_CNT_MASK        \\\n    (0x3ff << EMC_MRS_WAIT_CNT2_MRS_EXT1_WAIT_CNT_SHIFT)\n\n#define EMC_MRS_WAIT_CNT                    0xc8\n#define EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT           0\n#define EMC_MRS_WAIT_CNT_SHORT_WAIT_MASK            \\\n    (0x3FF << EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT)\n#define EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT            16\n#define EMC_MRS_WAIT_CNT_LONG_WAIT_MASK             \\\n    (0x3FF << EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT)\n\n#define EMC_MRS                         0xcc\n#define EMC_MODE_SET_DLL_RESET                  (1 << 8)\n#define EMC_MRS_USE_MRS_LONG_CNT                (1 << 26)\n\n#define EMC_EMRS                        0xd0\n#define EMC_EMRS_USE_EMRS_LONG_CNT              (1 << 26)\n\n#define EMC_REF                         0xd4\n#define EMC_REF_FORCE_CMD                   1\n\n#define EMC_PRE                         0xd8\n#define EMC_NOP                         0xdc\n#define EMC_SELF_REF                            0xe0\n#define EMC_SELF_REF_CMD_ENABLED                (1 << 0)\n#define EMC_SELF_REF_ACTIVE_SELF_REF                (1 << 8)\n#define EMC_SELF_REF_DEV_SEL_SHIFT              30\n#define EMC_SELF_REF_DEV_SEL_MASK               \\\n    (0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)\n\n#define EMC_DPD                         0xe4\n#define EMC_MRW                         0xe8\n#define EMC_MRW_MRW_OP_SHIFT                    0\n#define EMC_MRW_MRW_OP_MASK                 \\\n    (0xff << EMC_MRW_MRW_OP_SHIFT)\n#define EMC_MRW_MRW_MA_SHIFT                    16\n#define EMC_MRW_MRW_MA_MASK                 \\\n    (0xff << EMC_MRW_MRW_MA_SHIFT)\n#define EMC_MRW_USE_MRW_LONG_CNT                26\n#define EMC_MRW_USE_MRW_EXT_CNT                 27\n#define EMC_MRW_MRW_DEV_SELECTN_SHIFT               30\n#define EMC_MRW_MRW_DEV_SELECTN_MASK                \\\n    (0x3 << EMC_MRW_MRW_DEV_SELECTN_SHIFT)\n\n#define EMC_MRR                         0xec\n#define EMC_MRR_DEV_SEL_SHIFT                   30\n#define EMC_MRR_DEV_SEL_MASK                    \\\n    (0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)\n#define EMC_MRR_MA_SHIFT                    16\n#define EMC_MRR_MA_MASK                     \\\n    (0xff << EMC_MRR_MA_SHIFT)\n#define EMC_MRR_DATA_SHIFT                  0\n#define EMC_MRR_DATA_MASK                   \\\n    (0xffff << EMC_MRR_DATA_SHIFT)\n#define LPDDR2_MR4_TEMP_SHIFT                   0\n#define LPDDR2_MR4_TEMP_MASK                    \\\n    (0x7 << LPDDR2_MR4_TEMP_SHIFT)\n\n#define EMC_CMDQ                        0xf0\n#define EMC_MC2EMCQ                     0xf4\n#define EMC_FBIO_SPARE                      0x100\n#define EMC_FBIO_CFG5                       0x104\n#define EMC_FBIO_CFG5_DRAM_TYPE_SHIFT               0\n#define EMC_FBIO_CFG5_DRAM_TYPE_MASK                \\\n    (0x3 << EMC_FBIO_CFG5_DRAM_TYPE_SHIFT)\n#define EMC_FBIO_CFG5_CMD_TX_DIS                (1 << 8)\n#define EMC_FBIO_CFG5_CMD_BUS_RETURN_TO_ZERO            (1 << 27)\n\n#define EMC_CFG5_QUSE_MODE_SHIFT                13\n#define EMC_CFG5_QUSE_MODE_MASK                 \\\n    (0x7 << EMC_CFG5_QUSE_MODE_SHIFT)\n\n#define EMC_CFG_RSV                     0x120\n#define EMC_ACPD_CONTROL                    0x124\n#define EMC_MPC                         0x128\n#define EMC_EMRS2                       0x12c\n#define EMC_EMRS2_USE_EMRS2_LONG_CNT                (1 << 26)\n\n#define EMC_EMRS3                       0x130\n#define EMC_MRW2                        0x134\n#define EMC_MRW3                        0x138\n#define EMC_MRW4                        0x13c\n#define EMC_MRW5                        0x4a0\n#define EMC_MRW6                        0x4a4\n#define EMC_MRW7                        0x4a8\n#define EMC_MRW8                        0x4ac\n#define EMC_MRW9                        0x4b0\n#define EMC_MRW10                       0x4b4\n#define EMC_MRW11                       0x4b8\n#define EMC_MRW12                       0x4bc\n#define EMC_MRW13                       0x4c0\n#define EMC_MRW14                       0x4c4\n#define EMC_MRW15                       0x4d0\n#define EMC_CFG_SYNC                        0x4d4\n#define EMC_CLKEN_OVERRIDE                  0x140\n#define EMC_R2R                         0x144\n#define EMC_W2W                         0x148\n#define EMC_EINPUT                      0x14c\n#define EMC_EINPUT_DURATION                     0x150\n#define EMC_PUTERM_EXTRA                    0x154\n#define EMC_TCKESR                      0x158\n#define EMC_TPD                         0x15c\n#define EMC_STAT_CONTROL                    0x160\n#define EMC_STAT_STATUS                     0x164\n#define EMC_STAT_DRAM_CLOCK_LIMIT_LO                0x19c\n#define EMC_STAT_DRAM_CLOCK_LIMIT_HI                0x1a0\n#define EMC_STAT_DRAM_CLOCKS_LO                 0x1a4\n#define EMC_STAT_DRAM_CLOCKS_HI                 0x1a8\n#define EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_LO          0x1ac\n#define EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_HI          0x1b0\n#define EMC_STAT_DRAM_DEV0_READ_CNT_LO              0x1b4\n#define EMC_STAT_DRAM_DEV0_READ_CNT_HI              0x1b8\n#define EMC_STAT_DRAM_DEV0_READ8_CNT_LO             0x1bc\n#define EMC_STAT_DRAM_DEV0_READ8_CNT_HI             0x1c0\n#define EMC_STAT_DRAM_DEV0_WRITE_CNT_LO             0x1c4\n#define EMC_STAT_DRAM_DEV0_WRITE_CNT_HI             0x1c8\n#define EMC_STAT_DRAM_DEV0_WRITE8_CNT_LO            0x1cc\n#define EMC_STAT_DRAM_DEV0_WRITE8_CNT_HI            0x1d0\n#define EMC_STAT_DRAM_DEV0_REF_CNT_LO               0x1d4\n#define EMC_STAT_DRAM_DEV0_REF_CNT_HI               0x1d8\n#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO  0x1dc\n#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI  0x1e0\n#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO  0x1e4\n#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI  0x1e8\n#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO  0x1ec\n#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI  0x1f0\n#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO  0x1f4\n#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI  0x1f8\n#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO    0x1fc\n#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI    0x200\n#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO    0x204\n#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI    0x208\n#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO    0x20c\n#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI    0x210\n#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO    0x214\n#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI    0x218\n#define EMC_STAT_DRAM_DEV0_SR_CKE_EQ0_CLKS_LO               0x21c\n#define EMC_STAT_DRAM_DEV0_SR_CKE_EQ0_CLKS_HI               0x220\n#define EMC_STAT_DRAM_DEV0_DSR                      0x224\n#define EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_LO              0x228\n#define EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_HI              0x22c\n#define EMC_STAT_DRAM_DEV1_READ_CNT_LO                  0x230\n#define EMC_STAT_DRAM_DEV1_READ_CNT_HI                  0x234\n#define EMC_STAT_DRAM_DEV1_READ8_CNT_LO                 0x238\n#define EMC_STAT_DRAM_DEV1_READ8_CNT_HI                 0x23c\n#define EMC_STAT_DRAM_DEV1_WRITE_CNT_LO                 0x240\n#define EMC_STAT_DRAM_DEV1_WRITE_CNT_HI                 0x244\n#define EMC_STAT_DRAM_DEV1_WRITE8_CNT_LO                0x248\n#define EMC_STAT_DRAM_DEV1_WRITE8_CNT_HI                0x24c\n#define EMC_STAT_DRAM_DEV1_REF_CNT_LO                   0x250\n#define EMC_STAT_DRAM_DEV1_REF_CNT_HI                   0x254\n#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO  0x258\n#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI  0x25c\n#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO  0x260\n#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI  0x264\n#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO  0x268\n#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI  0x26c\n#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO  0x270\n#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI  0x274\n#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO    0x278\n#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI    0x27c\n#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO    0x280\n#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI    0x284\n#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO    0x288\n#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI    0x28c\n#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO    0x290\n#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI    0x294\n#define EMC_STAT_DRAM_DEV1_SR_CKE_EQ0_CLKS_LO               0x298\n#define EMC_STAT_DRAM_DEV1_SR_CKE_EQ0_CLKS_HI               0x29c\n#define EMC_STAT_DRAM_DEV1_DSR                      0x2a0\n#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO    0xc8c\n#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI    0xc90\n#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO    0xc94\n#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI    0xc98\n#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO    0xc9c\n#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI    0xca0\n#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO    0xca4\n#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI    0xca8\n#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO  0xcac\n#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI  0xcb0\n#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO  0xcb4\n#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI  0xcb8\n#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO  0xcbc\n#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI  0xcc0\n#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO  0xcc4\n#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI  0xcc8\n#define EMC_STAT_DRAM_IO_SR_CKE_EQ0_CLKS_LO         0xccc\n#define EMC_STAT_DRAM_IO_SR_CKE_EQ0_CLKS_HI         0xcd0\n#define EMC_STAT_DRAM_IO_DSR                    0xcd4\n#define EMC_AUTO_CAL_CONFIG                 0x2a4\n#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_COMPUTE_START      (1 << 0)\n#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_MEASURE_STALL      (1 << 9)\n#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_UPDATE_STALL       (1 << 10)\n#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_ENABLE         (1 << 29)\n#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_START          (1 << 31)\n\n#define EMC_AUTO_CAL_CONFIG2                    0x458\n#define EMC_AUTO_CAL_CONFIG3                    0x45c\n#define EMC_AUTO_CAL_CONFIG4                    0x5b0\n#define EMC_AUTO_CAL_CONFIG5                    0x5b4\n#define EMC_AUTO_CAL_CONFIG6                    0x5cc\n#define EMC_AUTO_CAL_CONFIG7                    0x574\n#define EMC_AUTO_CAL_CONFIG8                    0x2dc\n#define EMC_AUTO_CAL_VREF_SEL_0                 0x2f8\n#define EMC_AUTO_CAL_VREF_SEL_1                 0x300\n#define EMC_AUTO_CAL_INTERVAL                   0x2a8\n#define EMC_AUTO_CAL_STATUS                 0x2ac\n#define EMC_AUTO_CAL_STATUS2                    0x3d4\n#define EMC_AUTO_CAL_CHANNEL                    0x464\n#define EMC_PMACRO_RX_TERM                  0xc48\n#define EMC_PMACRO_DQ_TX_DRV                    0xc70\n#define EMC_PMACRO_CA_TX_DRV                    0xc74\n#define EMC_PMACRO_CMD_TX_DRV                   0xc4c\n#define EMC_PMACRO_AUTOCAL_CFG_0                0x700\n#define EMC_PMACRO_AUTOCAL_CFG_1                0x704\n#define EMC_PMACRO_AUTOCAL_CFG_2                0x708\n#define EMC_PMACRO_AUTOCAL_CFG_COMMON               0xc78\n#define EMC_PMACRO_AUTOCAL_CFG_COMMON_E_CAL_BYPASS_DVFS     (1 << 16)\n\n#define EMC_PMACRO_ZCTRL                    0xc44\n#define EMC_XM2COMPPADCTRL                  0x30c\n#define EMC_XM2COMPPADCTRL_VREF_CAL_ENABLE          (1 << 10)\n\n#define EMC_XM2COMPPADCTRL2                 0x578\n#define EMC_XM2COMPPADCTRL3                 0x2f4\n#define EMC_COMP_PAD_SW_CTRL                    0x57c\n#define EMC_REQ_CTRL                        0x2b0\n#define EMC_EMC_STATUS                      0x2b4\n#define EMC_EMC_STATUS_MRR_DIVLD                (1 << 20)\n#define EMC_EMC_STATUS_TIMING_UPDATE_STALLED            (1 << 23)\n#define EMC_EMC_STATUS_DRAM_IN_POWERDOWN_SHIFT          4\n#define EMC_EMC_STATUS_DRAM_IN_POWERDOWN_MASK           \\\n    (0x3 << EMC_EMC_STATUS_DRAM_IN_POWERDOWN_SHIFT)\n#define EMC_EMC_STATUS_DRAM_IN_SELF_REFRESH_SHIFT       8\n#define EMC_EMC_STATUS_DRAM_IN_SELF_REFRESH_MASK        \\\n    (0x3 << EMC_EMC_STATUS_DRAM_IN_SELF_REFRESH_SHIFT)\n\n#define EMC_CFG_2                       0x2b8\n#define EMC_CFG_DIG_DLL                     0x2bc\n#define EMC_CFG_DIG_DLL_CFG_DLL_EN              (1 << 0)\n#define EMC_CFG_DIG_DLL_CFG_DLL_STALL_ALL_UNTIL_LOCK        (1 << 1)\n#define EMC_CFG_DIG_DLL_CFG_DLL_STALL_ALL_TRAFFIC       (1 << 3)\n#define EMC_CFG_DIG_DLL_CFG_DLL_STALL_RW_UNTIL_LOCK     (1 << 4)\n#define EMC_CFG_DIG_DLL_CFG_DLL_MODE_SHIFT          6\n#define EMC_CFG_DIG_DLL_CFG_DLL_MODE_MASK           \\\n    (0x3 << EMC_CFG_DIG_DLL_CFG_DLL_MODE_SHIFT)\n#define EMC_CFG_DIG_DLL_CFG_DLL_LOCK_LIMIT_SHIFT        8\n#define EMC_CFG_DIG_DLL_CFG_DLL_LOCK_LIMIT_MASK         \\\n    (0x7 << EMC_CFG_DIG_DLL_CFG_DLL_LOCK_LIMIT_SHIFT)\n\n#define EMC_CFG_DIG_DLL_PERIOD                  0x2c0\n#define EMC_DIG_DLL_STATUS                  0x2c4\n#define EMC_DIG_DLL_STATUS_DLL_LOCK             (1 << 15)\n#define EMC_DIG_DLL_STATUS_DLL_PRIV_UPDATED         (1 << 17)\n#define EMC_DIG_DLL_STATUS_DLL_OUT_SHIFT            0\n#define EMC_DIG_DLL_STATUS_DLL_OUT_MASK             \\\n    (0x7ff << EMC_DIG_DLL_STATUS_DLL_OUT_SHIFT)\n\n#define EMC_CFG_DIG_DLL_1                   0x2c8\n#define EMC_RDV_MASK                        0x2cc\n#define EMC_WDV_MASK                        0x2d0\n#define EMC_RDV_EARLY_MASK                  0x2d4\n#define EMC_RDV_EARLY                       0x2d8\n#define EMC_WDV_CHK                     0x4e0\n#define EMC_ZCAL_INTERVAL                   0x2e0\n#define EMC_ZCAL_WAIT_CNT                   0x2e4\n#define EMC_ZCAL_WAIT_CNT_ZCAL_WAIT_CNT_MASK            0x7ff\n#define EMC_ZCAL_WAIT_CNT_ZCAL_WAIT_CNT_SHIFT           0\n\n#define EMC_ZCAL_MRW_CMD                    0x2e8\n#define EMC_ZQ_CAL                      0x2ec\n#define EMC_ZQ_CAL_DEV_SEL_SHIFT                30\n#define EMC_ZQ_CAL_DEV_SEL_MASK                 \\\n    (0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)\n#define EMC_ZQ_CAL_LONG                     (1 << 4)\n#define EMC_ZQ_CAL_ZQ_LATCH_CMD                 (1 << 1)\n#define EMC_ZQ_CAL_ZQ_CAL_CMD                   (1 << 0)\n#define EMC_ZQ_CAL_LONG_CMD_DEV0                \\\n    (DRAM_DEV_SEL_0 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD)\n#define EMC_ZQ_CAL_LONG_CMD_DEV1                \\\n    (DRAM_DEV_SEL_1 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD)\n\n#define EMC_SCRATCH0                        0x324\n#define EMC_STALL_THEN_EXE_BEFORE_CLKCHANGE         0x3c8\n#define EMC_STALL_THEN_EXE_AFTER_CLKCHANGE          0x3cc\n#define EMC_UNSTALL_RW_AFTER_CLKCHANGE              0x3d0\n#define EMC_FDPD_CTRL_CMD_NO_RAMP               0x4d8\n#define EMC_FDPD_CTRL_CMD_NO_RAMP_CMD_DPD_NO_RAMP_ENABLE    (1 << 0)\n\n#define EMC_SEL_DPD_CTRL                    0x3d8\n#define EMC_SEL_DPD_CTRL_DATA_SEL_DPD_EN            (1 << 8)\n#define EMC_SEL_DPD_CTRL_ODT_SEL_DPD_EN             (1 << 5)\n#define EMC_SEL_DPD_CTRL_RESET_SEL_DPD_EN           (1 << 4)\n#define EMC_SEL_DPD_CTRL_CA_SEL_DPD_EN              (1 << 3)\n#define EMC_SEL_DPD_CTRL_CLK_SEL_DPD_EN             (1 << 2)\n#define EMC_SEL_DPD_CTRL_DDR3_MASK              \\\n    ((0xf << 2) | (0x1 << 8))\n#define EMC_SEL_DPD_CTRL_MAS                    \\\n    ((0x3 << 2) | (0x1 << 5) | (0x1 << 8))\n\n#define EMC_FDPD_CTRL_DQ                    0x310\n#define EMC_FDPD_CTRL_CMD                   0x314\n#define EMC_PRE_REFRESH_REQ_CNT                 0x3dc\n#define EMC_REFCTRL2                        0x580\n#define EMC_FBIO_CFG7                       0x584\n#define EMC_FBIO_CFG7_CH0_ENABLE                (1 << 1)\n#define EMC_FBIO_CFG7_CH1_ENABLE                (1 << 2)\n\n#define EMC_DATA_BRLSHFT_0                  0x588\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_SHIFT   21\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_SHIFT   18\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_SHIFT   15\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_SHIFT   12\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_SHIFT   9\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_SHIFT   6\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_SHIFT   3\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_SHIFT   0\n#define EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_SHIFT)\n\n#define EMC_DATA_BRLSHFT_1                  0x58c\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_SHIFT   21\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_SHIFT   18\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_SHIFT   15\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_SHIFT   12\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_SHIFT   9\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_SHIFT   6\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_SHIFT   3\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_SHIFT)\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_SHIFT   0\n#define EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_MASK    \\\n    (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_SHIFT)\n\n#define EMC_DQS_BRLSHFT_0                   0x594\n#define EMC_DQS_BRLSHFT_1                   0x598\n#define EMC_CMD_BRLSHFT_0                   0x59c\n#define EMC_CMD_BRLSHFT_1                   0x5a0\n#define EMC_CMD_BRLSHFT_2                   0x5a4\n#define EMC_CMD_BRLSHFT_3                   0x5a8\n#define EMC_QUSE_BRLSHFT_0                  0x5ac\n#define EMC_QUSE_BRLSHFT_1                  0x5b8\n#define EMC_QUSE_BRLSHFT_2                  0x5bc\n#define EMC_QUSE_BRLSHFT_3                  0x5c4\n#define EMC_FBIO_CFG8                       0x5c8\n#define EMC_CMD_MAPPING_CMD0_0                  0x380\n#define EMC_CMD_MAPPING_CMD0_1                  0x384\n#define EMC_CMD_MAPPING_CMD0_2                  0x388\n#define EMC_CMD_MAPPING_CMD1_0                  0x38c\n#define EMC_CMD_MAPPING_CMD1_1                  0x390\n#define EMC_CMD_MAPPING_CMD1_2                  0x394\n#define EMC_CMD_MAPPING_CMD2_0                  0x398\n#define EMC_CMD_MAPPING_CMD2_1                  0x39c\n#define EMC_CMD_MAPPING_CMD2_2                  0x3a0\n#define EMC_CMD_MAPPING_CMD3_0                  0x3a4\n#define EMC_CMD_MAPPING_CMD3_1                  0x3a8\n#define EMC_CMD_MAPPING_CMD3_2                  0x3ac\n#define EMC_CMD_MAPPING_BYTE                    0x3b0\n#define EMC_DYN_SELF_REF_CONTROL                0x3e0\n#define EMC_TXSRDLL                     0x3e4\n#define EMC_CCFIFO_ADDR                     0x3e8\n#define EMC_CCFIFO_DATA                     0x3ec\n#define EMC_CCFIFO_STATUS                   0x3f0\n#define EMC_SWIZZLE_RANK0_BYTE0                 0x404\n#define EMC_SWIZZLE_RANK0_BYTE1                 0x408\n#define EMC_SWIZZLE_RANK0_BYTE2                 0x40c\n#define EMC_SWIZZLE_RANK0_BYTE3                 0x410\n#define EMC_SWIZZLE_RANK1_BYTE0                 0x418\n#define EMC_SWIZZLE_RANK1_BYTE1                 0x41c\n#define EMC_SWIZZLE_RANK1_BYTE2                 0x420\n#define EMC_SWIZZLE_RANK1_BYTE3                 0x424\n#define EMC_TR_TIMING_0                     0x3b4\n#define EMC_TR_CTRL_0                       0x3b8\n#define EMC_TR_CTRL_1                       0x3bc\n#define EMC_TR_DVFS                     0x460\n#define EMC_TR_DVFS_TRAINING_DVFS               (1 << 0)\n\n#define EMC_SWITCH_BACK_CTRL                    0x3c0\n#define EMC_TR_RDV                      0x3c4\n#define EMC_TR_QPOP                     0x3f4\n#define EMC_TR_RDV_MASK                     0x3f8\n#define EMC_TR_QSAFE                        0x3fc\n#define EMC_TR_QRST                     0x400\n#define EMC_IBDLY                       0x468\n#define EMC_OBDLY                       0x46c\n#define EMC_TXDSRVTTGEN                     0x480\n#define EMC_WE_DURATION                     0x48c\n#define EMC_WS_DURATION                     0x490\n#define EMC_WEV                         0x494\n#define EMC_WSV                         0x498\n#define EMC_CFG_3                       0x49c\n#define EMC_CFG_PIPE_2                      0x554\n#define EMC_CFG_PIPE_CLK                    0x558\n#define EMC_CFG_PIPE_CLK_CLK_ALWAYS_ON              (1 << 0)\n\n#define EMC_CFG_PIPE_1                      0x55c\n#define EMC_CFG_PIPE                        0x560\n#define EMC_QPOP                        0x564\n#define EMC_QUSE_WIDTH                      0x568\n#define EMC_PUTERM_WIDTH                    0x56c\n#define EMC_PROTOBIST_CONFIG_ADR_1              0x5d0\n#define EMC_PROTOBIST_CONFIG_ADR_2              0x5d4\n#define EMC_PROTOBIST_MISC                  0x5d8\n#define EMC_PROTOBIST_WDATA_LOWER               0x5dc\n#define EMC_PROTOBIST_WDATA_UPPER               0x5e0\n#define EMC_PROTOBIST_RDATA                 0x5ec\n#define EMC_DLL_CFG_0                       0x5e4\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_IGNORE_START         (1 << 29)\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_DUAL_PASS_LOCK       (1 << 28)\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_STEP_SIZE_SHIFT      24\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_STEP_SIZE_MASK       \\\n    (0xf << EMC_DLL_CFG_0_DDLLCAL_CTRL_STEP_SIZE_SHIFT)\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_END_COUNT_SHIFT      20\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_END_COUNT_MASK       \\\n    (0xf << EMC_DLL_CFG_0_DDLLCAL_CTRL_END_COUNT_SHIFT)\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_FILTER_BITS_SHIFT        16\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_FILTER_BITS_MASK     \\\n    (0xf << EMC_DLL_CFG_0_DDLLCAL_CTRL_FILTER_BITS_SHIFT)\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_COUNT_SHIFT       12\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_COUNT_MASK        \\\n    (0xf << EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_COUNT_SHIFT)\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_DELAY_SHIFT       4\n#define EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_DELAY_MASK        \\\n    (0xff << EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_DELAY_SHIFT)\n#define EMC_DLL_CFG_0_DDLLCAL_UPDATE_CNT_LIMIT_SHIFT        0\n#define EMC_DLL_CFG_0_DDLLCAL_UPDATE_CNT_LIMIT_MASK     \\\n    (0xf << EMC_DLL_CFG_0_DDLLCAL_UPDATE_CNT_LIMIT_SHIFT)\n\n#define EMC_DLL_CFG_1                       0x5e8\n#define EMC_DLL_CFG_1_DDLLCAL_CTRL_START_TRIM_SHIFT     10\n#define EMC_DLL_CFG_1_DDLLCAL_CTRL_START_TRIM_MASK      \\\n    (0x7ff << EMC_DLL_CFG_1_DDLLCAL_CTRL_START_TRIM_SHIFT)\n\n#define EMC_TRAINING_CMD                    0xe00\n#define EMC_TRAINING_CMD_PRIME                  (1 << 0)\n#define EMC_TRAINING_CMD_CA                 (1 << 1)\n#define EMC_TRAINING_CMD_RD                 (1 << 2)\n#define EMC_TRAINING_CMD_WR                 (1 << 3)\n#define EMC_TRAINING_CMD_QUSE                   (1 << 4)\n#define EMC_TRAINING_CMD_CA_VREF                (1 << 5)\n#define EMC_TRAINING_CMD_RD_VREF                (1 << 6)\n#define EMC_TRAINING_CMD_WR_VREF                (1 << 7)\n#define EMC_TRAINING_CMD_QUSE_VREF              (1 << 8)\n#define EMC_TRAINING_CMD_GO                 (1 << 31)\n\n#define EMC_TRAINING_CTRL                   0xe04\n#define EMC_TRAINING_CTRL_SWAP_RANK             (1 << 14)\n\n#define EMC_TRAINING_STATUS                 0xe08\n#define EMC_TRAINING_QUSE_CORS_CTRL             0xe0c\n#define EMC_TRAINING_QUSE_FINE_CTRL             0xe10\n#define EMC_TRAINING_QUSE_CTRL_MISC             0xe14\n#define EMC_TRAINING_WRITE_FINE_CTRL                0xe18\n#define EMC_TRAINING_WRITE_CTRL_MISC                0xe1c\n#define EMC_TRAINING_WRITE_VREF_CTRL                0xe20\n#define EMC_TRAINING_READ_FINE_CTRL             0xe24\n#define EMC_TRAINING_READ_CTRL_MISC             0xe28\n#define EMC_TRAINING_READ_VREF_CTRL             0xe2c\n#define EMC_TRAINING_CA_FINE_CTRL               0xe30\n#define EMC_TRAINING_CA_CTRL_MISC               0xe34\n#define EMC_TRAINING_CA_CTRL_MISC1              0xe38\n#define EMC_TRAINING_CA_VREF_CTRL               0xe3c\n#define EMC_TRAINING_CA_TADR_CTRL               0xe40\n#define EMC_TRAINING_SETTLE                 0xe44\n#define EMC_TRAINING_DEBUG_CTRL                 0xe48\n#define EMC_TRAINING_DEBUG_DQ0                  0xe4c\n#define EMC_TRAINING_DEBUG_DQ1                  0xe50\n#define EMC_TRAINING_DEBUG_DQ2                  0xe54\n#define EMC_TRAINING_DEBUG_DQ3                  0xe58\n#define EMC_TRAINING_MPC                    0xe5c\n#define EMC_TRAINING_PATRAM_CTRL                0xe60\n#define EMC_TRAINING_PATRAM_DQ                  0xe64\n#define EMC_TRAINING_PATRAM_DMI                 0xe68\n#define EMC_TRAINING_VREF_SETTLE                0xe6c\n#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE0         0xe70\n#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE1         0xe74\n#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE2         0xe78\n#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE3         0xe7c\n#define EMC_TRAINING_RW_EYE_CENTER_IB_MISC          0xe80\n#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE0         0xe84\n#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE1         0xe88\n#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE2         0xe8c\n#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE3         0xe90\n#define EMC_TRAINING_RW_EYE_CENTER_OB_MISC          0xe94\n#define EMC_TRAINING_RW_OFFSET_IB_BYTE0             0xe98\n#define EMC_TRAINING_RW_OFFSET_IB_BYTE1             0xe9c\n#define EMC_TRAINING_RW_OFFSET_IB_BYTE2             0xea0\n#define EMC_TRAINING_RW_OFFSET_IB_BYTE3             0xea4\n#define EMC_TRAINING_RW_OFFSET_IB_MISC              0xea8\n#define EMC_TRAINING_RW_OFFSET_OB_BYTE0             0xeac\n#define EMC_TRAINING_RW_OFFSET_OB_BYTE1             0xeb0\n#define EMC_TRAINING_RW_OFFSET_OB_BYTE2             0xeb4\n#define EMC_TRAINING_RW_OFFSET_OB_BYTE3             0xeb8\n#define EMC_TRAINING_RW_OFFSET_OB_MISC              0xebc\n#define EMC_TRAINING_OPT_CA_VREF                0xec0\n#define EMC_TRAINING_OPT_DQ_OB_VREF             0xec4\n#define EMC_TRAINING_OPT_DQ_IB_VREF_RANK0           0xec8\n#define EMC_TRAINING_OPT_DQ_IB_VREF_RANK1           0xecc\n#define EMC_TRAINING_QUSE_VREF_CTRL             0xed0\n#define EMC_TRAINING_OPT_DQS_IB_VREF_RANK0          0xed4\n#define EMC_TRAINING_OPT_DQS_IB_VREF_RANK1          0xed8\n#define EMC_TRAINING_DRAMC_TIMING               0xedc\n#define EMC_PMACRO_QUSE_DDLL_RANK0_0                0x600\n#define EMC_PMACRO_QUSE_DDLL_RANK0_1                0x604\n#define EMC_PMACRO_QUSE_DDLL_RANK0_2                0x608\n#define EMC_PMACRO_QUSE_DDLL_RANK0_3                0x60c\n#define EMC_PMACRO_QUSE_DDLL_RANK0_4                0x610\n#define EMC_PMACRO_QUSE_DDLL_RANK0_5                0x614\n#define EMC_PMACRO_QUSE_DDLL_RANK1_0                0x620\n#define EMC_PMACRO_QUSE_DDLL_RANK1_1                0x624\n#define EMC_PMACRO_QUSE_DDLL_RANK1_2                0x628\n#define EMC_PMACRO_QUSE_DDLL_RANK1_3                0x62c\n#define EMC_PMACRO_QUSE_DDLL_RANK1_4                0x630\n#define EMC_PMACRO_QUSE_DDLL_RANK1_5                0x634\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0          0x640\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE1_SHIFT \\\n    16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE1_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE1_SHIFT\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE0_SHIFT \\\n    0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE0_MASK \\\n    0x3ff <<                                \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE0_SHIFT\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1          0x644\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE3_SHIFT \\\n    16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE3_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE3_SHIFT\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE2_SHIFT \\\n    0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE2_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE2_SHIFT\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2          0x648\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE5_SHIFT  \\\n    16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE5_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE5_SHIFT\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE4_SHIFT \\\n    0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE4_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE4_SHIFT\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3          0x64c\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE7_SHIFT \\\n    16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE7_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE7_SHIFT\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE6_SHIFT \\\n    0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE6_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE6_SHIFT\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4          0x650\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5          0x654\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0          0x660\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE1_SHIFT \\\n    16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE1_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE1_SHIFT\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE0_SHIFT \\\n    0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE0_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE0_SHIFT\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1          0x664\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE3_SHIFT \\\n    16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE3_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE3_SHIFT\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE2_SHIFT \\\n    0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE2_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE2_SHIFT\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2          0x668\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE5_SHIFT \\\n    16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE5_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE5_SHIFT\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE4_SHIFT \\\n    0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE4_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE4_SHIFT\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3          0x66c\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE7_SHIFT \\\n    16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE7_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE7_SHIFT\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE6_SHIFT \\\n    0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE6_MASK  \\\n    0x3ff <<                                 \\\n    EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE6_SHIFT\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4          0x670\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5          0x674\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0         0x680\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1         0x684\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2         0x688\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3         0x68c\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4         0x690\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5         0x694\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0         0x6a0\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1         0x6a4\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2         0x6a8\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3         0x6ac\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4         0x6b0\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5         0x6b4\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0         0x6c0\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1         0x6c4\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2         0x6c8\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3         0x6cc\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_4         0x6d0\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_5         0x6d4\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0         0x6e0\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1         0x6e4\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2         0x6e8\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3         0x6ec\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_4         0x6f0\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_5         0x6f4\n#define EMC_PMACRO_TX_PWRD_0                    0x720\n#define EMC_PMACRO_TX_PWRD_1                    0x724\n#define EMC_PMACRO_TX_PWRD_2                    0x728\n#define EMC_PMACRO_TX_PWRD_3                    0x72c\n#define EMC_PMACRO_TX_PWRD_4                    0x730\n#define EMC_PMACRO_TX_PWRD_5                    0x734\n#define EMC_PMACRO_TX_SEL_CLK_SRC_0             0x740\n#define EMC_PMACRO_TX_SEL_CLK_SRC_1             0x744\n#define EMC_PMACRO_TX_SEL_CLK_SRC_3             0x74c\n#define EMC_PMACRO_TX_SEL_CLK_SRC_2             0x748\n#define EMC_PMACRO_TX_SEL_CLK_SRC_4             0x750\n#define EMC_PMACRO_TX_SEL_CLK_SRC_5             0x754\n#define EMC_PMACRO_DDLL_BYPASS                  0x760\n#define EMC_PMACRO_DDLL_PWRD_0                  0x770\n#define EMC_PMACRO_DDLL_PWRD_1                  0x774\n#define EMC_PMACRO_DDLL_PWRD_2                  0x778\n#define EMC_PMACRO_CMD_CTRL_0                   0x780\n#define EMC_PMACRO_CMD_CTRL_1                   0x784\n#define EMC_PMACRO_CMD_CTRL_2                   0x788\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_0       0x800\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_1       0x804\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_2       0x808\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_3       0x80c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_0       0x810\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_1       0x814\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_2       0x818\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_3       0x81c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_0       0x820\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_1       0x824\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_2       0x828\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_3       0x82c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_0       0x830\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_1       0x834\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_2       0x838\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_3       0x83c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_0       0x840\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_1       0x844\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_2       0x848\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_3       0x84c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_0       0x850\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_1       0x854\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_2       0x858\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_3       0x85c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_0       0x860\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_1       0x864\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_2       0x868\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_3       0x86c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_0       0x870\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_1       0x874\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_2       0x878\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_3       0x87c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_0        0x880\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_1        0x884\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_2        0x888\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_3        0x88c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_0        0x890\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_1        0x894\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_2        0x898\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_3        0x89c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_0        0x8a0\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_1        0x8a4\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_2        0x8a8\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_3        0x8ac\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_0        0x8b0\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_1        0x8b4\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_2        0x8b8\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_3        0x8bc\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_0       0x900\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_1       0x904\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_2       0x908\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_3       0x90c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_0       0x910\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_1       0x914\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_2       0x918\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_3       0x91c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_0       0x920\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_1       0x924\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_2       0x928\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_3       0x92c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_0       0x930\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_1       0x934\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_2       0x938\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_3       0x93c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_0       0x940\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_1       0x944\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_2       0x948\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_3       0x94c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_0       0x950\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_1       0x954\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_2       0x958\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_3       0x95c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_0       0x960\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_1       0x964\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_2       0x968\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_3       0x96c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_0       0x970\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_1       0x974\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_2       0x978\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_3       0x97c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_0        0x980\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_1        0x984\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_2        0x988\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_3        0x98c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_0        0x990\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_1        0x994\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_2        0x998\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_3        0x99c\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_0        0x9a0\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_1        0x9a4\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_2        0x9a8\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_3        0x9ac\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_0        0x9b0\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_1        0x9b4\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_2        0x9b8\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_3        0x9bc\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_0       0xa00\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_1       0xa04\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_2       0xa08\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_0       0xa10\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_1       0xa14\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_2       0xa18\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_0       0xa20\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_1       0xa24\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_2       0xa28\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_0       0xa30\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_1       0xa34\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_2       0xa38\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_0       0xa40\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_1       0xa44\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_2       0xa48\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_0       0xa50\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_1       0xa54\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_2       0xa58\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_0       0xa60\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_1       0xa64\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_2       0xa68\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_0       0xa70\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_1       0xa74\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_2       0xa78\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_0        0xa80\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_1        0xa84\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_2        0xa88\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_0        0xa90\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_1        0xa94\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_2        0xa98\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_0        0xaa0\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_1        0xaa4\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_2        0xaa8\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_0        0xab0\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_1        0xab4\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_2        0xab8\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_0       0xb00\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_1       0xb04\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_2       0xb08\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_0       0xb10\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_1       0xb14\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_2       0xb18\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_0       0xb20\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_1       0xb24\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_2       0xb28\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_0       0xb30\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_1       0xb34\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_2       0xb38\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_0       0xb40\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_1       0xb44\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_2       0xb48\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_0       0xb50\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_1       0xb54\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_2       0xb58\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_0       0xb60\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_1       0xb64\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_2       0xb68\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_0       0xb70\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_1       0xb74\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_2       0xb78\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_0        0xb80\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_1        0xb84\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_2        0xb88\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_0        0xb90\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_1        0xb94\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_2        0xb98\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_0        0xba0\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_1        0xba4\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_2        0xba8\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_0        0xbb0\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_1        0xbb4\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_2        0xbb8\n#define EMC_PMACRO_IB_VREF_DQ_0                 0xbe0\n#define EMC_PMACRO_IB_VREF_DQ_1                 0xbe4\n#define EMC_PMACRO_IB_VREF_DQ_2                 0xbe8\n#define EMC_PMACRO_IB_VREF_DQS_0                0xbf0\n#define EMC_PMACRO_IB_VREF_DQS_1                0xbf4\n#define EMC_PMACRO_IB_VREF_DQS_2                0xbf8\n#define EMC_PMACRO_IB_RXRT                  0xcf4\n#define EMC_PMACRO_DDLL_LONG_CMD_0              0xc00\n#define EMC_PMACRO_DDLL_LONG_CMD_1              0xc04\n#define EMC_PMACRO_DDLL_LONG_CMD_2              0xc08\n#define EMC_PMACRO_DDLL_LONG_CMD_3              0xc0c\n#define EMC_PMACRO_DDLL_LONG_CMD_4              0xc10\n#define EMC_PMACRO_DDLL_LONG_CMD_5              0xc14\n#define EMC_PMACRO_DDLL_SHORT_CMD_0             0xc20\n#define EMC_PMACRO_DDLL_SHORT_CMD_1             0xc24\n#define EMC_PMACRO_DDLL_SHORT_CMD_2             0xc28\n#define EMC_PMACRO_CFG_PM_GLOBAL_0              0xc30\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE0        (1 << 16)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE1        (1 << 17)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE2        (1 << 18)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE3        (1 << 19)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE4        (1 << 20)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE5        (1 << 21)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE6        (1 << 22)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE7        (1 << 23)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD0     (1 << 24)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD1     (1 << 25)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD2     (1 << 26)\n#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD3     (1 << 27)\n\n#define EMC_PMACRO_VTTGEN_CTRL_0                0xc34\n#define EMC_PMACRO_VTTGEN_CTRL_1                0xc38\n#define EMC_PMACRO_VTTGEN_CTRL_2                0xcf0\n#define EMC_PMACRO_BG_BIAS_CTRL_0               0xc3c\n#define EMC_PMACRO_BG_BIAS_CTRL_0_BG_E_PWRD         (1 << 0)\n#define EMC_PMACRO_BG_BIAS_CTRL_0_BG_MODE           (1 << 1)\n#define EMC_PMACRO_BG_BIAS_CTRL_0_BGLP_E_PWRD           (1 << 2)\n\n#define EMC_PMACRO_PAD_CFG_CTRL                 0xc40\n#define EMC_PMACRO_CMD_PAD_RX_CTRL              0xc50\n#define EMC_PMACRO_DATA_PAD_RX_CTRL             0xc54\n#define EMC_PMACRO_CMD_RX_TERM_MODE             0xc58\n#define EMC_PMACRO_DATA_RX_TERM_MODE                0xc5c\n#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSN_RX_TERM_MODE_SHIFT 8\n#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSN_RX_TERM_MODE_MASK (0x3 << \\\n    EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSN_RX_TERM_MODE_SHIFT)\n#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSP_RX_TERM_MODE_SHIFT 4\n#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSP_RX_TERM_MODE_MASK (0x3 << \\\n    EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSP_RX_TERM_MODE_SHIFT)\n#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQ_RX_TERM_MODE_SHIFT   0\n#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQ_RX_TERM_MODE_MASK   (0x3 << \\\n    EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQ_RX_TERM_MODE_SHIFT)\n\n#define RX_TERM_MODE                            \\\n    ~(EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSN_RX_TERM_MODE_MASK |    \\\n      EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSP_RX_TERM_MODE_MASK |    \\\n      EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQ_RX_TERM_MODE_MASK)\n\n#define EMC_PMACRO_CMD_PAD_TX_CTRL              0xc60\n#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_DQ_TX_E_DCC      (1 << 1)\n#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_DQSP_TX_E_DCC        (1 << 9)\n#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_DQSN_TX_E_DCC        (1 << 16)\n#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_CMD_TX_E_DCC     (1 << 24)\n#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_DQ_TX_DRVFORCEON     (1 << 26)\n\n#define EMC_PMACRO_DATA_PAD_TX_CTRL             0xc64\n#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQ_E_IVREF     (1 << 0)\n#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQ_TX_E_DCC        (1 << 1)\n#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQS_E_IVREF        (1 << 8)\n#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQSP_TX_E_DCC      (1 << 9)\n#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQSN_TX_E_DCC      (1 << 16)\n#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_CMD_TX_E_DCC       (1 << 24)\n\n#define EMC_PMACRO_COMMON_PAD_TX_CTRL               0xc68\n#define EMC_PMACRO_BRICK_MAPPING_0              0xc80\n#define EMC_PMACRO_BRICK_MAPPING_1              0xc84\n#define EMC_PMACRO_BRICK_MAPPING_2              0xc88\n#define EMC_PMACRO_DDLLCAL_CAL                  0xce0\n#define EMC_PMACRO_DDLL_OFFSET                  0xce4\n#define EMC_PMACRO_DDLL_PERIODIC_OFFSET             0xce8\n#define EMC_PMACRO_BRICK_CTRL_RFU1              0x330\n#define EMC_PMACRO_BRICK_CTRL_RFU2              0x334\n#define EMC_PMACRO_CMD_BRICK_CTRL_FDPD              0x318\n#define EMC_PMACRO_DATA_BRICK_CTRL_FDPD             0x31c\n#define EMC_PMACRO_TRAINING_CTRL_0              0xcf8\n#define EMC_PMACRO_TRAINING_CTRL_0_CH0_TRAINING_E_WRPTR     (1 << 3)\n\n#define EMC_PMACRO_TRAINING_CTRL_1              0xcfc\n#define EMC_PMACRO_TRAINING_CTRL_1_CH1_TRAINING_E_WRPTR     (1 << 3)\n\n#define EMC_PMC_SCRATCH1                    0x440\n#define EMC_PMC_SCRATCH2                    0x444\n#define EMC_PMC_SCRATCH3                    0x448\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/mem/heap.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 Guillem96\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _HEAP_H_\n#define _HEAP_H_\n\n#include \"utils/types.h\"\n\ntypedef struct _hnode\n{\n\tint used;\n\tu32 size;\n\tstruct _hnode *prev;\n\tstruct _hnode *next;\n} hnode_t;\n\ntypedef struct _heap\n{\n\tu32 start;\n\thnode_t *first;\n} heap_t;\n\nvoid heap_init(u32 base);\nvoid *malloc(u32 size);\nvoid *calloc(u32 num, u32 size);\nvoid free(void *buf);\nvoid *memalign(u32 align, u32 size);\nvoid *m_realloc(void* ptr, u32 current_size, u32 new_size);\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/mem/mc.h",
    "content": "#ifndef _MC_H_\n#define _MC_H_\n\n#include \"utils/types.h\"\n#include \"mem/mc_t210.h\"\n\n#define MAKE_MC_REG(n) MAKE_REG32(MC_BASE + n)\n\nvoid mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock);\nvoid mc_config_carveout();\nvoid mc_config_carveout_finalize();\nvoid mc_enable_ahb_redirect();\nvoid mc_disable_ahb_redirect();\nvoid mc_enable();\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/mem/mc_t210.h",
    "content": "/*\n * Copyright (c) 2014, NVIDIA Corporation. All rights reserved.\n *\n * This software is licensed under the terms of the GNU General Public\n * License version 2, as published by the Free Software Foundation, and\n * may be copied, distributed, and modified under those terms.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n */\n\n#ifndef _MC_T210_H_\n#define _MC_T210_H_\n\n#define MC_INTSTATUS                                            0x0\n#define MC_INTMASK                                              0x4\n#define MC_ERR_STATUS                                           0x8\n#define MC_ERR_ADR                                              0xc\n#define MC_PCFIFO_CLIENT_CONFIG0                                0xdd0\n#define MC_PCFIFO_CLIENT_CONFIG1                                0xdd4\n#define MC_PCFIFO_CLIENT_CONFIG2                                0xdd8\n#define MC_PCFIFO_CLIENT_CONFIG3                                0xddc\n#define MC_PCFIFO_CLIENT_CONFIG4                                0xde0\n#define MC_EMEM_CFG                                             0x50\n#define MC_EMEM_ADR_CFG                                         0x54\n#define MC_EMEM_ADR_CFG_DEV0                                    0x58\n#define MC_EMEM_ADR_CFG_DEV1                                    0x5c\n#define MC_EMEM_ADR_CFG_CHANNEL_MASK                            0x60\n#define MC_EMEM_ADR_CFG_BANK_MASK_0                             0x64\n#define MC_EMEM_ADR_CFG_BANK_MASK_1                             0x68\n#define MC_EMEM_ADR_CFG_BANK_MASK_2                             0x6c\n#define MC_SECURITY_CFG0                                        0x70\n#define MC_SECURITY_CFG1                                        0x74\n#define MC_SECURITY_CFG3                                        0x9bc\n#define MC_SECURITY_RSV                                         0x7c\n#define MC_EMEM_ARB_CFG                                         0x90\n#define MC_EMEM_ARB_OUTSTANDING_REQ                             0x94\n#define MC_EMEM_ARB_TIMING_RCD                                  0x98\n#define MC_EMEM_ARB_TIMING_RP                                   0x9c\n#define MC_EMEM_ARB_TIMING_RC                                   0xa0\n#define MC_EMEM_ARB_TIMING_RAS                                  0xa4\n#define MC_EMEM_ARB_TIMING_FAW                                  0xa8\n#define MC_EMEM_ARB_TIMING_RRD                                  0xac\n#define MC_EMEM_ARB_TIMING_RAP2PRE                              0xb0\n#define MC_EMEM_ARB_TIMING_WAP2PRE                              0xb4\n#define MC_EMEM_ARB_TIMING_R2R                                  0xb8\n#define MC_EMEM_ARB_TIMING_W2W                                  0xbc\n#define MC_EMEM_ARB_TIMING_R2W                                  0xc0\n#define MC_EMEM_ARB_TIMING_W2R                                  0xc4\n#define MC_EMEM_ARB_TIMING_RFCPB                                0x6c0\n#define MC_EMEM_ARB_TIMING_CCDMW                                0x6c4\n#define MC_EMEM_ARB_REFPB_HP_CTRL                               0x6f0\n#define MC_EMEM_ARB_REFPB_BANK_CTRL                             0x6f4\n#define MC_EMEM_ARB_DA_TURNS                                    0xd0\n#define MC_EMEM_ARB_DA_COVERS                                   0xd4\n#define MC_EMEM_ARB_MISC0                                       0xd8\n#define MC_EMEM_ARB_MISC1                                       0xdc\n#define MC_EMEM_ARB_MISC2                                       0xc8\n#define MC_EMEM_ARB_RING1_THROTTLE                              0xe0\n#define MC_EMEM_ARB_RING3_THROTTLE                              0xe4\n#define MC_EMEM_ARB_NISO_THROTTLE                               0x6b0\n#define MC_EMEM_ARB_OVERRIDE                                    0xe8\n#define MC_EMEM_ARB_RSV                                         0xec\n#define MC_CLKEN_OVERRIDE                                       0xf4\n#define MC_TIMING_CONTROL_DBG                                   0xf8\n#define MC_TIMING_CONTROL                                       0xfc\n#define MC_STAT_CONTROL                                         0x100\n#define MC_STAT_STATUS                                          0x104\n#define MC_STAT_EMC_CLOCK_LIMIT                                 0x108\n#define MC_STAT_EMC_CLOCK_LIMIT_MSBS                            0x10c\n#define MC_STAT_EMC_CLOCKS                                      0x110\n#define MC_STAT_EMC_CLOCKS_MSBS                                 0x114\n#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_LO                    0x118\n#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_LO                    0x158\n#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_HI                    0x11c\n#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_HI                    0x15c\n#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_UPPER                 0xa20\n#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_UPPER                 0xa24\n#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_LO            0x198\n#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_LO            0x1a8\n#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_HI            0x19c\n#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_HI            0x1ac\n#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_UPPER         0xa28\n#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_UPPER         0xa2c\n#define MC_STAT_EMC_FILTER_SET0_ASID                            0x1a0\n#define MC_STAT_EMC_FILTER_SET1_ASID                            0x1b0\n#define MC_STAT_EMC_FILTER_SET0_SLACK_LIMIT                     0x120\n#define MC_STAT_EMC_FILTER_SET1_SLACK_LIMIT                     0x160\n#define MC_STAT_EMC_FILTER_SET0_CLIENT_0                        0x128\n#define MC_STAT_EMC_FILTER_SET1_CLIENT_0                        0x168\n#define MC_STAT_EMC_FILTER_SET0_CLIENT_1                        0x12c\n#define MC_STAT_EMC_FILTER_SET1_CLIENT_1                        0x16c\n#define MC_STAT_EMC_FILTER_SET0_CLIENT_2                        0x130\n#define MC_STAT_EMC_FILTER_SET1_CLIENT_2                        0x170\n#define MC_STAT_EMC_FILTER_SET0_CLIENT_3                        0x134\n#define MC_STAT_EMC_FILTER_SET0_CLIENT_4                        0xb88\n#define MC_STAT_EMC_FILTER_SET1_CLIENT_3                        0x174\n#define MC_STAT_EMC_FILTER_SET1_CLIENT_4                        0xb8c\n#define MC_STAT_EMC_SET0_COUNT                                  0x138\n#define MC_STAT_EMC_SET0_COUNT_MSBS                             0x13c\n#define MC_STAT_EMC_SET1_COUNT                                  0x178\n#define MC_STAT_EMC_SET1_COUNT_MSBS                             0x17c\n#define MC_STAT_EMC_SET0_SLACK_ACCUM                            0x140\n#define MC_STAT_EMC_SET0_SLACK_ACCUM_MSBS                       0x144\n#define MC_STAT_EMC_SET1_SLACK_ACCUM                            0x180\n#define MC_STAT_EMC_SET1_SLACK_ACCUM_MSBS                       0x184\n#define MC_STAT_EMC_SET0_HISTO_COUNT                            0x148\n#define MC_STAT_EMC_SET0_HISTO_COUNT_MSBS                       0x14c\n#define MC_STAT_EMC_SET1_HISTO_COUNT                            0x188\n#define MC_STAT_EMC_SET1_HISTO_COUNT_MSBS                       0x18c\n#define MC_STAT_EMC_SET0_MINIMUM_SLACK_OBSERVED                 0x150\n#define MC_STAT_EMC_SET1_MINIMUM_SLACK_OBSERVED                 0x190\n#define MC_STAT_EMC_SET0_IDLE_CYCLE_COUNT                       0x1b8\n#define MC_STAT_EMC_SET0_IDLE_CYCL_COUNT_MSBS                   0x1bc\n#define MC_STAT_EMC_SET1_IDLE_CYCLE_COUNT                       0x1c8\n#define MC_STAT_EMC_SET1_IDLE_CYCL_COUNT_MSBS                   0x1cc\n#define MC_STAT_EMC_SET0_IDLE_CYCLE_PARTITION_SELECT            0x1c0\n#define MC_STAT_EMC_SET1_IDLE_CYCLE_PARTITION_SELECT            0x1d0\n#define MC_CLIENT_HOTRESET_CTRL                                 0x200\n#define MC_CLIENT_HOTRESET_CTRL_1                               0x970\n#define MC_CLIENT_HOTRESET_STATUS                               0x204\n#define MC_CLIENT_HOTRESET_STATUS_1                             0x974\n#define MC_EMEM_ARB_ISOCHRONOUS_0                               0x208\n#define MC_EMEM_ARB_ISOCHRONOUS_1                               0x20c\n#define MC_EMEM_ARB_ISOCHRONOUS_2                               0x210\n#define MC_EMEM_ARB_ISOCHRONOUS_3                               0x214\n#define MC_EMEM_ARB_ISOCHRONOUS_4                               0xb94\n#define MC_EMEM_ARB_HYSTERESIS_0                                0x218\n#define MC_EMEM_ARB_HYSTERESIS_1                                0x21c\n#define MC_EMEM_ARB_HYSTERESIS_2                                0x220\n#define MC_EMEM_ARB_HYSTERESIS_3                                0x224\n#define MC_EMEM_ARB_HYSTERESIS_4                                0xb84\n#define MC_EMEM_ARB_DHYSTERESIS_0                               0xbb0\n#define MC_EMEM_ARB_DHYSTERESIS_1                               0xbb4\n#define MC_EMEM_ARB_DHYSTERESIS_2                               0xbb8\n#define MC_EMEM_ARB_DHYSTERESIS_3                               0xbbc\n#define MC_EMEM_ARB_DHYSTERESIS_4                               0xbc0\n#define MC_EMEM_ARB_DHYST_CTRL                                  0xbcc\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0                        0xbd0\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1                        0xbd4\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2                        0xbd8\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3                        0xbdc\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4                        0xbe0\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5                        0xbe4\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6                        0xbe8\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7                        0xbec\n#define MC_RESERVED_RSV                                         0x3fc\n#define MC_DISB_EXTRA_SNAP_LEVELS                               0x408\n#define MC_APB_EXTRA_SNAP_LEVELS                                0x2a4\n#define MC_AHB_EXTRA_SNAP_LEVELS                                0x2a0\n#define MC_USBD_EXTRA_SNAP_LEVELS                               0xa18\n#define MC_ISP_EXTRA_SNAP_LEVELS                                0xa08\n#define MC_AUD_EXTRA_SNAP_LEVELS                                0xa10\n#define MC_MSE_EXTRA_SNAP_LEVELS                                0x40c\n#define MC_GK2_EXTRA_SNAP_LEVELS                                0xa40\n#define MC_A9AVPPC_EXTRA_SNAP_LEVELS                            0x414\n#define MC_FTOP_EXTRA_SNAP_LEVELS                               0x2bc\n#define MC_JPG_EXTRA_SNAP_LEVELS                                0xa3c\n#define MC_HOST_EXTRA_SNAP_LEVELS                               0xa14\n#define MC_SAX_EXTRA_SNAP_LEVELS                                0x2c0\n#define MC_DIS_EXTRA_SNAP_LEVELS                                0x2ac\n#define MC_VICPC_EXTRA_SNAP_LEVELS                              0xa1c\n#define MC_HDAPC_EXTRA_SNAP_LEVELS                              0xa48\n#define MC_AVP_EXTRA_SNAP_LEVELS                                0x2a8\n#define MC_USBX_EXTRA_SNAP_LEVELS                               0x404\n#define MC_PCX_EXTRA_SNAP_LEVELS                                0x2b8\n#define MC_SD_EXTRA_SNAP_LEVELS                                 0xa04\n#define MC_DFD_EXTRA_SNAP_LEVELS                                0xa4c\n#define MC_VE_EXTRA_SNAP_LEVELS                                 0x2d8\n#define MC_GK_EXTRA_SNAP_LEVELS                                 0xa00\n#define MC_VE2_EXTRA_SNAP_LEVELS                                0x410\n#define MC_SDM_EXTRA_SNAP_LEVELS                                0xa44\n#define MC_VIDEO_PROTECT_BOM                                    0x648\n#define MC_VIDEO_PROTECT_SIZE_MB                                0x64c\n#define MC_VIDEO_PROTECT_BOM_ADR_HI                             0x978\n#define MC_VIDEO_PROTECT_REG_CTRL                               0x650\n#define MC_ERR_VPR_STATUS                                       0x654\n#define MC_ERR_VPR_ADR                                          0x658\n#define MC_VIDEO_PROTECT_VPR_OVERRIDE                           0x418\n#define MC_VIDEO_PROTECT_VPR_OVERRIDE1                          0x590\n#define MC_IRAM_BOM                                             0x65c\n#define MC_IRAM_TOM                                             0x660\n#define MC_IRAM_ADR_HI                                          0x980\n#define MC_IRAM_REG_CTRL                                        0x964\n#define MC_EMEM_CFG_ACCESS_CTRL                                 0x664\n#define MC_TZ_SECURITY_CTRL                                     0x668\n#define MC_EMEM_ARB_OUTSTANDING_REQ_RING3                       0x66c\n#define MC_EMEM_ARB_OUTSTANDING_REQ_NISO                        0x6b4\n#define MC_EMEM_ARB_RING0_THROTTLE_MASK                         0x6bc\n#define MC_EMEM_ARB_NISO_THROTTLE_MASK                          0x6b8\n#define MC_EMEM_ARB_NISO_THROTTLE_MASK_1                        0xb80\n#define MC_SEC_CARVEOUT_BOM                                     0x670\n#define MC_SEC_CARVEOUT_SIZE_MB                                 0x674\n#define MC_SEC_CARVEOUT_ADR_HI                                  0x9d4\n#define MC_SEC_CARVEOUT_REG_CTRL                                0x678\n#define MC_ERR_SEC_STATUS                                       0x67c\n#define MC_ERR_SEC_ADR                                          0x680\n#define MC_PC_IDLE_CLOCK_GATE_CONFIG                            0x684\n#define MC_STUTTER_CONTROL                                      0x688\n#define MC_RESERVED_RSV_1                                       0x958\n#define MC_DVFS_PIPE_SELECT                                     0x95c\n#define MC_AHB_PTSA_MIN                                         0x4e0\n#define MC_AUD_PTSA_MIN                                         0x54c\n#define MC_MLL_MPCORER_PTSA_RATE                                0x44c\n#define MC_RING2_PTSA_RATE                                      0x440\n#define MC_USBD_PTSA_RATE                                       0x530\n#define MC_USBX_PTSA_MIN                                        0x528\n#define MC_USBD_PTSA_MIN                                        0x534\n#define MC_APB_PTSA_MAX                                         0x4f0\n#define MC_JPG_PTSA_RATE                                        0x584\n#define MC_DIS_PTSA_MIN                                         0x420\n#define MC_AVP_PTSA_MAX                                         0x4fc\n#define MC_AVP_PTSA_RATE                                        0x4f4\n#define MC_RING1_PTSA_MIN                                       0x480\n#define MC_DIS_PTSA_MAX                                         0x424\n#define MC_SD_PTSA_MAX                                          0x4d8\n#define MC_MSE_PTSA_RATE                                        0x4c4\n#define MC_VICPC_PTSA_MIN                                       0x558\n#define MC_PCX_PTSA_MAX                                         0x4b4\n#define MC_ISP_PTSA_RATE                                        0x4a0\n#define MC_A9AVPPC_PTSA_MIN                                     0x48c\n#define MC_RING2_PTSA_MAX                                       0x448\n#define MC_AUD_PTSA_RATE                                        0x548\n#define MC_HOST_PTSA_MIN                                        0x51c\n#define MC_MLL_MPCORER_PTSA_MAX                                 0x454\n#define MC_SD_PTSA_MIN                                          0x4d4\n#define MC_RING1_PTSA_RATE                                      0x47c\n#define MC_JPG_PTSA_MIN                                         0x588\n#define MC_HDAPC_PTSA_MIN                                       0x62c\n#define MC_AVP_PTSA_MIN                                         0x4f8\n#define MC_JPG_PTSA_MAX                                         0x58c\n#define MC_VE_PTSA_MAX                                          0x43c\n#define MC_DFD_PTSA_MAX                                         0x63c\n#define MC_VICPC_PTSA_RATE                                      0x554\n#define MC_GK_PTSA_MAX                                          0x544\n#define MC_VICPC_PTSA_MAX                                       0x55c\n#define MC_SDM_PTSA_MAX                                         0x624\n#define MC_SAX_PTSA_RATE                                        0x4b8\n#define MC_PCX_PTSA_MIN                                         0x4b0\n#define MC_APB_PTSA_MIN                                         0x4ec\n#define MC_GK2_PTSA_MIN                                         0x614\n#define MC_PCX_PTSA_RATE                                        0x4ac\n#define MC_RING1_PTSA_MAX                                       0x484\n#define MC_HDAPC_PTSA_RATE                                      0x628\n#define MC_MLL_MPCORER_PTSA_MIN                                 0x450\n#define MC_GK2_PTSA_MAX                                         0x618\n#define MC_AUD_PTSA_MAX                                         0x550\n#define MC_GK2_PTSA_RATE                                        0x610\n#define MC_ISP_PTSA_MAX                                         0x4a8\n#define MC_DISB_PTSA_RATE                                       0x428\n#define MC_VE2_PTSA_MAX                                         0x49c\n#define MC_DFD_PTSA_MIN                                         0x638\n#define MC_FTOP_PTSA_RATE                                       0x50c\n#define MC_A9AVPPC_PTSA_RATE                                    0x488\n#define MC_VE2_PTSA_MIN                                         0x498\n#define MC_USBX_PTSA_MAX                                        0x52c\n#define MC_DIS_PTSA_RATE                                        0x41c\n#define MC_USBD_PTSA_MAX                                        0x538\n#define MC_A9AVPPC_PTSA_MAX                                     0x490\n#define MC_USBX_PTSA_RATE                                       0x524\n#define MC_FTOP_PTSA_MAX                                        0x514\n#define MC_HDAPC_PTSA_MAX                                       0x630\n#define MC_SD_PTSA_RATE                                         0x4d0\n#define MC_DFD_PTSA_RATE                                        0x634\n#define MC_FTOP_PTSA_MIN                                        0x510\n#define MC_SDM_PTSA_RATE                                        0x61c\n#define MC_AHB_PTSA_RATE                                        0x4dc\n#define MC_SMMU_SMMU_PTSA_MAX                                   0x460\n#define MC_RING2_PTSA_MIN                                       0x444\n#define MC_SDM_PTSA_MIN                                         0x620\n#define MC_APB_PTSA_RATE                                        0x4e8\n#define MC_MSE_PTSA_MIN                                         0x4c8\n#define MC_HOST_PTSA_RATE                                       0x518\n#define MC_VE_PTSA_RATE                                         0x434\n#define MC_AHB_PTSA_MAX                                         0x4e4\n#define MC_SAX_PTSA_MIN                                         0x4bc\n#define MC_SMMU_SMMU_PTSA_MIN                                   0x45c\n#define MC_ISP_PTSA_MIN                                         0x4a4\n#define MC_HOST_PTSA_MAX                                        0x520\n#define MC_SAX_PTSA_MAX                                         0x4c0\n#define MC_VE_PTSA_MIN                                          0x438\n#define MC_GK_PTSA_MIN                                          0x540\n#define MC_MSE_PTSA_MAX                                         0x4cc\n#define MC_DISB_PTSA_MAX                                        0x430\n#define MC_DISB_PTSA_MIN                                        0x42c\n#define MC_SMMU_SMMU_PTSA_RATE                                  0x458\n#define MC_VE2_PTSA_RATE                                        0x494\n#define MC_GK_PTSA_RATE                                         0x53c\n#define MC_PTSA_GRANT_DECREMENT                                 0x960\n#define MC_LATENCY_ALLOWANCE_AVPC_0                             0x2e4\n#define MC_LATENCY_ALLOWANCE_AXIAP_0                            0x3a0\n#define MC_LATENCY_ALLOWANCE_XUSB_1                             0x380\n#define MC_LATENCY_ALLOWANCE_ISP2B_0                            0x384\n#define MC_LATENCY_ALLOWANCE_SDMMCAA_0                          0x3bc\n#define MC_LATENCY_ALLOWANCE_SDMMCA_0                           0x3b8\n#define MC_LATENCY_ALLOWANCE_ISP2_0                             0x370\n#define MC_LATENCY_ALLOWANCE_SE_0                               0x3e0\n#define MC_LATENCY_ALLOWANCE_ISP2_1                             0x374\n#define MC_LATENCY_ALLOWANCE_DC_0                               0x2e8\n#define MC_LATENCY_ALLOWANCE_VIC_0                              0x394\n#define MC_LATENCY_ALLOWANCE_DCB_1                              0x2f8\n#define MC_LATENCY_ALLOWANCE_NVDEC_0                            0x3d8\n#define MC_LATENCY_ALLOWANCE_DCB_2                              0x2fc\n#define MC_LATENCY_ALLOWANCE_TSEC_0                             0x390\n#define MC_LATENCY_ALLOWANCE_DC_2                               0x2f0\n#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0AB                  0x694\n#define MC_LATENCY_ALLOWANCE_PPCS_1                             0x348\n#define MC_LATENCY_ALLOWANCE_XUSB_0                             0x37c\n#define MC_LATENCY_ALLOWANCE_PPCS_0                             0x344\n#define MC_LATENCY_ALLOWANCE_TSECB_0                            0x3f0\n#define MC_LATENCY_ALLOWANCE_AFI_0                              0x2e0\n#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0B                   0x698\n#define MC_LATENCY_ALLOWANCE_DC_1                               0x2ec\n#define MC_LATENCY_ALLOWANCE_APE_0                              0x3dc\n#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0C                   0x6a0\n#define MC_LATENCY_ALLOWANCE_A9AVP_0                            0x3a4\n#define MC_LATENCY_ALLOWANCE_GPU2_0                             0x3e8\n#define MC_LATENCY_ALLOWANCE_DCB_0                              0x2f4\n#define MC_LATENCY_ALLOWANCE_HC_1                               0x314\n#define MC_LATENCY_ALLOWANCE_SDMMC_0                            0x3c0\n#define MC_LATENCY_ALLOWANCE_NVJPG_0                            0x3e4\n#define MC_LATENCY_ALLOWANCE_PTC_0                              0x34c\n#define MC_LATENCY_ALLOWANCE_ETR_0                              0x3ec\n#define MC_LATENCY_ALLOWANCE_MPCORE_0                           0x320\n#define MC_LATENCY_ALLOWANCE_VI2_0                              0x398\n#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0BB                  0x69c\n#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0CB                  0x6a4\n#define MC_LATENCY_ALLOWANCE_SATA_0                             0x350\n#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0A                   0x690\n#define MC_LATENCY_ALLOWANCE_HC_0                               0x310\n#define MC_LATENCY_ALLOWANCE_DC_3                               0x3c8\n#define MC_LATENCY_ALLOWANCE_GPU_0                              0x3ac\n#define MC_LATENCY_ALLOWANCE_SDMMCAB_0                          0x3c4\n#define MC_LATENCY_ALLOWANCE_ISP2B_1                            0x388\n#define MC_LATENCY_ALLOWANCE_NVENC_0                            0x328\n#define MC_LATENCY_ALLOWANCE_HDA_0                              0x318\n#define MC_MIN_LENGTH_APE_0                                     0xb34\n#define MC_MIN_LENGTH_DCB_2                                     0x8a8\n#define MC_MIN_LENGTH_A9AVP_0                                   0x950\n#define MC_MIN_LENGTH_TSEC_0                                    0x93c\n#define MC_MIN_LENGTH_DC_1                                      0x898\n#define MC_MIN_LENGTH_AXIAP_0                                   0x94c\n#define MC_MIN_LENGTH_ISP2B_0                                   0x930\n#define MC_MIN_LENGTH_VI2_0                                     0x944\n#define MC_MIN_LENGTH_DCB_0                                     0x8a0\n#define MC_MIN_LENGTH_DCB_1                                     0x8a4\n#define MC_MIN_LENGTH_PPCS_1                                    0x8f4\n#define MC_MIN_LENGTH_NVJPG_0                                   0xb3c\n#define MC_MIN_LENGTH_HDA_0                                     0x8c4\n#define MC_MIN_LENGTH_NVENC_0                                   0x8d4\n#define MC_MIN_LENGTH_SDMMC_0                                   0xb18\n#define MC_MIN_LENGTH_ISP2B_1                                   0x934\n#define MC_MIN_LENGTH_HC_1                                      0x8c0\n#define MC_MIN_LENGTH_DC_3                                      0xb20\n#define MC_MIN_LENGTH_AVPC_0                                    0x890\n#define MC_MIN_LENGTH_VIC_0                                     0x940\n#define MC_MIN_LENGTH_ISP2_0                                    0x91c\n#define MC_MIN_LENGTH_HC_0                                      0x8bc\n#define MC_MIN_LENGTH_SE_0                                      0xb38\n#define MC_MIN_LENGTH_NVDEC_0                                   0xb30\n#define MC_MIN_LENGTH_SATA_0                                    0x8fc\n#define MC_MIN_LENGTH_DC_0                                      0x894\n#define MC_MIN_LENGTH_XUSB_1                                    0x92c\n#define MC_MIN_LENGTH_DC_2                                      0x89c\n#define MC_MIN_LENGTH_SDMMCAA_0                                 0xb14\n#define MC_MIN_LENGTH_GPU_0                                     0xb04\n#define MC_MIN_LENGTH_ETR_0                                     0xb44\n#define MC_MIN_LENGTH_AFI_0                                     0x88c\n#define MC_MIN_LENGTH_PPCS_0                                    0x8f0\n#define MC_MIN_LENGTH_ISP2_1                                    0x920\n#define MC_MIN_LENGTH_XUSB_0                                    0x928\n#define MC_MIN_LENGTH_MPCORE_0                                  0x8cc\n#define MC_MIN_LENGTH_TSECB_0                                   0xb48\n#define MC_MIN_LENGTH_SDMMCA_0                                  0xb10\n#define MC_MIN_LENGTH_GPU2_0                                    0xb40\n#define MC_MIN_LENGTH_SDMMCAB_0                                 0xb1c\n#define MC_MIN_LENGTH_PTC_0                                     0x8f8\n#define MC_EMEM_ARB_OVERRIDE_1                                  0x968\n#define MC_VIDEO_PROTECT_GPU_OVERRIDE_0                         0x984\n#define MC_VIDEO_PROTECT_GPU_OVERRIDE_1                         0x988\n#define MC_EMEM_ARB_STATS_0                                     0x990\n#define MC_EMEM_ARB_STATS_1                                     0x994\n#define MC_MTS_CARVEOUT_BOM                                     0x9a0\n#define MC_MTS_CARVEOUT_SIZE_MB                                 0x9a4\n#define MC_MTS_CARVEOUT_ADR_HI                                  0x9a8\n#define MC_MTS_CARVEOUT_REG_CTRL                                0x9ac\n#define MC_ERR_MTS_STATUS                                       0x9b0\n#define MC_ERR_MTS_ADR                                          0x9b4\n#define MC_ERR_GENERALIZED_CARVEOUT_STATUS                      0xc00\n#define MC_ERR_GENERALIZED_CARVEOUT_ADR                         0xc04\n#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2     0xd74\n#define MC_SECURITY_CARVEOUT4_CFG0                              0xcf8\n#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2                    0xd10\n#define MC_SECURITY_CARVEOUT4_SIZE_128KB                        0xd04\n#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4                    0xc28\n#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1     0xc30\n#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4     0xc8c\n#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0     0xd1c\n#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1     0xd70\n#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0     0xc2c\n#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4     0xd7c\n#define MC_SECURITY_CARVEOUT3_SIZE_128KB                        0xcb4\n#define MC_SECURITY_CARVEOUT2_CFG0                              0xc58\n#define MC_SECURITY_CARVEOUT1_CFG0                              0xc08\n#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2     0xc84\n#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0                    0xc68\n#define MC_SECURITY_CARVEOUT3_BOM                               0xcac\n#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2                    0xc70\n#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3     0xd78\n#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0     0xc7c\n#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4                    0xd18\n#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1                    0xcbc\n#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3     0xc38\n#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2     0xc34\n#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2                    0xcc0\n#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2                    0xd60\n#define MC_SECURITY_CARVEOUT3_CFG0                              0xca8\n#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0                    0xcb8\n#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3     0xc88\n#define MC_SECURITY_CARVEOUT2_SIZE_128KB                        0xc64\n#define MC_SECURITY_CARVEOUT5_BOM_HI                            0xd50\n#define MC_SECURITY_CARVEOUT1_SIZE_128KB                        0xc14\n#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3                    0xd14\n#define MC_SECURITY_CARVEOUT1_BOM                               0xc0c\n#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4     0xd2c\n#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4                    0xd68\n#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4                    0xcc8\n#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0                    0xd58\n#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2     0xd24\n#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3                    0xcc4\n#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4                    0xc78\n#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1                    0xc1c\n#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0                    0xc18\n#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3     0xd28\n#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1                    0xd5c\n#define MC_SECURITY_CARVEOUT3_BOM_HI                            0xcb0\n#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3     0xcd8\n#define MC_SECURITY_CARVEOUT2_BOM_HI                            0xc60\n#define MC_SECURITY_CARVEOUT4_BOM_HI                            0xd00\n#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3                    0xd64\n#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4     0xcdc\n#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1     0xc80\n#define MC_SECURITY_CARVEOUT5_SIZE_128KB                        0xd54\n#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1     0xd20\n#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2     0xcd4\n#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1                    0xd0c\n#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3                    0xc74\n#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0     0xccc\n#define MC_SECURITY_CARVEOUT4_BOM                               0xcfc\n#define MC_SECURITY_CARVEOUT5_CFG0                              0xd48\n#define MC_SECURITY_CARVEOUT2_BOM                               0xc5c\n#define MC_SECURITY_CARVEOUT5_BOM                               0xd4c\n#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3                    0xc24\n#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0     0xd6c\n#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1     0xcd0\n#define MC_SECURITY_CARVEOUT1_BOM_HI                            0xc10\n#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2                    0xc20\n#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4     0xc3c\n#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1                    0xc6c\n#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0                    0xd08\n#define MC_ERR_APB_ASID_UPDATE_STATUS                           0x9d0\n#define MC_DA_CONFIG0                                           0x9dc\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/mem/sdram.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _SDRAM_H_\n#define _SDRAM_H_\n\nvoid sdram_init();\nconst void *sdram_get_params();\nu32 get_sdram_id();\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/mem/sdram_config_lz.inl",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 balika011\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\nstatic const u8 _dram_cfg_lz[1270] = {\n\t0x17, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00,\n\t0x00, 0x2C, 0x17, 0x04, 0x09, 0x00, 0x17, 0x04, 0x04, 0x17, 0x08, 0x08,\n\t0x17, 0x10, 0x10, 0x00, 0x00, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00,\n\t0x00, 0x04, 0xB4, 0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00,\n\t0x70, 0x17, 0x10, 0x24, 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40,\n\t0x00, 0x00, 0x00, 0x17, 0x04, 0x04, 0x17, 0x09, 0x18, 0xFF, 0xFF, 0x1F,\n\t0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77,\n\t0x00, 0x17, 0x04, 0x04, 0x17, 0x08, 0x08, 0x17, 0x08, 0x08, 0xA6, 0xA6,\n\t0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x04,\n\t0x04, 0x04, 0x17, 0x04, 0x04, 0x17, 0x04, 0x3C, 0x1F, 0x1F, 0x1F, 0x1F,\n\t0x17, 0x04, 0x04, 0x17, 0x06, 0x06, 0x00, 0x00, 0x04, 0x08, 0x17, 0x06,\n\t0x46, 0xA1, 0x01, 0x00, 0x00, 0x32, 0x17, 0x0B, 0x64, 0x01, 0x17, 0x04,\n\t0x7C, 0x17, 0x07, 0x0C, 0x03, 0x17, 0x04, 0x04, 0x00, 0x00, 0x00, 0x1E,\n\t0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13,\n\t0x17, 0x0B, 0x2C, 0x09, 0x00, 0x00, 0x00, 0x17, 0x05, 0x5D, 0x17, 0x07,\n\t0x10, 0x0B, 0x17, 0x07, 0x28, 0x08, 0x17, 0x07, 0x0C, 0x17, 0x04, 0x1C,\n\t0x20, 0x00, 0x00, 0x00, 0x06, 0x17, 0x04, 0x04, 0x17, 0x07, 0x08, 0x17,\n\t0x04, 0x50, 0x17, 0x04, 0x2C, 0x17, 0x04, 0x1C, 0x17, 0x04, 0x10, 0x17,\n\t0x08, 0x6C, 0x17, 0x04, 0x10, 0x17, 0x04, 0x38, 0x17, 0x04, 0x40, 0x05,\n\t0x17, 0x07, 0x1C, 0x17, 0x08, 0x58, 0x17, 0x04, 0x24, 0x17, 0x04, 0x18,\n\t0x17, 0x08, 0x64, 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14,\n\t0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x17, 0x09, 0x0C, 0x17, 0x05, 0x82,\n\t0x58, 0x17, 0x07, 0x61, 0xC1, 0x17, 0x07, 0x50, 0x17, 0x04, 0x04, 0x17,\n\t0x08, 0x81, 0x48, 0x17, 0x04, 0x04, 0x17, 0x04, 0x28, 0x17, 0x04, 0x60,\n\t0x17, 0x08, 0x54, 0x27, 0x17, 0x04, 0x04, 0x17, 0x07, 0x14, 0x17, 0x04,\n\t0x04, 0x04, 0x17, 0x07, 0x81, 0x58, 0x17, 0x0C, 0x0C, 0x1C, 0x03, 0x00,\n\t0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x17, 0x04, 0x5A, 0xF3, 0x0C,\n\t0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05,\n\t0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03,\n\t0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02,\n\t0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08,\n\t0x24, 0x06, 0x07, 0x9A, 0x12, 0x17, 0x05, 0x83, 0x41, 0x00, 0xFF, 0x17,\n\t0x10, 0x83, 0x6C, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00,\n\t0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00,\n\t0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x17, 0x04, 0x20, 0x08, 0x08,\n\t0x0D, 0x0C, 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x17, 0x06,\n\t0x2C, 0x11, 0x08, 0x17, 0x10, 0x84, 0x67, 0x15, 0x00, 0xCC, 0x00, 0x0A,\n\t0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00, 0xFF,\n\t0x0F, 0xFF, 0x0F, 0x17, 0x08, 0x83, 0x4C, 0x01, 0x03, 0x00, 0x70, 0x00,\n\t0x0C, 0x00, 0x01, 0x17, 0x04, 0x0C, 0x08, 0x44, 0x00, 0x10, 0x04, 0x04,\n\t0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x17, 0x04, 0x10, 0xA0, 0x00, 0x2C,\n\t0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x17, 0x06, 0x48, 0x08, 0x00,\n\t0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28,\n\t0x28, 0x28, 0x17, 0x04, 0x04, 0x11, 0x11, 0x11, 0x11, 0x17, 0x04, 0x04,\n\t0xBE, 0x00, 0x00, 0x17, 0x05, 0x58, 0x17, 0x08, 0x5C, 0x17, 0x22, 0x85,\n\t0x6A, 0x17, 0x1A, 0x1A, 0x14, 0x00, 0x12, 0x00, 0x10, 0x17, 0x05, 0x83,\n\t0x0A, 0x17, 0x16, 0x18, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x17, 0x05, 0x83, 0x0C, 0x17,\n\t0x04, 0x20, 0x17, 0x18, 0x18, 0x28, 0x00, 0x28, 0x17, 0x04, 0x04, 0x17,\n\t0x08, 0x08, 0x17, 0x10, 0x10, 0x00, 0x14, 0x17, 0x05, 0x5A, 0x17, 0x04,\n\t0x5C, 0x17, 0x04, 0x5E, 0x17, 0x04, 0x0E, 0x17, 0x0E, 0x78, 0x17, 0x09,\n\t0x82, 0x50, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51,\n\t0x17, 0x08, 0x18, 0x80, 0x01, 0x00, 0x00, 0x40, 0x17, 0x04, 0x20, 0x03,\n\t0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x17, 0x08, 0x82, 0x58,\n\t0x17, 0x0C, 0x38, 0x17, 0x1B, 0x81, 0x6C, 0x17, 0x08, 0x85, 0x60, 0x17,\n\t0x08, 0x86, 0x50, 0x17, 0x08, 0x86, 0x60, 0x17, 0x06, 0x83, 0x21, 0x22,\n\t0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x17, 0x0C, 0x86, 0x74, 0x17, 0x08, 0x2C,\n\t0x8B, 0xFF, 0x07, 0x17, 0x06, 0x81, 0x04, 0x32, 0x54, 0x76, 0x10, 0x47,\n\t0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75,\n\t0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45,\n\t0x32, 0x67, 0x17, 0x04, 0x24, 0x49, 0x92, 0x24, 0x17, 0x04, 0x04, 0x17,\n\t0x11, 0x7C, 0x1B, 0x17, 0x04, 0x04, 0x17, 0x13, 0x81, 0x14, 0x2F, 0x41,\n\t0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x17, 0x04, 0x7C, 0xFF, 0xFF, 0xFF,\n\t0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03,\n\t0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x17, 0x06, 0x86, 0x59,\n\t0x17, 0x0F, 0x89, 0x14, 0x37, 0x17, 0x07, 0x82, 0x72, 0x10, 0x17, 0x06,\n\t0x83, 0x0D, 0x00, 0x11, 0x01, 0x17, 0x05, 0x85, 0x39, 0x17, 0x04, 0x0E,\n\t0x0A, 0x17, 0x07, 0x89, 0x29, 0x17, 0x04, 0x1B, 0x17, 0x08, 0x86, 0x77,\n\t0x17, 0x09, 0x12, 0x20, 0x00, 0x00, 0x00, 0x81, 0x10, 0x09, 0x28, 0x93,\n\t0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x17, 0x18, 0x82, 0x2C, 0xFF,\n\t0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0x17, 0x04, 0x04, 0xDC, 0xDC,\n\t0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x17, 0x04, 0x04, 0x17, 0x04, 0x04,\n\t0x17, 0x05, 0x82, 0x24, 0x03, 0x07, 0x17, 0x04, 0x04, 0x00, 0x00, 0x24,\n\t0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10,\n\t0x9C, 0x4B, 0x17, 0x04, 0x64, 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00,\n\t0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x17, 0x06, 0x85, 0x60, 0x17,\n\t0x10, 0x82, 0x74, 0x17, 0x08, 0x08, 0x17, 0x08, 0x88, 0x00, 0x17, 0x04,\n\t0x10, 0x04, 0x17, 0x0B, 0x87, 0x6C, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02,\n\t0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x17, 0x08, 0x8B, 0x18,\n\t0x1F, 0x17, 0x09, 0x81, 0x73, 0x00, 0xFF, 0x00, 0xFF, 0x17, 0x05, 0x86,\n\t0x48, 0x17, 0x04, 0x0C, 0x17, 0x07, 0x86, 0x34, 0x00, 0x00, 0xF0, 0x17,\n\t0x09, 0x87, 0x54, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x17, 0x0C, 0x81,\n\t0x52, 0x17, 0x0A, 0x1C, 0x17, 0x10, 0x81, 0x6C, 0x17, 0x0A, 0x82, 0x21,\n\t0x17, 0x07, 0x82, 0x4D, 0x17, 0x0A, 0x8A, 0x1B, 0x17, 0x11, 0x2C, 0x76,\n\t0x0C, 0x17, 0x0A, 0x8A, 0x67, 0x17, 0x0F, 0x84, 0x28, 0x17, 0x06, 0x34,\n\t0x17, 0x17, 0x3A, 0x7E, 0x16, 0x40, 0x17, 0x0C, 0x8B, 0x1F, 0x17, 0x2A,\n\t0x38, 0x1E, 0x17, 0x0A, 0x38, 0x17, 0x13, 0x81, 0x28, 0x00, 0xC0, 0x17,\n\t0x17, 0x55, 0x46, 0x24, 0x17, 0x0A, 0x81, 0x28, 0x17, 0x14, 0x38, 0x17,\n\t0x18, 0x81, 0x60, 0x46, 0x2C, 0x17, 0x06, 0x38, 0xEC, 0x00, 0x00, 0x00,\n\t0x01, 0x77, 0x00, 0xFC, 0x00, 0x20, 0xCF, 0x22, 0x17, 0x10, 0x82, 0x3C,\n\t0x17, 0x82, 0x0C, 0x8E, 0x68, 0x17, 0x04, 0x24, 0x17, 0x5C, 0x8E, 0x68,\n\t0x17, 0x07, 0x82, 0x5F, 0x80, 0x17, 0x87, 0x01, 0x8E, 0x68, 0x02, 0x17,\n\t0x81, 0x4A, 0x8E, 0x68, 0x17, 0x0C, 0x87, 0x78, 0x17, 0x85, 0x28, 0x8E,\n\t0x68, 0x17, 0x8E, 0x68, 0x9D, 0x50, 0x17, 0x81, 0x24, 0x8E, 0x68, 0x17,\n\t0x04, 0x2C, 0x17, 0x28, 0x8E, 0x68, 0x17, 0x04, 0x30, 0x17, 0x85, 0x3C,\n\t0x8E, 0x68, 0x12, 0x17, 0x07, 0x85, 0x70, 0x17, 0x88, 0x74, 0x8E, 0x68,\n\t0x17, 0x87, 0x3E, 0x9D, 0x50, 0x0C, 0x17, 0x04, 0x04, 0x17, 0x12, 0x8E,\n\t0x68, 0x18, 0x17, 0x87, 0x12, 0xBB, 0x20, 0x17, 0x83, 0x04, 0x9D, 0x50,\n\t0x15, 0x17, 0x05, 0x8D, 0x76, 0x17, 0x0F, 0x8B, 0x49, 0x17, 0x0B, 0x18,\n\t0x32, 0x00, 0x2F, 0x00, 0x32, 0x00, 0x31, 0x00, 0x34, 0x00, 0x36, 0x00,\n\t0x2F, 0x00, 0x33, 0x17, 0x09, 0x84, 0x0C, 0x17, 0x18, 0x18, 0x17, 0x20,\n\t0x8E, 0x68, 0x15, 0x17, 0x07, 0x5A, 0x17, 0x06, 0x5E, 0x16, 0x00, 0x15,\n\t0x17, 0x82, 0x40, 0x9D, 0x50, 0x17, 0x86, 0x5F, 0xBB, 0x20, 0x3A, 0x00,\n\t0x00, 0x00, 0x1D, 0x17, 0x81, 0x4F, 0xAC, 0x38, 0x3B, 0x17, 0x04, 0x04,\n\t0x17, 0x86, 0x30, 0x8E, 0x68, 0x17, 0x81, 0x53, 0xAC, 0x38, 0x07, 0x17,\n\t0x0D, 0x8E, 0x68, 0xA3, 0x72, 0x17, 0x83, 0x10, 0x8E, 0x68\n};\n"
  },
  {
    "path": "argon-nx-gui/include/mem/sdram_param_t210.h",
    "content": "/*\n * Copyright (c) 2015, NVIDIA CORPORATION.  All rights reserved.\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n *\n * See file CREDITS for list of people who contributed to this\n * project.\n */\n\n/**\n * Defines the SDRAM parameter structure.\n *\n * Note that PLLM is used by EMC.\n */\n\n#ifndef _SDRAM_PARAM_T210_H_\n#define _SDRAM_PARAM_T210_H_\n\n#define MEMORY_TYPE_NONE 0\n#define MEMORY_TYPE_DDR 0\n#define MEMORY_TYPE_LPDDR 0\n#define MEMORY_TYPE_DDR2 0\n#define MEMORY_TYPE_LPDDR2 1\n#define MEMORY_TYPE_DDR3 2\n#define MEMORY_TYPE_LPDDR4 3\n\n/**\n * Defines the SDRAM parameter structure\n */\ntypedef struct _sdram_params\n{\n\t/* Specifies the type of memory device */\n\tu32 memory_type;\n\n\t/* MC/EMC clock source configuration */\n\n\t/* Specifies the M value for PllM */\n\tu32 pllm_input_divider;\n\t/* Specifies the N value for PllM */\n\tu32 pllm_feedback_divider;\n\t/* Specifies the time to wait for PLLM to lock (in microseconds) */\n\tu32 pllm_stable_time;\n\t/* Specifies misc. control bits */\n\tu32 pllm_setup_control;\n\t/* Specifies the P value for PLLM */\n\tu32 pllm_post_divider;\n\t/* Specifies value for Charge Pump Gain Control */\n\tu32 pllm_kcp;\n\t/* Specifies VCO gain */\n\tu32 pllm_kvco;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare0;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare1;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare2;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare3;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare4;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare5;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare6;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare7;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare8;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare9;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare10;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare11;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare12;\n\t/* Spare BCT param */\n\tu32 emc_bct_spare13;\n\n\t/* Defines EMC_2X_CLK_SRC, EMC_2X_CLK_DIVISOR, EMC_INVERT_DCD */\n\tu32 emc_clock_source;\n\tu32 emc_clock_source_dll;\n\n\t/* Defines possible override for PLLLM_MISC2 */\n\tu32 clk_rst_pllm_misc20_override;\n\t/* enables override for PLLLM_MISC2 */\n\tu32 clk_rst_pllm_misc20_override_enable;\n\t/* defines CLK_ENB_MC1 in register clk_rst_controller_clk_enb_w_clr */\n\tu32 clear_clock2_mc1;\n\n\t/* Auto-calibration of EMC pads */\n\n\t/* Specifies the value for EMC_AUTO_CAL_INTERVAL */\n\tu32 emc_auto_cal_interval;\n\t/*\n\t * Specifies the value for EMC_AUTO_CAL_CONFIG\n\t * Note: Trigger bits are set by the SDRAM code.\n\t */\n\tu32 emc_auto_cal_config;\n\n\t/* Specifies the value for EMC_AUTO_CAL_CONFIG2 */\n\tu32 emc_auto_cal_config2;\n\n\t/* Specifies the value for EMC_AUTO_CAL_CONFIG3 */\n\tu32 emc_auto_cal_config3;\n\n\tu32 emc_auto_cal_config4;\n\tu32 emc_auto_cal_config5;\n\tu32 emc_auto_cal_config6;\n\tu32 emc_auto_cal_config7;\n\tu32 emc_auto_cal_config8;\n\t/* Specifies the value for EMC_AUTO_CAL_VREF_SEL_0 */\n\tu32 emc_auto_cal_vref_sel0;\n\tu32 emc_auto_cal_vref_sel1;\n\n\t/* Specifies the value for EMC_AUTO_CAL_CHANNEL */\n\tu32 emc_auto_cal_channel;\n\n\t/* Specifies the value for EMC_PMACRO_AUTOCAL_CFG_0 */\n\tu32 emc_pmacro_auto_cal_cfg0;\n\tu32 emc_pmacro_auto_cal_cfg1;\n\tu32 emc_pmacro_auto_cal_cfg2;\n\n\tu32 emc_pmacro_rx_term;\n\tu32 emc_pmacro_dq_tx_drive;\n\tu32 emc_pmacro_ca_tx_drive;\n\tu32 emc_pmacro_cmd_tx_drive;\n\tu32 emc_pmacro_auto_cal_common;\n\tu32 emc_pmacro_zcrtl;\n\n\t/*\n\t * Specifies the time for the calibration\n\t * to stabilize (in microseconds)\n\t */\n\tu32 emc_auto_cal_wait;\n\n\tu32 emc_xm2_comp_pad_ctrl;\n\tu32 emc_xm2_comp_pad_ctrl2;\n\tu32 emc_xm2_comp_pad_ctrl3;\n\n\t/*\n\t * DRAM size information\n\t * Specifies the value for EMC_ADR_CFG\n\t */\n\tu32 emc_adr_cfg;\n\n\t/*\n\t * Specifies the time to wait after asserting pin\n\t * CKE (in microseconds)\n\t */\n\tu32 emc_pin_program_wait;\n\t/* Specifies the extra delay before/after pin RESET/CKE command */\n\tu32 emc_pin_extra_wait;\n\n\tu32 emc_pin_gpio_enable;\n\tu32 emc_pin_gpio;\n\n\t/*\n\t * Specifies the extra delay after the first writing\n\t * of EMC_TIMING_CONTROL\n\t */\n\tu32 emc_timing_control_wait;\n\n\t/* Timing parameters required for the SDRAM */\n\n\t/* Specifies the value for EMC_RC */\n\tu32 emc_rc;\n\t/* Specifies the value for EMC_RFC */\n\tu32 emc_rfc;\n\n\tu32 emc_rfc_pb;\n\tu32 emc_ref_ctrl2;\n\n\t/* Specifies the value for EMC_RFC_SLR */\n\tu32 emc_rfc_slr;\n\t/* Specifies the value for EMC_RAS */\n\tu32 emc_ras;\n\t/* Specifies the value for EMC_RP */\n\tu32 emc_rp;\n\t/* Specifies the value for EMC_R2R */\n\tu32 emc_r2r;\n\t/* Specifies the value for EMC_W2W */\n\tu32 emc_w2w;\n\t/* Specifies the value for EMC_R2W */\n\tu32 emc_r2w;\n\t/* Specifies the value for EMC_W2R */\n\tu32 emc_w2r;\n\t/* Specifies the value for EMC_R2P */\n\tu32 emc_r2p;\n\t/* Specifies the value for EMC_W2P */\n\tu32 emc_w2p;\n\t/* Specifies the value for EMC_RD_RCD */\n\n\tu32 emc_tppd;\n\tu32 emc_ccdmw;\n\n\tu32 emc_rd_rcd;\n\t/* Specifies the value for EMC_WR_RCD */\n\tu32 emc_wr_rcd;\n\t/* Specifies the value for EMC_RRD */\n\tu32 emc_rrd;\n\t/* Specifies the value for EMC_REXT */\n\tu32 emc_rext;\n\t/* Specifies the value for EMC_WEXT */\n\tu32 emc_wext;\n\t/* Specifies the value for EMC_WDV */\n\tu32 emc_wdv;\n\n\tu32 emc_wdv_chk;\n\tu32 emc_wsv;\n\tu32 emc_wev;\n\n\t/* Specifies the value for EMC_WDV_MASK */\n\tu32 emc_wdv_mask;\n\n\tu32 emc_ws_duration;\n\tu32 emc_we_duration;\n\n\t/* Specifies the value for EMC_QUSE */\n\tu32 emc_quse;\n\t/* Specifies the value for EMC_QUSE_WIDTH */\n\tu32 emc_quse_width;\n\t/* Specifies the value for EMC_IBDLY */\n\tu32 emc_ibdly;\n\n\tu32 emc_obdly;\n\n\t/* Specifies the value for EMC_EINPUT */\n\tu32 emc_einput;\n\t/* Specifies the value for EMC_EINPUT_DURATION */\n\tu32 emc_einput_duration;\n\t/* Specifies the value for EMC_PUTERM_EXTRA */\n\tu32 emc_puterm_extra;\n\t/* Specifies the value for EMC_PUTERM_WIDTH */\n\tu32 emc_puterm_width;\n\n\tu32 emc_qrst;\n\tu32 emc_qsafe;\n\tu32 emc_rdv;\n\tu32 emc_rdv_mask;\n\n\tu32 emc_rdv_early;\n\tu32 emc_rdv_early_mask;\n\n\t/* Specifies the value for EMC_QPOP */\n\tu32 emc_qpop;\n\n\t/* Specifies the value for EMC_REFRESH */\n\tu32 emc_refresh;\n\t/* Specifies the value for EMC_BURST_REFRESH_NUM */\n\tu32 emc_burst_refresh_num;\n\t/* Specifies the value for EMC_PRE_REFRESH_REQ_CNT */\n\tu32 emc_prerefresh_req_cnt;\n\t/* Specifies the value for EMC_PDEX2WR */\n\tu32 emc_pdex2wr;\n\t/* Specifies the value for EMC_PDEX2RD */\n\tu32 emc_pdex2rd;\n\t/* Specifies the value for EMC_PCHG2PDEN */\n\tu32 emc_pchg2pden;\n\t/* Specifies the value for EMC_ACT2PDEN */\n\tu32 emc_act2pden;\n\t/* Specifies the value for EMC_AR2PDEN */\n\tu32 emc_ar2pden;\n\t/* Specifies the value for EMC_RW2PDEN */\n\tu32 emc_rw2pden;\n\n\tu32 emc_cke2pden;\n\tu32 emc_pdex2che;\n\tu32 emc_pdex2mrr;\n\n\t/* Specifies the value for EMC_TXSR */\n\tu32 emc_txsr;\n\t/* Specifies the value for EMC_TXSRDLL */\n\tu32 emc_txsr_dll;\n\t/* Specifies the value for EMC_TCKE */\n\tu32 emc_tcke;\n\t/* Specifies the value for EMC_TCKESR */\n\tu32 emc_tckesr;\n\t/* Specifies the value for EMC_TPD */\n\tu32 emc_tpd;\n\t/* Specifies the value for EMC_TFAW */\n\tu32 emc_tfaw;\n\t/* Specifies the value for EMC_TRPAB */\n\tu32 emc_trpab;\n\t/* Specifies the value for EMC_TCLKSTABLE */\n\tu32 emc_tclkstable;\n\t/* Specifies the value for EMC_TCLKSTOP */\n\tu32 emc_tclkstop;\n\t/* Specifies the value for EMC_TREFBW */\n\tu32 emc_trefbw;\n\n\t/* FBIO configuration values */\n\n\t/* Specifies the value for EMC_FBIO_CFG5 */\n\tu32 emc_fbio_cfg5;\n\t/* Specifies the value for EMC_FBIO_CFG7 */\n\tu32 emc_fbio_cfg7;\n\tu32 emc_fbio_cfg8;\n\n\t/* Command mapping for CMD brick 0 */\n\tu32 emc_cmd_mapping_cmd0_0;\n\tu32 emc_cmd_mapping_cmd0_1;\n\tu32 emc_cmd_mapping_cmd0_2;\n\tu32 emc_cmd_mapping_cmd1_0;\n\tu32 emc_cmd_mapping_cmd1_1;\n\tu32 emc_cmd_mapping_cmd1_2;\n\tu32 emc_cmd_mapping_cmd2_0;\n\tu32 emc_cmd_mapping_cmd2_1;\n\tu32 emc_cmd_mapping_cmd2_2;\n\tu32 emc_cmd_mapping_cmd3_0;\n\tu32 emc_cmd_mapping_cmd3_1;\n\tu32 emc_cmd_mapping_cmd3_2;\n\tu32 emc_cmd_mapping_byte;\n\n\t/* Specifies the value for EMC_FBIO_SPARE */\n\tu32 emc_fbio_spare;\n\n\t/* Specifies the value for EMC_CFG_RSV */\n\tu32 emc_cfg_rsv;\n\n\t/* MRS command values */\n\n\t/* Specifies the value for EMC_MRS */\n\tu32 emc_mrs;\n\t/* Specifies the MP0 command to initialize mode registers */\n\tu32 emc_emrs;\n\t/* Specifies the MP2 command to initialize mode registers */\n\tu32 emc_emrs2;\n\t/* Specifies the MP3 command to initialize mode registers */\n\tu32 emc_emrs3;\n\t/* Specifies the programming to LPDDR2 Mode Register 1 at cold boot */\n\tu32 emc_mrw1;\n\t/* Specifies the programming to LPDDR2 Mode Register 2 at cold boot */\n\tu32 emc_mrw2;\n\t/* Specifies the programming to LPDDR2 Mode Register 3 at cold boot */\n\tu32 emc_mrw3;\n\t/* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */\n\tu32 emc_mrw4;\n\n\t/* Specifies the programming to LPDDR4 Mode Register 3 at cold boot */\n\tu32 emc_mrw6;\n\t/* Specifies the programming to LPDDR4 Mode Register 11 at cold boot */\n\tu32 emc_mrw8;\n\t/* Specifies the programming to LPDDR4 Mode Register 11 at cold boot */\n\tu32 emc_mrw9;\n\t/* Specifies the programming to LPDDR4 Mode Register 12 at cold boot */\n\tu32 emc_mrw10;\n\t/* Specifies the programming to LPDDR4 Mode Register 14 at cold boot */\n\tu32 emc_mrw12;\n\t/* Specifies the programming to LPDDR4 Mode Register 14 at cold boot */\n\tu32 emc_mrw13;\n\t/* Specifies the programming to LPDDR4 Mode Register 22 at cold boot */\n\tu32 emc_mrw14;\n\n\t/*\n\t * Specifies the programming to extra LPDDR2 Mode Register\n\t * at cold boot\n\t */\n\tu32 emc_mrw_extra;\n\t/*\n\t * Specifies the programming to extra LPDDR2 Mode Register\n\t * at warm boot\n\t */\n\tu32 emc_warm_boot_mrw_extra;\n\t/*\n\t * Specify the enable of extra Mode Register programming at\n\t * warm boot\n\t */\n\tu32 emc_warm_boot_extramode_reg_write_enable;\n\t/*\n\t * Specify the enable of extra Mode Register programming at\n\t * cold boot\n\t */\n\tu32 emc_extramode_reg_write_enable;\n\n\t/* Specifies the EMC_MRW reset command value */\n\tu32 emc_mrw_reset_command;\n\t/* Specifies the EMC Reset wait time (in microseconds) */\n\tu32 emc_mrw_reset_ninit_wait;\n\t/* Specifies the value for EMC_MRS_WAIT_CNT */\n\tu32 emc_mrs_wait_cnt;\n\t/* Specifies the value for EMC_MRS_WAIT_CNT2 */\n\tu32 emc_mrs_wait_cnt2;\n\n\t/* EMC miscellaneous configurations */\n\n\t/* Specifies the value for EMC_CFG */\n\tu32 emc_cfg;\n\t/* Specifies the value for EMC_CFG_2 */\n\tu32 emc_cfg2;\n\t/* Specifies the pipe bypass controls */\n\tu32 emc_cfg_pipe;\n\n\tu32 emc_cfg_pipe_clk;\n\tu32 emc_fdpd_ctrl_cmd_no_ramp;\n\tu32 emc_cfg_update;\n\n\t/* Specifies the value for EMC_DBG */\n\tu32 emc_dbg;\n\n\tu32 emc_dbg_write_mux;\n\n\t/* Specifies the value for EMC_CMDQ */\n\tu32 emc_cmd_q;\n\t/* Specifies the value for EMC_MC2EMCQ */\n\tu32 emc_mc2emc_q;\n\t/* Specifies the value for EMC_DYN_SELF_REF_CONTROL */\n\tu32 emc_dyn_self_ref_control;\n\n\t/* Specifies the value for MEM_INIT_DONE */\n\tu32 ahb_arbitration_xbar_ctrl_meminit_done;\n\n\t/* Specifies the value for EMC_CFG_DIG_DLL */\n\tu32 emc_cfg_dig_dll;\n\tu32 emc_cfg_dig_dll_1;\n\n\t/* Specifies the value for EMC_CFG_DIG_DLL_PERIOD */\n\tu32 emc_cfg_dig_dll_period;\n\t/* Specifies the value of *DEV_SELECTN of various EMC registers */\n\tu32 emc_dev_select;\n\n\t/* Specifies the value for EMC_SEL_DPD_CTRL */\n\tu32 emc_sel_dpd_ctrl;\n\n\t/* Pads trimmer delays */\n\tu32 emc_fdpd_ctrl_dq;\n\tu32 emc_fdpd_ctrl_cmd;\n\tu32 emc_pmacro_ib_vref_dq_0;\n\tu32 emc_pmacro_ib_vref_dq_1;\n\tu32 emc_pmacro_ib_vref_dqs_0;\n\tu32 emc_pmacro_ib_vref_dqs_1;\n\tu32 emc_pmacro_ib_rxrt;\n\tu32 emc_cfg_pipe1;\n\tu32 emc_cfg_pipe2;\n\n\t/* Specifies the value for EMC_PMACRO_QUSE_DDLL_RANK0_0 */\n\tu32 emc_pmacro_quse_ddll_rank0_0;\n\tu32 emc_pmacro_quse_ddll_rank0_1;\n\tu32 emc_pmacro_quse_ddll_rank0_2;\n\tu32 emc_pmacro_quse_ddll_rank0_3;\n\tu32 emc_pmacro_quse_ddll_rank0_4;\n\tu32 emc_pmacro_quse_ddll_rank0_5;\n\tu32 emc_pmacro_quse_ddll_rank1_0;\n\tu32 emc_pmacro_quse_ddll_rank1_1;\n\tu32 emc_pmacro_quse_ddll_rank1_2;\n\tu32 emc_pmacro_quse_ddll_rank1_3;\n\tu32 emc_pmacro_quse_ddll_rank1_4;\n\tu32 emc_pmacro_quse_ddll_rank1_5;\n\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_0;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_1;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_2;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_3;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_4;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_5;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_0;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_1;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_2;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_3;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_4;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_5;\n\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_0;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_1;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_2;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_3;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_4;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_5;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_0;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_1;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_2;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_3;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_4;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_5;\n\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank0_0;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank0_1;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank0_2;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank0_3;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank1_0;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank1_1;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank1_2;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank1_3;\n\n\tu32 emc_pmacro_ddll_long_cmd_0;\n\tu32 emc_pmacro_ddll_long_cmd_1;\n\tu32 emc_pmacro_ddll_long_cmd_2;\n\tu32 emc_pmacro_ddll_long_cmd_3;\n\tu32 emc_pmacro_ddll_long_cmd_4;\n\tu32 emc_pmacro_ddll_short_cmd_0;\n\tu32 emc_pmacro_ddll_short_cmd_1;\n\tu32 emc_pmacro_ddll_short_cmd_2;\n\n\t/*\n\t * Specifies the delay after asserting CKE pin during a WarmBoot0\n\t * sequence (in microseconds)\n\t */\n\tu32 warm_boot_wait;\n\n\t/* Specifies the value for EMC_ODT_WRITE */\n\tu32 emc_odt_write;\n\n\t/* Periodic ZQ calibration */\n\n\t/*\n\t * Specifies the value for EMC_ZCAL_INTERVAL\n\t * Value 0 disables ZQ calibration\n\t */\n\tu32 emc_zcal_interval;\n\t/* Specifies the value for EMC_ZCAL_WAIT_CNT */\n\tu32 emc_zcal_wait_cnt;\n\t/* Specifies the value for EMC_ZCAL_MRW_CMD */\n\tu32 emc_zcal_mrw_cmd;\n\n\t/* DRAM initialization sequence flow control */\n\n\t/* Specifies the MRS command value for resetting DLL */\n\tu32 emc_mrs_reset_dll;\n\t/* Specifies the command for ZQ initialization of device 0 */\n\tu32 emc_zcal_init_dev0;\n\t/* Specifies the command for ZQ initialization of device 1 */\n\tu32 emc_zcal_init_dev1;\n\t/*\n\t * Specifies the wait time after programming a ZQ initialization\n\t * command (in microseconds)\n\t */\n\tu32 emc_zcal_init_wait;\n\t/*\n\t * Specifies the enable for ZQ calibration at cold boot [bit 0]\n\t * and warm boot [bit 1]\n\t */\n\tu32 emc_zcal_warm_cold_boot_enables;\n\n\t/*\n\t * Specifies the MRW command to LPDDR2 for ZQ calibration\n\t * on warmboot\n\t */\n\t/* Is issued to both devices separately */\n\tu32 emc_mrw_lpddr2zcal_warm_boot;\n\t/*\n\t * Specifies the ZQ command to DDR3 for ZQ calibration on warmboot\n\t * Is issued to both devices separately\n\t */\n\tu32 emc_zqcal_ddr3_warm_boot;\n\n\tu32 emc_zqcal_lpddr4_warm_boot;\n\n\t/*\n\t * Specifies the wait time for ZQ calibration on warmboot\n\t * (in microseconds)\n\t */\n\tu32 emc_zcal_warm_boot_wait;\n\t/*\n\t * Specifies the enable for DRAM Mode Register programming\n\t * at warm boot\n\t */\n\tu32 emc_mrs_warm_boot_enable;\n\t/*\n\t * Specifies the wait time after sending an MRS DLL reset command\n\t * in microseconds)\n\t */\n\tu32 emc_mrs_reset_dll_wait;\n\t/* Specifies the extra MRS command to initialize mode registers */\n\tu32 emc_mrs_extra;\n\t/* Specifies the extra MRS command at warm boot */\n\tu32 emc_warm_boot_mrs_extra;\n\t/* Specifies the EMRS command to enable the DDR2 DLL */\n\tu32 emc_emrs_ddr2_dll_enable;\n\t/* Specifies the MRS command to reset the DDR2 DLL */\n\tu32 emc_mrs_ddr2_dll_reset;\n\t/* Specifies the EMRS command to set OCD calibration */\n\tu32 emc_emrs_ddr2_ocd_calib;\n\t/*\n\t * Specifies the wait between initializing DDR and setting OCD\n\t * calibration (in microseconds)\n\t */\n\tu32 emc_ddr2_wait;\n\t/* Specifies the value for EMC_CLKEN_OVERRIDE */\n\tu32 emc_clken_override;\n\t/*\n\t * Specifies LOG2 of the extra refresh numbers after booting\n\t * Program 0 to disable\n\t */\n\tu32 emc_extra_refresh_num;\n\t/* Specifies the master override for all EMC clocks */\n\tu32 emc_clken_override_allwarm_boot;\n\t/* Specifies the master override for all MC clocks */\n\tu32 mc_clken_override_allwarm_boot;\n\t/* Specifies digital dll period, choosing between 4 to 64 ms */\n\tu32 emc_cfg_dig_dll_period_warm_boot;\n\n\t/* Pad controls */\n\n\t/* Specifies the value for PMC_VDDP_SEL */\n\tu32 pmc_vddp_sel;\n\t/* Specifies the wait time after programming PMC_VDDP_SEL */\n\tu32 pmc_vddp_sel_wait;\n\t/* Specifies the value for PMC_DDR_PWR */\n\tu32 pmc_ddr_pwr;\n\t/* Specifies the value for PMC_DDR_CFG */\n\tu32 pmc_ddr_cfg;\n\t/* Specifies the value for PMC_IO_DPD3_REQ */\n\tu32 pmc_io_dpd3_req;\n\t/* Specifies the wait time after programming PMC_IO_DPD3_REQ */\n\tu32 pmc_io_dpd3_req_wait;\n\n\tu32 pmc_io_dpd4_req_wait;\n\n\t/* Specifies the value for PMC_REG_SHORT */\n\tu32 pmc_reg_short;\n\t/* Specifies the value for PMC_NO_IOPOWER */\n\tu32 pmc_no_io_power;\n\n\tu32 pmc_ddr_ctrl_wait;\n\tu32 pmc_ddr_ctrl;\n\n\t/* Specifies the value for EMC_ACPD_CONTROL */\n\tu32 emc_acpd_control;\n\n\t/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE0 */\n\tu32 emc_swizzle_rank0_byte0;\n\t/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE1 */\n\tu32 emc_swizzle_rank0_byte1;\n\t/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE2 */\n\tu32 emc_swizzle_rank0_byte2;\n\t/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE3 */\n\tu32 emc_swizzle_rank0_byte3;\n\t/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE0 */\n\tu32 emc_swizzle_rank1_byte0;\n\t/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE1 */\n\tu32 emc_swizzle_rank1_byte1;\n\t/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE2 */\n\tu32 emc_swizzle_rank1_byte2;\n\t/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE3 */\n\tu32 emc_swizzle_rank1_byte3;\n\n\t/* Specifies the value for EMC_TXDSRVTTGEN */\n\tu32 emc_txdsrvttgen;\n\n\t/* Specifies the value for EMC_DATA_BRLSHFT_0 */\n\tu32 emc_data_brlshft0;\n\tu32 emc_data_brlshft1;\n\n\tu32 emc_dqs_brlshft0;\n\tu32 emc_dqs_brlshft1;\n\n\tu32 emc_cmd_brlshft0;\n\tu32 emc_cmd_brlshft1;\n\tu32 emc_cmd_brlshft2;\n\tu32 emc_cmd_brlshft3;\n\n\tu32 emc_quse_brlshft0;\n\tu32 emc_quse_brlshft1;\n\tu32 emc_quse_brlshft2;\n\tu32 emc_quse_brlshft3;\n\n\tu32 emc_dll_cfg0;\n\tu32 emc_dll_cfg1;\n\n\tu32 emc_pmc_scratch1;\n\tu32 emc_pmc_scratch2;\n\tu32 emc_pmc_scratch3;\n\n\tu32 emc_pmacro_pad_cfg_ctrl;\n\n\tu32 emc_pmacro_vttgen_ctrl0;\n\tu32 emc_pmacro_vttgen_ctrl1;\n\tu32 emc_pmacro_vttgen_ctrl2;\n\n\tu32 emc_pmacro_brick_ctrl_rfu1;\n\tu32 emc_pmacro_cmd_brick_ctrl_fdpd;\n\tu32 emc_pmacro_brick_ctrl_rfu2;\n\tu32 emc_pmacro_data_brick_ctrl_fdpd;\n\tu32 emc_pmacro_bg_bias_ctrl0;\n\tu32 emc_pmacro_data_pad_rx_ctrl;\n\tu32 emc_pmacro_cmd_pad_rx_ctrl;\n\tu32 emc_pmacro_data_rx_term_mode;\n\tu32 emc_pmacro_cmd_rx_term_mode;\n\tu32 emc_pmacro_data_pad_tx_ctrl;\n\tu32 emc_pmacro_common_pad_tx_ctrl;\n\tu32 emc_pmacro_cmd_pad_tx_ctrl;\n\tu32 emc_cfg3;\n\n\tu32 emc_pmacro_tx_pwrd0;\n\tu32 emc_pmacro_tx_pwrd1;\n\tu32 emc_pmacro_tx_pwrd2;\n\tu32 emc_pmacro_tx_pwrd3;\n\tu32 emc_pmacro_tx_pwrd4;\n\tu32 emc_pmacro_tx_pwrd5;\n\n\tu32 emc_config_sample_delay;\n\n\tu32 emc_pmacro_brick_mapping0;\n\tu32 emc_pmacro_brick_mapping1;\n\tu32 emc_pmacro_brick_mapping2;\n\n\tu32 emc_pmacro_tx_sel_clk_src0;\n\tu32 emc_pmacro_tx_sel_clk_src1;\n\tu32 emc_pmacro_tx_sel_clk_src2;\n\tu32 emc_pmacro_tx_sel_clk_src3;\n\tu32 emc_pmacro_tx_sel_clk_src4;\n\tu32 emc_pmacro_tx_sel_clk_src5;\n\n\tu32 emc_pmacro_ddll_bypass;\n\n\tu32 emc_pmacro_ddll_pwrd0;\n\tu32 emc_pmacro_ddll_pwrd1;\n\tu32 emc_pmacro_ddll_pwrd2;\n\n\tu32 emc_pmacro_cmd_ctrl0;\n\tu32 emc_pmacro_cmd_ctrl1;\n\tu32 emc_pmacro_cmd_ctrl2;\n\n\t/* DRAM size information */\n\n\t/* Specifies the value for MC_EMEM_ADR_CFG */\n\tu32 mc_emem_adr_cfg;\n\t/* Specifies the value for MC_EMEM_ADR_CFG_DEV0 */\n\tu32 mc_emem_adr_cfg_dev0;\n\t/* Specifies the value for MC_EMEM_ADR_CFG_DEV1 */\n\tu32 mc_emem_adr_cfg_dev1;\n\n\tu32 mc_emem_adr_cfg_channel_mask;\n\n\t/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG0 */\n\tu32 mc_emem_adr_cfg_bank_mask0;\n\t/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG1 */\n\tu32 mc_emem_adr_cfg_bank_mask1;\n\t/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG2 */\n\tu32 mc_emem_adr_cfg_bank_mask2;\n\n\t/*\n\t * Specifies the value for MC_EMEM_CFG which holds the external memory\n\t * size (in KBytes)\n\t */\n\tu32 mc_emem_cfg;\n\n\t/* MC arbitration configuration */\n\n\t/* Specifies the value for MC_EMEM_ARB_CFG */\n\tu32 mc_emem_arb_cfg;\n\t/* Specifies the value for MC_EMEM_ARB_OUTSTANDING_REQ */\n\tu32 mc_emem_arb_outstanding_req;\n\n\tu32 emc_emem_arb_refpb_hp_ctrl;\n\tu32 emc_emem_arb_refpb_bank_ctrl;\n\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_RCD */\n\tu32 mc_emem_arb_timing_rcd;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_RP */\n\tu32 mc_emem_arb_timing_rp;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_RC */\n\tu32 mc_emem_arb_timing_rc;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_RAS */\n\tu32 mc_emem_arb_timing_ras;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_FAW */\n\tu32 mc_emem_arb_timing_faw;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_RRD */\n\tu32 mc_emem_arb_timing_rrd;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_RAP2PRE */\n\tu32 mc_emem_arb_timing_rap2pre;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_WAP2PRE */\n\tu32 mc_emem_arb_timing_wap2pre;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_R2R */\n\tu32 mc_emem_arb_timing_r2r;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_W2W */\n\tu32 mc_emem_arb_timing_w2w;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_R2W */\n\tu32 mc_emem_arb_timing_r2w;\n\t/* Specifies the value for MC_EMEM_ARB_TIMING_W2R */\n\tu32 mc_emem_arb_timing_w2r;\n\n\tu32 mc_emem_arb_timing_rfcpb;\n\n\t/* Specifies the value for MC_EMEM_ARB_DA_TURNS */\n\tu32 mc_emem_arb_da_turns;\n\t/* Specifies the value for MC_EMEM_ARB_DA_COVERS */\n\tu32 mc_emem_arb_da_covers;\n\t/* Specifies the value for MC_EMEM_ARB_MISC0 */\n\tu32 mc_emem_arb_misc0;\n\t/* Specifies the value for MC_EMEM_ARB_MISC1 */\n\tu32 mc_emem_arb_misc1;\n\tu32 mc_emem_arb_misc2;\n\n\t/* Specifies the value for MC_EMEM_ARB_RING1_THROTTLE */\n\tu32 mc_emem_arb_ring1_throttle;\n\t/* Specifies the value for MC_EMEM_ARB_OVERRIDE */\n\tu32 mc_emem_arb_override;\n\t/* Specifies the value for MC_EMEM_ARB_OVERRIDE_1 */\n\tu32 mc_emem_arb_override1;\n\t/* Specifies the value for MC_EMEM_ARB_RSV */\n\tu32 mc_emem_arb_rsv;\n\n\tu32 mc_da_cfg0;\n\tu32 mc_emem_arb_timing_ccdmw;\n\n\t/* Specifies the value for MC_CLKEN_OVERRIDE */\n\tu32 mc_clken_override;\n\n\t/* Specifies the value for MC_STAT_CONTROL */\n\tu32 mc_stat_control;\n\t/* Specifies the value for MC_VIDEO_PROTECT_BOM */\n\tu32 mc_video_protect_bom;\n\t/* Specifies the value for MC_VIDEO_PROTECT_BOM_ADR_HI */\n\tu32 mc_video_protect_bom_adr_hi;\n\t/* Specifies the value for MC_VIDEO_PROTECT_SIZE_MB */\n\tu32 mc_video_protect_size_mb;\n\t/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE */\n\tu32 mc_video_protect_vpr_override;\n\t/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE1 */\n\tu32 mc_video_protect_vpr_override1;\n\t/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_0 */\n\tu32 mc_video_protect_gpu_override0;\n\t/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_1 */\n\tu32 mc_video_protect_gpu_override1;\n\t/* Specifies the value for MC_SEC_CARVEOUT_BOM */\n\tu32 mc_sec_carveout_bom;\n\t/* Specifies the value for MC_SEC_CARVEOUT_ADR_HI */\n\tu32 mc_sec_carveout_adr_hi;\n\t/* Specifies the value for MC_SEC_CARVEOUT_SIZE_MB */\n\tu32 mc_sec_carveout_size_mb;\n\t/* Specifies the value for MC_VIDEO_PROTECT_REG_CTRL.VIDEO_PROTECT_WRITE_ACCESS */\n\tu32 mc_video_protect_write_access;\n\t/* Specifies the value for MC_SEC_CARVEOUT_REG_CTRL.SEC_CARVEOUT_WRITE_ACCESS */\n\tu32 mc_sec_carveout_protect_write_access;\n\n\tu32 mc_generalized_carveout1_bom;\n\tu32 mc_generalized_carveout1_bom_hi;\n\tu32 mc_generalized_carveout1_size_128kb;\n\tu32 mc_generalized_carveout1_access0;\n\tu32 mc_generalized_carveout1_access1;\n\tu32 mc_generalized_carveout1_access2;\n\tu32 mc_generalized_carveout1_access3;\n\tu32 mc_generalized_carveout1_access4;\n\tu32 mc_generalized_carveout1_force_internal_access0;\n\tu32 mc_generalized_carveout1_force_internal_access1;\n\tu32 mc_generalized_carveout1_force_internal_access2;\n\tu32 mc_generalized_carveout1_force_internal_access3;\n\tu32 mc_generalized_carveout1_force_internal_access4;\n\tu32 mc_generalized_carveout1_cfg0;\n\n\tu32 mc_generalized_carveout2_bom;\n\tu32 mc_generalized_carveout2_bom_hi;\n\tu32 mc_generalized_carveout2_size_128kb;\n\tu32 mc_generalized_carveout2_access0;\n\tu32 mc_generalized_carveout2_access1;\n\tu32 mc_generalized_carveout2_access2;\n\tu32 mc_generalized_carveout2_access3;\n\tu32 mc_generalized_carveout2_access4;\n\tu32 mc_generalized_carveout2_force_internal_access0;\n\tu32 mc_generalized_carveout2_force_internal_access1;\n\tu32 mc_generalized_carveout2_force_internal_access2;\n\tu32 mc_generalized_carveout2_force_internal_access3;\n\tu32 mc_generalized_carveout2_force_internal_access4;\n\tu32 mc_generalized_carveout2_cfg0;\n\n\tu32 mc_generalized_carveout3_bom;\n\tu32 mc_generalized_carveout3_bom_hi;\n\tu32 mc_generalized_carveout3_size_128kb;\n\tu32 mc_generalized_carveout3_access0;\n\tu32 mc_generalized_carveout3_access1;\n\tu32 mc_generalized_carveout3_access2;\n\tu32 mc_generalized_carveout3_access3;\n\tu32 mc_generalized_carveout3_access4;\n\tu32 mc_generalized_carveout3_force_internal_access0;\n\tu32 mc_generalized_carveout3_force_internal_access1;\n\tu32 mc_generalized_carveout3_force_internal_access2;\n\tu32 mc_generalized_carveout3_force_internal_access3;\n\tu32 mc_generalized_carveout3_force_internal_access4;\n\tu32 mc_generalized_carveout3_cfg0;\n\n\tu32 mc_generalized_carveout4_bom;\n\tu32 mc_generalized_carveout4_bom_hi;\n\tu32 mc_generalized_carveout4_size_128kb;\n\tu32 mc_generalized_carveout4_access0;\n\tu32 mc_generalized_carveout4_access1;\n\tu32 mc_generalized_carveout4_access2;\n\tu32 mc_generalized_carveout4_access3;\n\tu32 mc_generalized_carveout4_access4;\n\tu32 mc_generalized_carveout4_force_internal_access0;\n\tu32 mc_generalized_carveout4_force_internal_access1;\n\tu32 mc_generalized_carveout4_force_internal_access2;\n\tu32 mc_generalized_carveout4_force_internal_access3;\n\tu32 mc_generalized_carveout4_force_internal_access4;\n\tu32 mc_generalized_carveout4_cfg0;\n\n\tu32 mc_generalized_carveout5_bom;\n\tu32 mc_generalized_carveout5_bom_hi;\n\tu32 mc_generalized_carveout5_size_128kb;\n\tu32 mc_generalized_carveout5_access0;\n\tu32 mc_generalized_carveout5_access1;\n\tu32 mc_generalized_carveout5_access2;\n\tu32 mc_generalized_carveout5_access3;\n\tu32 mc_generalized_carveout5_access4;\n\tu32 mc_generalized_carveout5_force_internal_access0;\n\tu32 mc_generalized_carveout5_force_internal_access1;\n\tu32 mc_generalized_carveout5_force_internal_access2;\n\tu32 mc_generalized_carveout5_force_internal_access3;\n\tu32 mc_generalized_carveout5_force_internal_access4;\n\tu32 mc_generalized_carveout5_cfg0;\n\n\t/* Specifies enable for CA training */\n\tu32 emc_ca_training_enable;\n\t/* Set if bit 6 select is greater than bit 7 select; uses aremc.spec packet SWIZZLE_BIT6_GT_BIT7 */\n\tu32 swizzle_rank_byte_encode;\n\t/* Specifies enable and offset for patched boot rom write */\n\tu32 boot_rom_patch_control;\n\t/* Specifies data for patched boot rom write */\n\tu32 boot_rom_patch_data;\n\n\t/* Specifies the value for MC_MTS_CARVEOUT_BOM */\n\tu32 mc_mts_carveout_bom;\n\t/* Specifies the value for MC_MTS_CARVEOUT_ADR_HI */\n\tu32 mc_mts_carveout_adr_hi;\n\t/* Specifies the value for MC_MTS_CARVEOUT_SIZE_MB */\n\tu32 mc_mts_carveout_size_mb;\n\t/* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */\n\tu32 mc_mts_carveout_reg_ctrl;\n} sdram_params_t;\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/menu/gui/gui_menu.h",
    "content": "/*  \n * Copyright (c) 2018 Guillem96\n *\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef _MENU_H_\n#define _MENU_H_\n\n#include \"utils/types.h\"\n#include \"core/custom-gui.h\"\n#include \"core/argon-ctxt.h\"\n\n/* Handle all menu related stuff */\nvoid gui_menu_open(argon_ctxt_t* argon_ctxt);\n\n/* Handle all menu related stuff */\nvoid gui_menu_draw(argon_ctxt_t* argon_ctxt);\n\n/* Deallocate a menu from heap */\nvoid gui_menu_destroy(argon_ctxt_t* argon_ctxt);\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/menu/gui/gui_menu_controllers.h",
    "content": "#ifndef _GUI_MENU_CTRL_\n#define _GUI_MENU_CTRL_\n\n#include \"libs/lvgl/lvgl.h\"\n#include \"core/argon-ctxt.h\"\n\nargon_ctxt_t* g_argon_ctxt;\n\nvoid ctrl_reboot_rcm(lv_obj_t *obj, lv_event_t event);\nvoid ctrl_reboot_ofw(lv_obj_t *obj, lv_event_t event);\nvoid ctrl_power_off(lv_obj_t *obj, lv_event_t event);\nvoid ctrl_lauch_payload(lv_obj_t *obj, lv_event_t event);\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/menu/gui/gui_menu_pool.h",
    "content": "/*  \n * Copyright (c) 2018 Guillem96\n *\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef _GUI_MENU_POOL_H_\n#define _GUI_MENU_POOL_H_\n\n#include \"libs/lvgl/lvgl.h\"\n\ntypedef struct {\n    int max_items;\n    int current_items;\n    lv_obj_t** menus;\n} gui_menu_pool_t;\n\n\n/* Initializes the pool */\nvoid gui_menu_pool_init(gui_menu_pool_t* pool);\n\n/* Add a lv object to the pool */\nvoid gui_menu_pool_push(gui_menu_pool_t* pool, lv_obj_t* item);\n\n/* Deallocate all entries and menus */\nvoid gui_menu_pool_cleanup(gui_menu_pool_t* pool);\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/minerva/minerva.h",
    "content": "#ifndef _MINERVA_H_\n#define _MINERVA_H_\n\n#include \"mtc_table.h\"\n\n#include \"libs/lvgl/lvgl.h\"\n\ntypedef struct\n{\n\ts32 rate_to;\n\ts32 rate_from;\n\temc_table_t *mtc_table;\n\tu32 table_entries;\n\temc_table_t *current_emc_table;\n\tu32 train_mode;\n\tu32 sdram_id;\n\tu32 prev_temp;\n\tbool emc_2X_clk_src_is_pllmb;\n\tbool fsp_for_src_freq;\n\tbool train_ram_patterns;\n} mtc_config_t;\n\nenum train_mode_t\n{\n\tOP_SWITCH         = 0,\n\tOP_TRAIN          = 1,\n\tOP_TRAIN_SWITCH   = 2,\n\tOP_PERIODIC_TRAIN = 3,\n\tOP_TEMP_COMP      = 4\n};\n\ntypedef enum\n{\n\tFREQ_204  = 204000,\n\tFREQ_800  = 800000,\n\tFREQ_1600 = 1600000\n} minerva_freq_t;\n\n\nvoid (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);\nvoid minerva(mtc_config_t *mtc_cfg);\nvoid minerva_change_freq(mtc_config_t *mtc_cfg, minerva_freq_t freq);\nvoid minerva_periodic_training(lv_task_t * task);\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/minerva/mtc_table.h",
    "content": "/*\n * Minerva Training Cell\n * DRAM Training for Tegra X1 SoC. Supports DDR2/3 and LPDDR3/4.\n *\n * Copyright (c) 2018 CTCaer  <ctcaer@gmail.com>\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _MTC_TABLE_H_\n#define _MTC_TABLE_H_\n\n#include \"../utils/types.h\"\n\ntypedef struct \n{\n\ts32 pll_osc_in;\n\ts32 pll_out;\n\tu32 pll_feedback_div;\n\tu32 pll_input_div;\n\tu32 pll_post_div;\n} pllm_clk_config_t;\n\ntypedef struct\n{\n\tu32 emc_rc_idx;\n\tu32 emc_rfc_idx;\n\tu32 emc_rfcpb_idx;\n\tu32 emc_refctrl2_idx;\n\tu32 emc_rfc_slr_idx;\n\tu32 emc_ras_idx;\n\tu32 emc_rp_idx;\n\tu32 emc_r2w_idx;\n\tu32 emc_w2r_idx;\n\tu32 emc_r2p_idx;\n\tu32 emc_w2p_idx;\n\tu32 emc_r2r_idx;\n\tu32 emc_tppd_idx;\n\tu32 emc_ccdmw_idx;\n\tu32 emc_rd_rcd_idx;\n\tu32 emc_wr_rcd_idx;\n\tu32 emc_rrd_idx;\n\tu32 emc_rext_idx;\n\tu32 emc_wext_idx;\n\tu32 emc_wdv_chk_idx;\n\tu32 emc_wdv_idx;\n\tu32 emc_wsv_idx;\n\tu32 emc_wev_idx;\n\tu32 emc_wdv_mask_idx;\n\tu32 emc_ws_duration_idx;\n\tu32 emc_we_duration_idx;\n\tu32 emc_quse_idx;\n\tu32 emc_quse_width_idx;\n\tu32 emc_ibdly_idx;\n\tu32 emc_obdly_idx;\n\tu32 emc_einput_idx;\n\tu32 emc_mrw6_idx;\n\tu32 emc_einput_duration_idx;\n\tu32 emc_puterm_extra_idx;\n\tu32 emc_puterm_width_idx;\n\tu32 emc_qrst_idx;\n\tu32 emc_qsafe_idx;\n\tu32 emc_rdv_idx;\n\tu32 emc_rdv_mask_idx;\n\tu32 emc_rdv_early_idx;\n\tu32 emc_rdv_early_mask_idx;\n\tu32 emc_refresh_idx;\n\tu32 emc_burst_refresh_num_idx;\n\tu32 emc_pre_refresh_req_cnt_idx;\n\tu32 emc_pdex2wr_idx;\n\tu32 emc_pdex2rd_idx;\n\tu32 emc_pchg2pden_idx;\n\tu32 emc_act2pden_idx;\n\tu32 emc_ar2pden_idx;\n\tu32 emc_rw2pden_idx;\n\tu32 emc_cke2pden_idx;\n\tu32 emc_pdex2cke_idx;\n\tu32 emc_pdex2mrr_idx;\n\tu32 emc_txsr_idx;\n\tu32 emc_txsrdll_idx;\n\tu32 emc_tcke_idx;\n\tu32 emc_tckesr_idx;\n\tu32 emc_tpd_idx;\n\tu32 emc_tfaw_idx;\n\tu32 emc_trpab_idx;\n\tu32 emc_tclkstable_idx;\n\tu32 emc_tclkstop_idx;\n\tu32 emc_mrw7_idx;\n\tu32 emc_trefbw_idx;\n\tu32 emc_odt_write_idx;\n\tu32 emc_fbio_cfg5_idx;\n\tu32 emc_fbio_cfg7_idx;\n\tu32 emc_cfg_dig_dll_idx;\n\tu32 emc_cfg_dig_dll_period_idx;\n\tu32 emc_pmacro_ib_rxrt_idx;\n\tu32 emc_cfg_pipe_1_idx;\n\tu32 emc_cfg_pipe_2_idx;\n\tu32 emc_pmacro_quse_ddll_rank0_4_idx;\n\tu32 emc_pmacro_quse_ddll_rank0_5_idx;\n\tu32 emc_pmacro_quse_ddll_rank1_4_idx;\n\tu32 emc_pmacro_quse_ddll_rank1_5_idx;\n\tu32 emc_mrw8_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_4_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_5_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_0_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_1_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_2_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_3_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_4_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_5_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_0_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_1_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_2_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_3_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_4_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_5_idx;\n\tu32 emc_pmacro_ddll_long_cmd_0_idx;\n\tu32 emc_pmacro_ddll_long_cmd_1_idx;\n\tu32 emc_pmacro_ddll_long_cmd_2_idx;\n\tu32 emc_pmacro_ddll_long_cmd_3_idx;\n\tu32 emc_pmacro_ddll_long_cmd_4_idx;\n\tu32 emc_pmacro_ddll_short_cmd_0_idx;\n\tu32 emc_pmacro_ddll_short_cmd_1_idx;\n\tu32 emc_pmacro_ddll_short_cmd_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte0_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte1_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte2_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte3_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte4_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte5_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte6_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte7_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd0_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd1_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd2_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd3_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte0_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte1_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte2_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte3_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte4_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte5_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte6_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte7_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd0_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd0_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd0_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd0_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd1_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd1_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd1_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd1_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd2_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd2_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd2_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd2_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd3_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd3_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd3_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd3_3_idx;\n\tu32 emc_txdsrvttgen_idx;\n\tu32 emc_fdpd_ctrl_dq_idx;\n\tu32 emc_fdpd_ctrl_cmd_idx;\n\tu32 emc_fbio_spare_idx;\n\tu32 emc_zcal_interval_idx;\n\tu32 emc_zcal_wait_cnt_idx;\n\tu32 emc_mrs_wait_cnt_idx;\n\tu32 emc_mrs_wait_cnt2_idx;\n\tu32 emc_auto_cal_channel_idx;\n\tu32 emc_dll_cfg_0_idx;\n\tu32 emc_dll_cfg_1_idx;\n\tu32 emc_pmacro_autocal_cfg_common_idx;\n\tu32 emc_pmacro_zctrl_idx;\n\tu32 emc_cfg_idx;\n\tu32 emc_cfg_pipe_idx;\n\tu32 emc_dyn_self_ref_control_idx;\n\tu32 emc_qpop_idx;\n\tu32 emc_dqs_brlshft_0_idx;\n\tu32 emc_dqs_brlshft_1_idx;\n\tu32 emc_cmd_brlshft_2_idx;\n\tu32 emc_cmd_brlshft_3_idx;\n\tu32 emc_pmacro_pad_cfg_ctrl_idx;\n\tu32 emc_pmacro_data_pad_rx_ctrl_idx;\n\tu32 emc_pmacro_cmd_pad_rx_ctrl_idx;\n\tu32 emc_pmacro_data_rx_term_mode_idx;\n\tu32 emc_pmacro_cmd_rx_term_mode_idx;\n\tu32 emc_pmacro_cmd_pad_tx_ctrl_idx;\n\tu32 emc_pmacro_data_pad_tx_ctrl_idx;\n\tu32 emc_pmacro_common_pad_tx_ctrl_idx;\n\tu32 emc_pmacro_vttgen_ctrl_0_idx;\n\tu32 emc_pmacro_vttgen_ctrl_1_idx;\n\tu32 emc_pmacro_vttgen_ctrl_2_idx;\n\tu32 emc_pmacro_brick_ctrl_rfu1_idx;\n\tu32 emc_pmacro_cmd_brick_ctrl_fdpd_idx;\n\tu32 emc_pmacro_brick_ctrl_rfu2_idx;\n\tu32 emc_pmacro_data_brick_ctrl_fdpd_idx;\n\tu32 emc_pmacro_bg_bias_ctrl_0_idx;\n\tu32 emc_cfg_3_idx;\n\tu32 emc_pmacro_tx_pwrd_0_idx;\n\tu32 emc_pmacro_tx_pwrd_1_idx;\n\tu32 emc_pmacro_tx_pwrd_2_idx;\n\tu32 emc_pmacro_tx_pwrd_3_idx;\n\tu32 emc_pmacro_tx_pwrd_4_idx;\n\tu32 emc_pmacro_tx_pwrd_5_idx;\n\tu32 emc_config_sample_delay_idx;\n\tu32 emc_pmacro_tx_sel_clk_src_0_idx;\n\tu32 emc_pmacro_tx_sel_clk_src_1_idx;\n\tu32 emc_pmacro_tx_sel_clk_src_2_idx;\n\tu32 emc_pmacro_tx_sel_clk_src_3_idx;\n\tu32 emc_pmacro_tx_sel_clk_src_4_idx;\n\tu32 emc_pmacro_tx_sel_clk_src_5_idx;\n\tu32 emc_pmacro_ddll_bypass_idx;\n\tu32 emc_pmacro_ddll_pwrd_0_idx;\n\tu32 emc_pmacro_ddll_pwrd_1_idx;\n\tu32 emc_pmacro_ddll_pwrd_2_idx;\n\tu32 emc_pmacro_cmd_ctrl_0_idx;\n\tu32 emc_pmacro_cmd_ctrl_1_idx;\n\tu32 emc_pmacro_cmd_ctrl_2_idx;\n\tu32 emc_tr_timing_0_idx;\n\tu32 emc_tr_dvfs_idx;\n\tu32 emc_tr_ctrl_1_idx;\n\tu32 emc_tr_rdv_idx;\n\tu32 emc_tr_qpop_idx;\n\tu32 emc_tr_rdv_mask_idx;\n\tu32 emc_mrw14_idx;\n\tu32 emc_tr_qsafe_idx;\n\tu32 emc_tr_qrst_idx;\n\tu32 emc_training_ctrl_idx;\n\tu32 emc_training_settle_idx;\n\tu32 emc_training_vref_settle_idx;\n\tu32 emc_training_ca_fine_ctrl_idx;\n\tu32 emc_training_ca_ctrl_misc_idx;\n\tu32 emc_training_ca_ctrl_misc1_idx;\n\tu32 emc_training_ca_vref_ctrl_idx;\n\tu32 emc_training_quse_cors_ctrl_idx;\n\tu32 emc_training_quse_fine_ctrl_idx;\n\tu32 emc_training_quse_ctrl_misc_idx;\n\tu32 emc_training_quse_vref_ctrl_idx;\n\tu32 emc_training_read_fine_ctrl_idx;\n\tu32 emc_training_read_ctrl_misc_idx;\n\tu32 emc_training_read_vref_ctrl_idx;\n\tu32 emc_training_write_fine_ctrl_idx;\n\tu32 emc_training_write_ctrl_misc_idx;\n\tu32 emc_training_write_vref_ctrl_idx;\n\tu32 emc_training_mpc_idx;\n\tu32 emc_mrw15_idx;\n} burst_regs_t;\n\n\ntypedef struct \n{\n\tu32 burst_regs[221];\n\tu32 burst_reg_per_ch[8];\n\tu32 shadow_regs_ca_train[221];\n\tu32 shadow_regs_quse_train[221];\n\tu32 shadow_regs_rdwr_train[221];\n} burst_regs_table_t;\n\ntypedef struct \n{\n\tu32 ptfv_dqsosc_movavg_c0d0u0_idx;\n\tu32 ptfv_dqsosc_movavg_c0d0u1_idx;\n\tu32 ptfv_dqsosc_movavg_c0d1u0_idx;\n\tu32 ptfv_dqsosc_movavg_c0d1u1_idx;\n\tu32 ptfv_dqsosc_movavg_c1d0u0_idx;\n\tu32 ptfv_dqsosc_movavg_c1d0u1_idx;\n\tu32 ptfv_dqsosc_movavg_c1d1u0_idx;\n\tu32 ptfv_dqsosc_movavg_c1d1u1_idx;\n\tu32 ptfv_write_samples_idx;\n\tu32 ptfv_dvfs_samples_idx;\n\tu32 ptfv_movavg_weight_idx;\n\tu32 ptfv_config_ctrl_idx;\n} ptfv_list_table_t;\n\ntypedef struct\n{\n\tu32 emc0_mrw10_idx;\n\tu32 emc1_mrw10_idx;\n\tu32 emc0_mrw11_idx;\n\tu32 emc1_mrw11_idx;\n\tu32 emc0_mrw12_idx;\n\tu32 emc1_mrw12_idx;\n\tu32 emc0_mrw13_idx;\n\tu32 emc1_mrw13_idx;\n} burst_reg_per_ch_t;\n\ntypedef struct\n{\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank0_0_idx;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank0_1_idx;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank0_2_idx;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank0_3_idx;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank1_0_idx;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank1_1_idx;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank1_2_idx;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank1_3_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte0_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte0_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte0_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte1_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte1_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte1_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte2_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte2_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte2_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte3_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte3_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte3_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte4_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte4_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte4_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte5_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte5_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte5_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte6_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte6_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte6_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte7_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte7_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte7_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte0_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte0_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte0_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte1_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte1_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte1_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte2_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte2_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte2_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte3_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte3_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte3_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte4_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte4_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte4_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte5_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte5_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte5_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte6_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte6_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte6_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte7_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte7_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte7_2_idx;\n\tu32 emc_pmacro_ib_vref_dqs_0_idx;\n\tu32 emc_pmacro_ib_vref_dqs_1_idx;\n\tu32 emc_pmacro_ib_vref_dq_0_idx;\n\tu32 emc_pmacro_ib_vref_dq_1_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_0_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_1_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_2_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_3_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_4_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_5_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_0_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_1_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_2_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte0_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte0_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte0_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte1_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte1_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte1_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte2_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte2_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte2_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte3_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte3_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte3_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte4_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte4_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte4_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte5_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte5_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte5_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte6_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte6_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte6_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte7_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte7_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte7_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd0_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd0_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd0_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd1_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd1_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd1_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd2_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd2_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd2_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd3_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd3_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd3_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte0_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte0_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte0_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte1_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte1_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte1_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte2_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte2_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte2_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte3_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte3_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte3_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte4_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte4_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte4_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte5_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte5_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte5_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte6_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte6_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte6_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte7_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte7_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte7_2_idx;\n\tu32 emc_pmacro_quse_ddll_rank0_0_idx;\n\tu32 emc_pmacro_quse_ddll_rank0_1_idx;\n\tu32 emc_pmacro_quse_ddll_rank0_2_idx;\n\tu32 emc_pmacro_quse_ddll_rank0_3_idx;\n\tu32 emc_pmacro_quse_ddll_rank1_0_idx;\n\tu32 emc_pmacro_quse_ddll_rank1_1_idx;\n\tu32 emc_pmacro_quse_ddll_rank1_2_idx;\n\tu32 emc_pmacro_quse_ddll_rank1_3_idx;\n} trim_regs_t;\n\ntypedef struct\n{\n\tu32 emc_cmd_brlshft_0_idx;\n\tu32 emc_cmd_brlshft_1_idx;\n\tu32 emc0_data_brlshft_0_idx;\n\tu32 emc1_data_brlshft_0_idx;\n\tu32 emc0_data_brlshft_1_idx;\n\tu32 emc1_data_brlshft_1_idx;\n\tu32 emc_quse_brlshft_0_idx;\n\tu32 emc_quse_brlshft_1_idx;\n\tu32 emc_quse_brlshft_2_idx;\n\tu32 emc_quse_brlshft_3_idx;\n} trim_perch_regs_t;\n\ntypedef struct\n{\n\tu32 t_rp;\n\tu32 t_fc_lpddr4;\n\tu32 t_rfc;\n\tu32 t_pdex;\n\tu32 rl;\n} dram_timings_t;\n\ntypedef struct\n{\n\tu32 emc0_training_opt_dqs_ib_vref_rank0_idx;\n\tu32 emc1_training_opt_dqs_ib_vref_rank0_idx;\n\tu32 emc0_training_opt_dqs_ib_vref_rank1_idx;\n\tu32 emc1_training_opt_dqs_ib_vref_rank1_idx;\n} vref_perch_regs_t;\n\ntypedef struct\n{\n\tu32 trim_regs[138];\n\tu32 trim_perch_regs[10];\n\tu32 vref_perch_regs[4];\n} trim_regs_table_t;\n\ntypedef struct\n{\n\tu32 rev;\n\tchar dvfs_ver[60];\n\tu32 rate_khz;\n\tu32 min_volt;\n\tu32 gpu_min_volt;\n\tchar clock_src[32];\n\tu32 clk_src_emc;\n\tu32 needs_training;\n\tu32 training_pattern;\n\tu32 trained;\n\tu32 periodic_training;\n\tu32 trained_dram_clktree_c0d0u0;\n\tu32 trained_dram_clktree_c0d0u1;\n\tu32 trained_dram_clktree_c0d1u0;\n\tu32 trained_dram_clktree_c0d1u1;\n\tu32 trained_dram_clktree_c1d0u0;\n\tu32 trained_dram_clktree_c1d0u1;\n\tu32 trained_dram_clktree_c1d1u0;\n\tu32 trained_dram_clktree_c1d1u1;\n\tu32 current_dram_clktree_c0d0u0;\n\tu32 current_dram_clktree_c0d0u1;\n\tu32 current_dram_clktree_c0d1u0;\n\tu32 current_dram_clktree_c0d1u1;\n\tu32 current_dram_clktree_c1d0u0;\n\tu32 current_dram_clktree_c1d0u1;\n\tu32 current_dram_clktree_c1d1u0;\n\tu32 current_dram_clktree_c1d1u1;\n\tu32 run_clocks;\n\tu32 tree_margin;\n\tu32 num_burst;\n\tu32 num_burst_per_ch;\n\tu32 num_trim;\n\tu32 num_trim_per_ch;\n\tu32 num_mc_regs;\n\tu32 num_up_down;\n\tu32 vref_num;\n\tu32 training_mod_num;\n\tu32 dram_timing_num;\n\n\tptfv_list_table_t ptfv_list;\n\n\tburst_regs_t burst_regs;\n\tburst_reg_per_ch_t burst_reg_per_ch;\n\tburst_regs_t shadow_regs_ca_train;\n\tburst_regs_t shadow_regs_quse_train;\n\tburst_regs_t shadow_regs_rdwr_train;\n\ttrim_regs_t trim_regs;\n\ttrim_perch_regs_t trim_perch_regs;\n\tvref_perch_regs_t vref_perch_regs;\n\tdram_timings_t dram_timings;\n\n\tu32 training_mod_regs[20];\n\tu32 save_restore_mod_regs[12];\n\tu32 burst_mc_regs[33];\n\tu32 la_scale_regs[24];\n\n\tu32 min_mrs_wait;\n\tu32 emc_mrw;\n\tu32 emc_mrw2;\n\tu32 emc_mrw3;\n\tu32 emc_mrw4;\n\tu32 emc_mrw9;\n\tu32 emc_mrs;\n\tu32 emc_emrs;\n\tu32 emc_emrs2;\n\tu32 emc_auto_cal_config;\n\tu32 emc_auto_cal_config2;\n\tu32 emc_auto_cal_config3;\n\tu32 emc_auto_cal_config4;\n\tu32 emc_auto_cal_config5;\n\tu32 emc_auto_cal_config6;\n\tu32 emc_auto_cal_config7;\n\tu32 emc_auto_cal_config8;\n\tu32 emc_cfg_2;\n\tu32 emc_sel_dpd_ctrl;\n\tu32 emc_fdpd_ctrl_cmd_no_ramp;\n\tu32 dll_clk_src;\n\tu32 clk_out_enb_x_0_clk_enb_emc_dll;\n\tu32 latency;\n} emc_table_t;\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/power/battery.h",
    "content": "/*\n * Battery charger driver for Nintendo Switch's TI BQ24193\n *\n * Copyright (C) 2019 Guillem96\n * \n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"utils/types.h\"\n\n#ifndef _BATTERY_H_\n#define _BATTERY_H_\n\ntypedef enum \n{\n    NOT_CHARGING,\n    CHARGING,\n    FAST_CHARGING,\n    TERMINATED,\n    UNKNOWN,\n} charge_status_t;\n\ntypedef struct {\n    charge_status_t charge_status;\n    u32 percent;\n} battery_status_t;\n\nvoid battery_get_status(battery_status_t* battery_status);\ncharge_status_t battery_charge_status();\nconst char* battery_str_charge_status(charge_status_t);\nvoid battery_percent(int*);\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/power/bq24193.h",
    "content": "/*\n * Battery charger driver for Nintendo Switch's TI BQ24193\n *\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef __BQ24193_H_\n#define __BQ24193_H_\n\n#define BQ24193_I2C_ADDR 0x6B\n\n// REG 0 masks.\n#define BQ24193_INCONFIG_INLIMIT_MASK (7<<0)\n#define BQ24193_INCONFIG_VINDPM_MASK   0x78\n#define BQ24193_INCONFIG_HIZ_EN_MASK  (1<<7)\n\n// REG 1 masks.\n#define BQ24193_PORCONFIG_BOOST_MASK       (1<<0)\n#define BQ24193_PORCONFIG_SYSMIN_MASK      (7<<1)\n#define BQ24193_PORCONFIG_CHGCONFIG_MASK   (3<<4)\n#define BQ24193_PORCONFIG_I2CWATCHDOG_MASK (1<<6)\n#define BQ24193_PORCONFIG_RESET_MASK       (1<<7)\n\n// REG 2 masks.\n#define BQ24193_CHRGCURR_20PCT_MASK (1<<0)\n#define BQ24193_CHRGCURR_ICHG_MASK   0xFC\n\n// REG 3 masks.\n#define BQ24193_PRECHRG_ITERM   0x0F\n#define BQ24193_PRECHRG_IPRECHG 0xF0\n\n// REG 4 masks.\n#define BQ24193_CHRGVOLT_VTHRES  (1<<0)\n#define BQ24193_CHRGVOLT_BATTLOW (1<<1)\n#define BQ24193_CHRGVOLT_VREG     0xFC\n\n// REG 5 masks.\n#define BQ24193_CHRGTERM_ISET_MASK     (1<<0)\n#define BQ24193_CHRGTERM_CHGTIMER_MASK (3<<1)\n#define BQ24193_CHRGTERM_ENTIMER_MASK  (1<<3)\n#define BQ24193_CHRGTERM_WATCHDOG_MASK (3<<4)\n#define BQ24193_CHRGTERM_TERM_ST_MASK  (1<<6)\n#define BQ24193_CHRGTERM_TERM_EN_MASK  (1<<7)\n\n// REG 6 masks.\n#define BQ24193_IRTHERMAL_THERM_MASK    (3<<0)\n#define BQ24193_IRTHERMAL_VCLAMP_MASK   (7<<2)\n#define BQ24193_IRTHERMAL_BATTCOMP_MASK (7<<5)\n\n// REG 7 masks.\n#define BQ24193_MISC_INT_MASK       (3<<0)\n#define BQ24193_MISC_VSET_MASK      (1<<4)\n#define BQ24193_MISC_BATFET_DI_MASK (1<<5)\n#define BQ24193_MISC_TMR2X_EN_MASK  (1<<6)\n#define BQ24193_MISC_DPDM_EN_MASK   (1<<7)\n\n// REG 8 masks.\n#define BQ24193_STATUS_VSYS_MASK  (1<<0)\n#define BQ24193_STATUS_THERM_MASK (1<<1)\n#define BQ24193_STATUS_PG_MASK    (1<<2)\n#define BQ24193_STATUS_DPM_MASK   (1<<3)\n#define BQ24193_STATUS_CHRG_MASK  (3<<4)\n#define BQ24193_STATUS_VBUS_MASK  (3<<6)\n\n// REG 9 masks.\n#define BQ24193_FAULT_THERM_MASK    (7<<0)\n#define BQ24193_FAULT_BATT_OVP_MASK (1<<3)\n#define BQ24193_FAULT_CHARGE_MASK   (3<<4)\n#define BQ24193_FAULT_BOOST_MASK    (1<<6)\n#define BQ24193_FAULT_WATCHDOG_MASK (1<<7)\n\n// REG A masks.\n#define BQ24193_VENDORPART_DEV_MASK (3<<0)\n#define BQ24193_VENDORPART_PN_MASK  (7<<3)\n\nenum BQ24193_reg {\n\tBQ24193_InputSource     = 0x00,\n\tBQ24193_PORConfig       = 0x01,\n\tBQ24193_ChrgCurr        = 0x02,\n\tBQ24193_PreChrgTerm     = 0x03,\n\tBQ24193_ChrgVolt        = 0x04,\n\tBQ24193_ChrgTermTimer   = 0x05,\n\tBQ24193_IRCompThermal   = 0x06,\n\tBQ24193_Misc            = 0x07,\n\tBQ24193_Status          = 0x08,\n\tBQ24193_FaultReg        = 0x09,\n\tBQ24193_VendorPart      = 0x0A,\n};\n\nenum BQ24193_reg_prop {\n\tBQ24193_InputVoltageLimit,      // REG 0.\n\tBQ24193_InputCurrentLimit,      // REG 0.\n\tBQ24193_SystemMinimumVoltage,   // REG 1.\n\tBQ24193_FastChargeCurrentLimit, // REG 2.\n\tBQ24193_ChargeVoltageLimit,     // REG 4.\n\tBQ24193_RechargeThreshold,      // REG 4.\n\tBQ24193_ThermalRegulation,      // REG 6.\n\tBQ24193_ChargeStatus,           // REG 8.\n\tBQ24193_TempStatus,             // REG 9.\n\tBQ24193_DevID,                  // REG A.\n\tBQ24193_ProductNumber,          // REG A.\n};\n\nint bq24193_get_property(enum BQ24193_reg_prop prop, int *value);\nvoid bq24193_fake_battery_removal();\n\n#endif /* __BQ24193_H_ */"
  },
  {
    "path": "argon-nx-gui/include/power/max17050.h",
    "content": "/*\n * Fuel gauge driver for Nintendo Switch's Maxim 17050\n *  Note that Maxim 8966 and 8997 are mfd and this is its subdevice.\n *\n * Copyright (C) 2011 Samsung Electronics\n * MyungJoo Ham <myungjoo.ham@samsung.com>\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\n#ifndef __MAX17050_H_\n#define __MAX17050_H_\n\n#define MAX17050_STATUS_BattAbsent    (1 << 3)\n#define MAX17050_DEFAULT_SNS_RESISTOR 10000\n\n/* Consider RepCap which is less then 10 units below FullCAP full */\n#define MAX17050_FULL_THRESHOLD 10\n\n#define MAX17050_CHARACTERIZATION_DATA_SIZE 48\n\n#define MAXIM17050_I2C_ADDR 0x36\n\nenum MAX17050_reg {\n\tMAX17050_STATUS\t\t= 0x00,\n\tMAX17050_VALRT_Th\t= 0x01,\n\tMAX17050_TALRT_Th\t= 0x02,\n\tMAX17050_SALRT_Th\t= 0x03,\n\tMAX17050_AtRate\t\t= 0x04,\n\tMAX17050_RepCap\t\t= 0x05,\n\tMAX17050_RepSOC\t\t= 0x06,\n\tMAX17050_Age\t\t= 0x07,\n\tMAX17050_TEMP\t\t= 0x08,\n\tMAX17050_VCELL\t\t= 0x09,\n\tMAX17050_Current\t= 0x0A,\n\tMAX17050_AvgCurrent\t= 0x0B,\n\n\tMAX17050_SOC\t\t= 0x0D,\n\tMAX17050_AvSOC\t\t= 0x0E,\n\tMAX17050_RemCap\t\t= 0x0F,\n\tMAX17050_FullCAP\t= 0x10,\n\tMAX17050_TTE\t\t= 0x11,\n\tMAX17050_QRTbl00\t= 0x12,\n\tMAX17050_FullSOCThr\t= 0x13,\n\tMAX17050_RSLOW\t\t= 0x14,\n\n\tMAX17050_AvgTA\t\t= 0x16,\n\tMAX17050_Cycles\t\t= 0x17,\n\tMAX17050_DesignCap\t= 0x18,\n\tMAX17050_AvgVCELL\t= 0x19,\n\tMAX17050_MinMaxTemp\t= 0x1A,\n\tMAX17050_MinMaxVolt\t= 0x1B,\n\tMAX17050_MinMaxCurr\t= 0x1C,\n\tMAX17050_CONFIG\t\t= 0x1D,\n\tMAX17050_ICHGTerm\t= 0x1E,\n\tMAX17050_AvCap\t\t= 0x1F,\n\tMAX17050_ManName\t= 0x20,\n\tMAX17050_DevName\t= 0x21,\n\tMAX17050_QRTbl10\t= 0x22,\n\tMAX17050_FullCAPNom\t= 0x23,\n\tMAX17050_TempNom\t= 0x24,\n\tMAX17050_TempLim\t= 0x25,\n\tMAX17050_TempHot\t= 0x26,\n\tMAX17050_AIN\t\t= 0x27,\n\tMAX17050_LearnCFG\t= 0x28,\n\tMAX17050_FilterCFG\t= 0x29,\n\tMAX17050_RelaxCFG\t= 0x2A,\n\tMAX17050_MiscCFG\t= 0x2B,\n\tMAX17050_TGAIN\t\t= 0x2C,\n\tMAX17050_TOFF\t\t= 0x2D,\n\tMAX17050_CGAIN\t\t= 0x2E,\n\tMAX17050_COFF\t\t= 0x2F,\n\n\tMAX17050_QRTbl20\t= 0x32,\n\tMAX17050_SOC_empty\t= 0x33,\n\tMAX17050_T_empty\t= 0x34,\n\tMAX17050_FullCAP0\t= 0x35,\n\tMAX17050_LAvg_empty\t= 0x36,\n\tMAX17050_FCTC\t\t= 0x37,\n\tMAX17050_RCOMP0\t\t= 0x38,\n\tMAX17050_TempCo\t\t= 0x39,\n\tMAX17050_V_empty\t= 0x3A,\n\tMAX17050_K_empty0\t= 0x3B,\n\tMAX17050_TaskPeriod\t= 0x3C,\n\tMAX17050_FSTAT\t\t= 0x3D,\n\n\tMAX17050_SHDNTIMER\t= 0x3F,\n\tMAX17050_QRTbl30\t= 0x42,\n\tMAX17050_dQacc\t\t= 0x45,\n\tMAX17050_dPacc\t\t= 0x46,\n\n\tMAX17050_VFSOC0\t\t= 0x48,\n\n\tMAX17050_QH\t\t\t= 0x4D,\n\tMAX17050_QL\t\t\t= 0x4E,\n\n\tMAX17050_MinVolt\t= 0x50, // Custom ID. Not to be sent to i2c.\n\tMAX17050_MaxVolt\t= 0x51, // Custom ID. Not to be sent to i2c.\n\n\tMAX17050_VFSOC0Enable\t= 0x60,\n\n\tMAX17050_MODELChrTbl\t= 0x80,\n\n\tMAX17050_OCV\t\t\t= 0xEE,\n\n\tMAX17050_OCVInternal\t= 0xFB,\n\n\tMAX17050_VFSOC\t\t\t= 0xFF,\n};\n\nint max17050_get_property(enum MAX17050_reg reg, int *value);\nint max17050_fix_configuration();\n\n#endif /* __MAX17050_H_ */\n"
  },
  {
    "path": "argon-nx-gui/include/power/max77620.h",
    "content": "/*\n * Defining registers address and its bit definitions of MAX77620 and MAX20024\n *\n * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n */\n#ifndef _MFD_MAX77620_H_\n#define _MFD_MAX77620_H_\n\n#define MAX77620_I2C_ADDR 0x3C\n\n/* GLOBAL, PMIC, GPIO, FPS, ONOFFC, CID Registers */\n#define MAX77620_REG_CNFGGLBL1      0x00\n#define  MAX77620_CNFGGLBL1_LBDAC_EN          (1 << 7)\n#define  MAX77620_CNFGGLBL1_MPPLD             (1 << 6)\n#define  MAX77620_CNFGGLBL1_LBHYST            ((1 << 5) | (1 << 4))\n#define  MAX77620_CNFGGLBL1_LBHYST_N          (1 << 4)\n#define  MAX77620_CNFGGLBL1_LBDAC             0x0E\n#define  MAX77620_CNFGGLBL1_LBDAC_N           (1 << 1)\n#define  MAX77620_CNFGGLBL1_LBRSTEN           (1 << 0)\n\n#define MAX77620_REG_CNFGGLBL2      0x01\n#define MAX77620_REG_CNFGGLBL3      0x02\n#define  MAX77620_WDTC_MASK                   0x3\n#define  MAX77620_WDTOFFC                     (1 << 4)\n#define  MAX77620_WDTSLPC                     (1 << 3)\n#define  MAX77620_WDTEN                       (1 << 2)\n#define  MAX77620_TWD_MASK                    0x3\n#define  MAX77620_TWD_2s                      0x0\n#define  MAX77620_TWD_16s                     0x1\n#define  MAX77620_TWD_64s                     0x2\n#define  MAX77620_TWD_128s                    0x3\n\n#define MAX77620_REG_CNFG1_32K      0x03\n#define  MAX77620_CNFG1_32K_OUT0_EN           (1 << 2)\n\n#define MAX77620_REG_CNFGBBC        0x04\n#define  MAX77620_CNFGBBC_ENABLE              (1 << 0)\n#define  MAX77620_CNFGBBC_CURRENT_MASK        0x06\n#define  MAX77620_CNFGBBC_CURRENT_SHIFT       1\n#define  MAX77620_CNFGBBC_VOLTAGE_MASK        0x18\n#define  MAX77620_CNFGBBC_VOLTAGE_SHIFT       3\n#define  MAX77620_CNFGBBC_LOW_CURRENT_DISABLE (1 << 5)\n#define  MAX77620_CNFGBBC_RESISTOR_MASK       0xC0\n#define  MAX77620_CNFGBBC_RESISTOR_SHIFT      6\n#define  MAX77620_CNFGBBC_RESISTOR_100        (0 << MAX77620_CNFGBBC_RESISTOR_SHIFT)\n#define  MAX77620_CNFGBBC_RESISTOR_1K         (1 << MAX77620_CNFGBBC_RESISTOR_SHIFT)\n#define  MAX77620_CNFGBBC_RESISTOR_3K         (2 << MAX77620_CNFGBBC_RESISTOR_SHIFT)\n#define  MAX77620_CNFGBBC_RESISTOR_6K         (3 << MAX77620_CNFGBBC_RESISTOR_SHIFT)\n\n#define MAX77620_REG_IRQTOP         0x05\n#define  MAX77620_IRQ_TOP_GLBL_MASK           (1 << 7)\n#define  MAX77620_IRQ_TOP_SD_MASK             (1 << 6)\n#define  MAX77620_IRQ_TOP_LDO_MASK            (1 << 5)\n#define  MAX77620_IRQ_TOP_GPIO_MASK           (1 << 4)\n#define  MAX77620_IRQ_TOP_RTC_MASK            (1 << 3)\n#define  MAX77620_IRQ_TOP_32K_MASK            (1 << 2)\n#define  MAX77620_IRQ_TOP_ONOFF_MASK          (1 << 1)\n\n#define MAX77620_REG_INTLBT         0x06\n#define MAX77620_REG_IRQTOPM        0x0D\n#define  MAX77620_IRQ_LBM_MASK                (1 << 3)\n#define  MAX77620_IRQ_TJALRM1_MASK            (1 << 2)\n#define  MAX77620_IRQ_TJALRM2_MASK            (1 << 1)\n\n#define MAX77620_REG_IRQSD          0x07\n#define MAX77620_REG_IRQ_LVL2_L0_7  0x08\n#define MAX77620_REG_IRQ_LVL2_L8    0x09\n#define MAX77620_REG_IRQ_LVL2_GPIO  0x0A\n#define MAX77620_REG_ONOFFIRQ       0x0B\n#define MAX77620_REG_NVERC          0x0C\n\n#define MAX77620_REG_INTENLBT       0x0E\n#define  MAX77620_GLBLM_MASK                  (1 << 0)\n\n#define MAX77620_REG_IRQMASKSD      0x0F\n#define MAX77620_REG_IRQ_MSK_L0_7   0x10\n#define MAX77620_REG_IRQ_MSK_L8     0x11\n#define MAX77620_REG_ONOFFIRQM      0x12\n#define MAX77620_REG_STATLBT        0x13\n#define MAX77620_REG_STATSD         0x14\n#define MAX77620_REG_ONOFFSTAT      0x15\n\n/* SD and LDO Registers */\n#define MAX77620_REG_SD0            0x16\n#define MAX77620_REG_SD1            0x17\n#define MAX77620_REG_SD2            0x18\n#define MAX77620_REG_SD3            0x19\n#define MAX77620_REG_SD4            0x1A\n#define  MAX77620_SDX_VOLT_MASK               0xFF\n#define  MAX77620_SD0_VOLT_MASK               0x3F\n#define  MAX77620_SD1_VOLT_MASK               0x7F\n#define  MAX77620_LDO_VOLT_MASK               0x3F\n#define MAX77620_REG_DVSSD0         0x1B\n#define MAX77620_REG_DVSSD1         0x1C\n#define MAX77620_REG_SD0_CFG        0x1D\n#define MAX77620_REG_SD1_CFG        0x1E\n#define MAX77620_REG_SD2_CFG        0x1F\n#define MAX77620_REG_SD3_CFG        0x20\n#define MAX77620_REG_SD4_CFG        0x21\n#define MAX77620_REG_SD_CFG2        0x22\n#define MAX77620_REG_LDO0_CFG       0x23\n#define MAX77620_REG_LDO0_CFG2      0x24\n#define MAX77620_REG_LDO1_CFG       0x25\n#define MAX77620_REG_LDO1_CFG2      0x26\n#define MAX77620_REG_LDO2_CFG       0x27\n#define MAX77620_REG_LDO2_CFG2      0x28\n#define MAX77620_REG_LDO3_CFG       0x29\n#define MAX77620_REG_LDO3_CFG2      0x2A\n#define MAX77620_REG_LDO4_CFG       0x2B\n#define MAX77620_REG_LDO4_CFG2      0x2C\n#define MAX77620_REG_LDO5_CFG       0x2D\n#define MAX77620_REG_LDO5_CFG2      0x2E\n#define MAX77620_REG_LDO6_CFG       0x2F\n#define MAX77620_REG_LDO6_CFG2      0x30\n#define MAX77620_REG_LDO7_CFG       0x31\n#define MAX77620_REG_LDO7_CFG2      0x32\n#define MAX77620_REG_LDO8_CFG       0x33\n#define MAX77620_REG_LDO8_CFG2      0x34\n#define  MAX77620_LDO_POWER_MODE_MASK         0xC0\n#define  MAX77620_LDO_POWER_MODE_SHIFT        6\n#define  MAX77620_POWER_MODE_NORMAL\t          3\n#define  MAX77620_POWER_MODE_LPM              2\n#define  MAX77620_POWER_MODE_GLPM             1\n#define  MAX77620_POWER_MODE_DISABLE          0\n#define  MAX20024_LDO_CFG2_MPOK_MASK          (1 << 2)\n#define  MAX77620_LDO_CFG2_ADE_MASK           (1 << 1)\n#define  MAX77620_LDO_CFG2_ADE_DISABLE        0\n#define  MAX77620_LDO_CFG2_ADE_ENABLE         (1 << 1)\n#define  MAX77620_LDO_CFG2_SS_MASK            (1 << 0)\n#define  MAX77620_LDO_CFG2_SS_FAST            (1 << 0)\n#define  MAX77620_LDO_CFG2_SS_SLOW            0\n\n#define MAX77620_REG_LDO_CFG3       0x35\n#define  MAX77620_TRACK4_MASK                 (1 << 5)\n#define  MAX77620_TRACK4_SHIFT                5\n\n#define MAX77620_LDO_SLEW_RATE_MASK 0x1\n\n#define MAX77620_REG_GPIO0          0x36\n#define MAX77620_REG_GPIO1          0x37\n#define MAX77620_REG_GPIO2          0x38\n#define MAX77620_REG_GPIO3          0x39\n#define MAX77620_REG_GPIO4          0x3A\n#define MAX77620_REG_GPIO5          0x3B\n#define MAX77620_REG_GPIO6          0x3C\n#define MAX77620_REG_GPIO7          0x3D\n#define MAX77620_REG_PUE_GPIO       0x3E\n#define MAX77620_REG_PDE_GPIO       0x3F\n#define MAX77620_REG_AME_GPIO       0x40\n\n#define MAX77620_REG_ONOFFCNFG1     0x41\n#define  MAX77620_ONOFFCNFG1_SFT_RST          (1 << 7)\n#define  MAX77620_ONOFFCNFG1_MRT_MASK         0x38\n#define  MAX77620_ONOFFCNFG1_MRT_SHIFT        0x3\n#define  MAX77620_ONOFFCNFG1_SLPEN            (1 << 2)\n#define  MAX77620_ONOFFCNFG1_PWR_OFF          (1 << 1)\n#define  MAX20024_ONOFFCNFG1_CLRSE            0x18\n\n#define MAX77620_REG_ONOFFCNFG2     0x42\n#define  MAX77620_ONOFFCNFG2_SFT_RST_WK       (1 << 7)\n#define  MAX77620_ONOFFCNFG2_WD_RST_WK        (1 << 6)\n#define  MAX77620_ONOFFCNFG2_SLP_LPM_MSK      (1 << 5)\n#define  MAX77620_ONOFFCNFG2_WK_ALARM1        (1 << 2)\n#define  MAX77620_ONOFFCNFG2_WK_EN0           (1 << 0)\n\n/* FPS Registers */\n#define MAX77620_REG_FPS_CFG0       0x43\n#define MAX77620_REG_FPS_CFG1       0x44\n#define MAX77620_REG_FPS_CFG2       0x45\n#define MAX77620_REG_FPS_LDO0       0x46\n#define MAX77620_REG_FPS_LDO1       0x47\n#define MAX77620_REG_FPS_LDO2       0x48\n#define MAX77620_REG_FPS_LDO3       0x49\n#define MAX77620_REG_FPS_LDO4       0x4A\n#define MAX77620_REG_FPS_LDO5       0x4B\n#define MAX77620_REG_FPS_LDO6       0x4C\n#define MAX77620_REG_FPS_LDO7       0x4D\n#define MAX77620_REG_FPS_LDO8       0x4E\n#define MAX77620_REG_FPS_SD0        0x4F\n#define MAX77620_REG_FPS_SD1        0x50\n#define MAX77620_REG_FPS_SD2        0x51\n#define MAX77620_REG_FPS_SD3        0x52\n#define MAX77620_REG_FPS_SD4        0x53\n#define MAX77620_REG_FPS_NONE       0\n#define  MAX77620_FPS_SRC_MASK                0xC0\n#define  MAX77620_FPS_SRC_SHIFT               6\n#define  MAX77620_FPS_PU_PERIOD_MASK          0x38\n#define  MAX77620_FPS_PU_PERIOD_SHIFT         3\n#define  MAX77620_FPS_PD_PERIOD_MASK          0x07\n#define  MAX77620_FPS_PD_PERIOD_SHIFT         0\n\n/* Minimum and maximum FPS period time (in microseconds) are\n * different for MAX77620 and Max20024.\n */\n#define MAX77620_FPS_COUNT 3\n\n#define MAX77620_FPS_PERIOD_MIN_US 40\n#define MAX20024_FPS_PERIOD_MIN_US 20\n\n#define MAX77620_FPS_PERIOD_MAX_US 2560\n#define MAX20024_FPS_PERIOD_MAX_US 5120\n\n#define MAX77620_REG_FPS_GPIO1      0x54\n#define MAX77620_REG_FPS_GPIO2      0x55\n#define MAX77620_REG_FPS_GPIO3      0x56\n#define  MAX77620_FPS_TIME_PERIOD_MASK        0x38\n#define  MAX77620_FPS_TIME_PERIOD_SHIFT       3\n#define  MAX77620_FPS_EN_SRC_MASK             0x06\n#define  MAX77620_FPS_EN_SRC_SHIFT            1\n#define  MAX77620_FPS_ENFPS_SW_MASK           0x01\n#define  MAX77620_FPS_ENFPS_SW                0x01\n\n#define MAX77620_REG_FPS_RSO        0x57\n#define MAX77620_REG_CID0           0x58\n#define MAX77620_REG_CID1           0x59\n#define MAX77620_REG_CID2           0x5A\n#define MAX77620_REG_CID3           0x5B\n#define MAX77620_REG_CID4           0x5C\n#define MAX77620_REG_CID5           0x5D\n\n#define MAX77620_REG_DVSSD4         0x5E\n#define MAX20024_REG_MAX_ADD        0x70\n\n#define MAX77620_CID_DIDM_MASK                0xF0\n#define MAX77620_CID_DIDM_SHIFT               4\n\n/* CNCG2SD */\n#define MAX77620_SD_CNF2_ROVS_EN_SD1          (1 << 1)\n#define MAX77620_SD_CNF2_ROVS_EN_SD0          (1 << 2)\n\n/* Device Identification Metal */\n#define MAX77620_CID5_DIDM(n) (((n) >> 4) & 0xF)\n/* Device Indentification OTP */\n#define MAX77620_CID5_DIDO(n) ((n) & 0xF)\n\n/* SD CNFG1 */\n#define MAX77620_SD_SR_MASK                   0xC0\n#define MAX77620_SD_SR_SHIFT                  6\n#define MAX77620_SD_POWER_MODE_MASK           0x30\n#define MAX77620_SD_POWER_MODE_SHIFT          4\n#define MAX77620_SD_CFG1_ADE_MASK             (1 << 3)\n#define MAX77620_SD_CFG1_ADE_DISABLE          0\n#define MAX77620_SD_CFG1_ADE_ENABLE           (1 << 3)\n#define MAX77620_SD_FPWM_MASK                 0x04\n#define MAX77620_SD_FPWM_SHIFT                2\n#define MAX77620_SD_FSRADE_MASK               0x01\n#define MAX77620_SD_FSRADE_SHIFT              0\n#define MAX77620_SD_CFG1_FPWM_SD_MASK         (1 << 2)\n#define MAX77620_SD_CFG1_FPWM_SD_SKIP         0\n#define MAX77620_SD_CFG1_FPWM_SD_FPWM         (1 << 2)\n#define MAX20024_SD_CFG1_MPOK_MASK            (1 << 1)\n#define MAX77620_SD_CFG1_FSRADE_SD_MASK       (1 << 0)\n#define MAX77620_SD_CFG1_FSRADE_SD_DISABLE    0\n#define MAX77620_SD_CFG1_FSRADE_SD_ENABLE     (1 << 0)\n\n#define MAX77620_CNFG_GPIO_DRV_MASK           (1 << 0)\n#define MAX77620_CNFG_GPIO_DRV_PUSHPULL       (1 << 0)\n#define MAX77620_CNFG_GPIO_DRV_OPENDRAIN      0\n#define MAX77620_CNFG_GPIO_DIR_MASK           (1 << 1)\n#define MAX77620_CNFG_GPIO_DIR_INPUT          (1 << 1)\n#define MAX77620_CNFG_GPIO_DIR_OUTPUT         0\n#define MAX77620_CNFG_GPIO_INPUT_VAL_MASK     (1 << 2)\n#define MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK    (1 << 3)\n#define MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH    (1 << 3)\n#define MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW     0\n#define MAX77620_CNFG_GPIO_INT_MASK           (0x3 << 4)\n#define MAX77620_CNFG_GPIO_INT_FALLING        (1 << 4)\n#define MAX77620_CNFG_GPIO_INT_RISING         (1 << 5)\n#define MAX77620_CNFG_GPIO_DBNC_MASK          (0x3 << 6)\n#define MAX77620_CNFG_GPIO_DBNC_None          (0x0 << 6)\n#define MAX77620_CNFG_GPIO_DBNC_8ms           (0x1 << 6)\n#define MAX77620_CNFG_GPIO_DBNC_16ms          (0x2 << 6)\n#define MAX77620_CNFG_GPIO_DBNC_32ms          (0x3 << 6)\n\n#define MAX77620_IRQ_LVL2_GPIO_EDGE0          (1 << 0)\n#define MAX77620_IRQ_LVL2_GPIO_EDGE1          (1 << 1)\n#define MAX77620_IRQ_LVL2_GPIO_EDGE2          (1 << 2)\n#define MAX77620_IRQ_LVL2_GPIO_EDGE3          (1 << 3)\n#define MAX77620_IRQ_LVL2_GPIO_EDGE4          (1 << 4)\n#define MAX77620_IRQ_LVL2_GPIO_EDGE5          (1 << 5)\n#define MAX77620_IRQ_LVL2_GPIO_EDGE6          (1 << 6)\n#define MAX77620_IRQ_LVL2_GPIO_EDGE7          (1 << 7)\n\n/* Interrupts */\nenum {\n\tMAX77620_IRQ_TOP_GLBL,\t\t/* Low-Battery */\n\tMAX77620_IRQ_TOP_SD,\t\t/* SD power fail */\n\tMAX77620_IRQ_TOP_LDO,\t\t/* LDO power fail */\n\tMAX77620_IRQ_TOP_GPIO,\t\t/* TOP GPIO internal int to MAX77620 */\n\tMAX77620_IRQ_TOP_RTC,\t\t/* RTC */\n\tMAX77620_IRQ_TOP_32K,\t\t/* 32kHz oscillator */\n\tMAX77620_IRQ_TOP_ONOFF,\t\t/* ON/OFF oscillator */\n\tMAX77620_IRQ_LBT_MBATLOW,\t/* Thermal alarm status, > 120C */\n\tMAX77620_IRQ_LBT_TJALRM1,\t/* Thermal alarm status, > 120C */\n\tMAX77620_IRQ_LBT_TJALRM2,\t/* Thermal alarm status, > 140C */\n};\n\n/* GPIOs */\nenum {\n\tMAX77620_GPIO0,\n\tMAX77620_GPIO1,\n\tMAX77620_GPIO2,\n\tMAX77620_GPIO3,\n\tMAX77620_GPIO4,\n\tMAX77620_GPIO5,\n\tMAX77620_GPIO6,\n\tMAX77620_GPIO7,\n\tMAX77620_GPIO_NR,\n};\n\n/* FPS Source */\nenum max77620_fps_src {\n\tMAX77620_FPS_SRC_0,\n\tMAX77620_FPS_SRC_1,\n\tMAX77620_FPS_SRC_2,\n\tMAX77620_FPS_SRC_NONE,\n\tMAX77620_FPS_SRC_DEF,\n};\n\nenum max77620_chip_id {\n\tMAX77620,\n\tMAX20024,\n};\n\n#endif /* _MFD_MAX77620_H_ */\n"
  },
  {
    "path": "argon-nx-gui/include/power/max7762x.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2019 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _MAX7762X_H_\n#define _MAX7762X_H_\n\n#include \"../utils/types.h\"\n\n/*\n* Switch Power domains (max77620):\n* Name  | Usage         | uV step | uV min | uV default | uV max  | Init\n*-------+---------------+---------+--------+------------+---------+------------------\n*  sd0  | core          | 12500   | 600000 |  625000    | 1400000 | 1.125V (pkg1.1)\n*  sd1  | SDRAM         | 12500   | 600000 | 1125000    | 1125000 | 1.1V   (pkg1.1)\n*  sd2  | ldo{0-1, 7-8} | 12500   | 600000 | 1325000    | 1350000 | 1.325V (pcv)\n*  sd3  | 1.8V general  | 12500   | 600000 | 1800000    | 1800000 |\n*  ldo0 | Display Panel | 25000   | 800000 | 1200000    | 1200000 | 1.2V   (pkg1.1)\n*  ldo1 | XUSB, PCIE    | 25000   | 800000 | 1050000    | 1050000 | 1.05V  (pcv)\n*  ldo2 | SDMMC1        | 50000   | 800000 | 1800000    | 3300000 |\n*  ldo3 | GC ASIC       | 50000   | 800000 | 3100000    | 3100000 | 3.1V  (pcv)\n*  ldo4 | RTC           | 12500   | 800000 |  850000    |  850000 |\n*  ldo5 | GC ASIC       | 50000   | 800000 | 1800000    | 1800000 | 1.8V  (pcv)\n*  ldo6 | Touch, ALS    | 50000   | 800000 | 2900000    | 2900000 | 2.9V\n*  ldo7 | XUSB          | 50000   | 800000 | 1050000    | 1050000 |\n*  ldo8 | XUSB, DC      | 50000   | 800000 | 1050000    | 1050000 |\n*/\n\n/*\n* MAX77620_AME_GPIO: control GPIO modes (bits 0 - 7 correspond to GPIO0 - GPIO7); 0 -> GPIO, 1 -> alt-mode\n* MAX77620_REG_GPIOx: 0x9 sets output and enable\n*/\n\n/*! MAX77620 partitions. */\n#define REGULATOR_SD0 0\n#define REGULATOR_SD1 1\n#define REGULATOR_SD2 2\n#define REGULATOR_SD3 3\n#define REGULATOR_LDO0 4\n#define REGULATOR_LDO1 5\n#define REGULATOR_LDO2 6\n#define REGULATOR_LDO3 7\n#define REGULATOR_LDO4 8\n#define REGULATOR_LDO5 9\n#define REGULATOR_LDO6 10\n#define REGULATOR_LDO7 11\n#define REGULATOR_LDO8 12\n#define REGULATOR_MAX 12\n\n#define MAX77621_CPU_I2C_ADDR 0x1B\n#define MAX77621_GPU_I2C_ADDR 0x1C\n\n#define MAX77621_VOUT_REG 0\n#define MAX77621_VOUT_DVC_REG 1\n#define MAX77621_CONTROL1_REG 2\n#define MAX77621_CONTROL2_REG 3\n\n/* MAX77621_VOUT */\n#define MAX77621_VOUT_ENABLE  (1 << 7)\n#define MAX77621_VOUT_MASK    0x7F\n\n/* MAX77621_VOUT_DVC_DVS */\n#define MAX77621_DVS_VOUT_MASK 0x7F\n\n/* MAX77621_CONTROL1 */\n#define MAX77621_SNS_ENABLE        (1 << 7)\n#define MAX77621_FPWM_EN_M         (1 << 6)\n#define MAX77621_NFSR_ENABLE       (1 << 5)\n#define MAX77621_AD_ENABLE         (1 << 4)\n#define MAX77621_BIAS_ENABLE       (1 << 3)\n#define MAX77621_FREQSHIFT_9PER    (1 << 2)\n\n#define MAX77621_RAMP_12mV_PER_US  0x0\n#define MAX77621_RAMP_25mV_PER_US  0x1\n#define MAX77621_RAMP_50mV_PER_US  0x2\n#define MAX77621_RAMP_200mV_PER_US 0x3\n#define MAX77621_RAMP_MASK         0x3\n\n/* MAX77621_CONTROL2 */\n#define MAX77621_WDTMR_ENABLE    (1 << 6)\n#define MAX77621_DISCH_ENBABLE   (1 << 5)\n#define MAX77621_FT_ENABLE\t\t (1 << 4)\n#define MAX77621_T_JUNCTION_120\t (1 << 7)\n\n#define MAX77621_CKKADV_TRIP_DISABLE              0xC\n#define MAX77621_CKKADV_TRIP_75mV_PER_US          0x0\n#define MAX77621_CKKADV_TRIP_150mV_PER_US         0x4\n#define MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS 0x8\n\n#define MAX77621_INDUCTOR_MIN_30_PER  0x0\n#define MAX77621_INDUCTOR_NOMINAL     0x1\n#define MAX77621_INDUCTOR_PLUS_30_PER 0x2\n#define MAX77621_INDUCTOR_PLUS_60_PER 0x3\n\nint max77620_regulator_get_status(u32 id);\nint max77620_regulator_config_fps(u32 id);\nint max77620_regulator_set_voltage(u32 id, u32 mv);\nint max77620_regulator_enable(u32 id, int enable);\nint max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags);\nvoid max77620_config_default();\nvoid max77620_low_battery_monitor_config();\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/sec/se.h",
    "content": "/*\n* Copyright (c) 2018 naehrwert\n*\n* This program is free software; you can redistribute it and/or modify it\n* under the terms and conditions of the GNU General Public License,\n* version 2, as published by the Free Software Foundation.\n*\n* This program is distributed in the hope it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _SE_H_\n#define _SE_H_\n\n#include \"../utils/types.h\"\n\nvoid se_rsa_acc_ctrl(u32 rs, u32 flags);\nvoid se_key_acc_ctrl(u32 ks, u32 flags);\nvoid se_aes_key_set(u32 ks, void *key, u32 size);\nvoid se_aes_key_clear(u32 ks);\nint se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input);\nint se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src);\nint se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr);\nint se_calc_sha256(void *dst, const void *src, u32 src_size);\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/sec/se_t210.h",
    "content": "/*\n* Driver for Tegra Security Engine\n*\n* Copyright (c) 2011-2013, NVIDIA Corporation. All Rights Reserved.\n*\n* This program is free software; you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation; either version 2 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License along\n* with this program; if not, write to the Free Software Foundation, Inc.,\n* 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\n*/\n\n#ifndef _CRYPTO_TEGRA_SE_H\n#define _CRYPTO_TEGRA_SE_H\n\n#include \"../utils/types.h\"\n\n#define TEGRA_SE_CRA_PRIORITY\t300\n#define TEGRA_SE_COMPOSITE_PRIORITY 400\n#define TEGRA_SE_CRYPTO_QUEUE_LENGTH 50\n#define SE_MAX_SRC_SG_COUNT\t\t50\n#define SE_MAX_DST_SG_COUNT\t\t50\n\n#define TEGRA_SE_KEYSLOT_COUNT\t\t16\n#define SE_MAX_LAST_BLOCK_SIZE\t0xFFFFF\n\n/* SE register definitions */\n#define SE_SECURITY_0 0x000\n#define SE_KEY_SCHED_READ_SHIFT 3\n\n#define SE_CONFIG_REG_OFFSET\t\t0x014\n#define SE_CONFIG_ENC_ALG_SHIFT\t\t12\n#define SE_CONFIG_DEC_ALG_SHIFT\t\t8\n#define ALG_AES_ENC\t\t1\n#define ALG_RNG\t\t\t2\n#define ALG_SHA\t\t\t3\n#define ALG_RSA\t\t\t4\n#define ALG_NOP\t\t\t0\n#define ALG_AES_DEC\t\t1\n#define SE_CONFIG_ENC_ALG(x)\t\t(x << SE_CONFIG_ENC_ALG_SHIFT)\n#define SE_CONFIG_DEC_ALG(x)\t\t(x << SE_CONFIG_DEC_ALG_SHIFT)\n#define SE_CONFIG_DST_SHIFT\t\t\t2\n#define DST_MEMORY\t\t0\n#define DST_HASHREG\t\t1\n#define DST_KEYTAB\t\t2\n#define DST_SRK\t\t\t3\n#define DST_RSAREG\t\t4\n#define SE_CONFIG_DST(x)\t\t\t(x << SE_CONFIG_DST_SHIFT)\n#define SE_CONFIG_ENC_MODE_SHIFT\t24\n#define SE_CONFIG_DEC_MODE_SHIFT\t16\n#define MODE_KEY128\t\t0\n#define MODE_KEY192\t\t1\n#define MODE_KEY256\t\t2\n#define MODE_SHA1\t\t0\n#define MODE_SHA224\t\t4\n#define MODE_SHA256\t\t5\n#define MODE_SHA384\t\t6\n#define MODE_SHA512\t\t7\n#define SE_CONFIG_ENC_MODE(x)\t\t(x << SE_CONFIG_ENC_MODE_SHIFT)\n#define SE_CONFIG_DEC_MODE(x)\t\t(x << SE_CONFIG_DEC_MODE_SHIFT)\n\n#define SE_RNG_CONFIG_REG_OFFSET\t\t0x340\n#define DRBG_MODE_SHIFT\t0\n#define DRBG_MODE_NORMAL\t0\n#define DRBG_MODE_FORCE_INSTANTION\t1\n#define DRBG_MODE_FORCE_RESEED\t\t2\n#define SE_RNG_CONFIG_MODE(x)\t\t(x << DRBG_MODE_SHIFT)\n\n#define SE_RNG_SRC_CONFIG_REG_OFFSET\t0x344\n#define DRBG_RO_ENT_SRC_SHIFT\t1\n#define DRBG_RO_ENT_SRC_ENABLE\t1\n#define DRBG_RO_ENT_SRC_DISABLE\t0\n#define SE_RNG_SRC_CONFIG_RO_ENT_SRC(x)\t(x << DRBG_RO_ENT_SRC_SHIFT)\n#define DRBG_RO_ENT_SRC_LOCK_SHIFT\t0\n#define DRBG_RO_ENT_SRC_LOCK_ENABLE\t1\n#define DRBG_RO_ENT_SRC_LOCK_DISABLE\t0\n#define SE_RNG_SRC_CONFIG_RO_ENT_SRC_LOCK(x) (x << DRBG_RO_ENT_SRC_LOCK_SHIFT)\n\n#define DRBG_SRC_SHIFT\t2\n#define DRBG_SRC_NONE\t0\n#define DRBG_SRC_ENTROPY\t1\n#define DRBG_SRC_LFSR\t2\n#define SE_RNG_CONFIG_SRC(x)\t\t(x << DRBG_SRC_SHIFT)\n\n#define SE_RNG_RESEED_INTERVAL_REG_OFFSET\t\t0x348\n\n#define SE_KEYTABLE_REG_OFFSET\t\t0x31c\n#define SE_KEYTABLE_SLOT_SHIFT\t\t4\n#define SE_KEYTABLE_SLOT(x)\t\t\t(x << SE_KEYTABLE_SLOT_SHIFT)\n#define SE_KEYTABLE_QUAD_SHIFT\t\t2\n#define QUAD_KEYS_128\t0\n#define QUAD_KEYS_192\t1\n#define QUAD_KEYS_256\t1\n#define QUAD_ORG_IV\t\t2\n#define QUAD_UPDTD_IV\t3\n#define SE_KEYTABLE_QUAD(x)\t\t\t(x << SE_KEYTABLE_QUAD_SHIFT)\n#define SE_KEYTABLE_OP_TYPE_SHIFT\t9\n#define OP_READ\t\t\t0\n#define OP_WRITE\t\t1\n#define SE_KEYTABLE_OP_TYPE(x)\t\t(x << SE_KEYTABLE_OP_TYPE_SHIFT)\n#define SE_KEYTABLE_TABLE_SEL_SHIFT\t\t8\n#define TABLE_KEYIV\t\t0\n#define TABLE_SCHEDULE\t1\n#define SE_KEYTABLE_TABLE_SEL(x)\t(x << SE_KEYTABLE_TABLE_SEL_SHIFT)\n#define SE_KEYTABLE_PKT_SHIFT\t\t0\n#define SE_KEYTABLE_PKT(x)\t\t\t(x << SE_KEYTABLE_PKT_SHIFT)\n\n#define SE_OP_DONE_SHIFT\t4\n#define OP_DONE\t1\n#define SE_OP_DONE(x, y)\t((x) && (y << SE_OP_DONE_SHIFT))\n\n#define SE_CRYPTO_REG_OFFSET\t\t0x304\n#define SE_CRYPTO_HASH_SHIFT\t\t0\n#define HASH_DISABLE\t0\n#define HASH_ENABLE\t\t1\n#define SE_CRYPTO_HASH(x)\t\t\t(x << SE_CRYPTO_HASH_SHIFT)\n#define SE_CRYPTO_XOR_POS_SHIFT\t\t1\n#define XOR_BYPASS\t\t0\n#define XOR_TOP\t\t\t2\n#define XOR_BOTTOM\t\t3\n#define SE_CRYPTO_XOR_POS(x)\t\t(x << SE_CRYPTO_XOR_POS_SHIFT)\n#define SE_CRYPTO_INPUT_SEL_SHIFT\t3\n#define INPUT_AHB\t\t0\n#define INPUT_RANDOM\t1\n#define INPUT_AESOUT\t2\n#define INPUT_LNR_CTR\t3\n#define SE_CRYPTO_INPUT_SEL(x)\t\t(x << SE_CRYPTO_INPUT_SEL_SHIFT)\n#define SE_CRYPTO_VCTRAM_SEL_SHIFT\t5\n#define VCTRAM_AHB\t\t0\n#define VCTRAM_AESOUT\t2\n#define VCTRAM_PREVAHB\t3\n#define SE_CRYPTO_VCTRAM_SEL(x)\t\t(x << SE_CRYPTO_VCTRAM_SEL_SHIFT)\n#define SE_CRYPTO_IV_SEL_SHIFT\t\t7\n#define IV_ORIGINAL\t\t0\n#define IV_UPDATED\t\t1\n#define SE_CRYPTO_IV_SEL(x)\t\t\t(x << SE_CRYPTO_IV_SEL_SHIFT)\n#define SE_CRYPTO_CORE_SEL_SHIFT\t8\n#define CORE_DECRYPT\t0\n#define CORE_ENCRYPT\t1\n#define SE_CRYPTO_CORE_SEL(x)\t\t(x << SE_CRYPTO_CORE_SEL_SHIFT)\n#define SE_CRYPTO_CTR_VAL_SHIFT\t\t11\n#define SE_CRYPTO_CTR_VAL(x)\t\t(x << SE_CRYPTO_CTR_VAL_SHIFT)\n#define SE_CRYPTO_KEY_INDEX_SHIFT\t24\n#define SE_CRYPTO_KEY_INDEX(x)\t\t(x << SE_CRYPTO_KEY_INDEX_SHIFT)\n#define SE_CRYPTO_CTR_CNTN_SHIFT\t11\n#define SE_CRYPTO_CTR_CNTN(x)\t\t(x << SE_CRYPTO_CTR_CNTN_SHIFT)\n\n#define SE_CRYPTO_CTR_REG_COUNT\t\t4\n#define SE_CRYPTO_CTR_REG_OFFSET\t0x308\n\n#define SE_OPERATION_REG_OFFSET\t\t0x008\n#define SE_OPERATION_SHIFT\t\t\t0\n#define OP_ABORT\t\t0\n#define OP_START\t\t1\n#define OP_RESTART\t\t2\n#define OP_CTX_SAVE\t\t3\n#define OP_RESTART_IN\t4\n#define SE_OPERATION(x)\t\t\t\t(x << SE_OPERATION_SHIFT)\n\n#define SE_CONTEXT_SAVE_CONFIG_REG_OFFSET\t\t0x070\n#define SE_CONTEXT_SAVE_WORD_QUAD_SHIFT\t\t0\n#define KEYS_0_3\t\t0\n#define KEYS_4_7\t\t1\n#define ORIG_IV\t\t2\n#define UPD_IV\t\t3\n#define SE_CONTEXT_SAVE_WORD_QUAD(x)\t(x << SE_CONTEXT_SAVE_WORD_QUAD_SHIFT)\n\n#define SE_CONTEXT_SAVE_KEY_INDEX_SHIFT\t\t8\n#define SE_CONTEXT_SAVE_KEY_INDEX(x)\t(x << SE_CONTEXT_SAVE_KEY_INDEX_SHIFT)\n\n#define SE_CONTEXT_SAVAE_STICKY_WORD_QUAD_SHIFT\t24\n#define STICKY_0_3\t\t0\n#define STICKY_4_7\t\t1\n#define SE_CONTEXT_SAVE_STICKY_WORD_QUAD(x)\t\t\\\n\t\t(x << SE_CONTEXT_SAVAE_STICKY_WORD_QUAD_SHIFT)\n\n#define SE_CONTEXT_SAVE_SRC_SHIFT\t\t29\n#define STICKY_BITS\t\t0\n#define KEYTABLE\t\t2\n#define MEM\t\t4\n#define SRK\t\t6\n\n#define RSA_KEYTABLE\t1\n#define SE_CONTEXT_SAVE_SRC(x)\t\t(x << SE_CONTEXT_SAVE_SRC_SHIFT)\n\n#define SE_CONTEXT_SAVE_RSA_KEY_INDEX_SHIFT\t16\n#define SE_CONTEXT_SAVE_RSA_KEY_INDEX(x)\t\t\\\n\t\t(x << SE_CONTEXT_SAVE_RSA_KEY_INDEX_SHIFT)\n\n#define SE_CONTEXT_RSA_WORD_QUAD_SHIFT\t12\n#define SE_CONTEXT_RSA_WORD_QUAD(x)\t\t\\\n\t\t(x << SE_CONTEXT_RSA_WORD_QUAD_SHIFT)\n\n#define SE_INT_ENABLE_REG_OFFSET\t0x00c\n#define SE_INT_STATUS_REG_OFFSET\t0x010\n#define INT_DISABLE\t\t0\n#define INT_ENABLE\t\t1\n#define INT_UNSET\t\t0\n#define INT_SET\t\t\t1\n#define SE_INT_OP_DONE_SHIFT\t\t4\n#define SE_INT_OP_DONE(x)\t\t\t(x << SE_INT_OP_DONE_SHIFT)\n#define SE_INT_ERROR_SHIFT\t\t16\n#define SE_INT_ERROR(x)\t\t\t(x << SE_INT_ERROR_SHIFT)\n#define SE_STATUS_0 0x800\n#define SE_ERR_STATUS_0\t\t\t0x804\n\n#define SE_CRYPTO_KEYTABLE_DST_REG_OFFSET\t0X330\n#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT\t\t0\n#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD(x)\t\t\\\n\t\t(x << SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT)\n\n#define SE_KEY_INDEX_SHIFT\t\t8\n#define SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(x)\t(x << SE_KEY_INDEX_SHIFT)\n\n#define SE_IN_LL_ADDR_REG_OFFSET\t0x018\n#define SE_OUT_LL_ADDR_REG_OFFSET\t0x024\n\n#define SE_KEYTABLE_DATA0_REG_OFFSET\t0x320\n#define SE_KEYTABLE_REG_MAX_DATA\t\t16\n\n#define SE_BLOCK_COUNT_REG_OFFSET\t0x318\n\n#define SE_SPARE_0_REG_OFFSET\t\t0x80c\n\n#define SE_SHA_CONFIG_REG_OFFSET\t0x200\n#define SHA_DISABLE\t\t0\n#define SHA_ENABLE\t\t1\n\n#define SE_SHA_MSG_LENGTH_REG_OFFSET\t0x204\n#define SE_SHA_MSG_LEFT_REG_OFFSET\t\t0x214\n\n#define SE_HASH_RESULT_REG_COUNT\t16\n#define SE_HASH_RESULT_REG_OFFSET\t0x030\n#define TEGRA_SE_KEY_256_SIZE\t\t32\n#define TEGRA_SE_KEY_192_SIZE\t\t24\n#define TEGRA_SE_KEY_128_SIZE\t\t16\n#define TEGRA_SE_AES_BLOCK_SIZE\t\t16\n#define TEGRA_SE_AES_MIN_KEY_SIZE\t16\n#define TEGRA_SE_AES_MAX_KEY_SIZE\t32\n#define TEGRA_SE_AES_IV_SIZE\t\t16\n#define TEGRA_SE_RNG_IV_SIZE\t\t16\n#define TEGRA_SE_RNG_DT_SIZE\t\t16\n#define TEGRA_SE_RNG_KEY_SIZE\t\t16\n#define TEGRA_SE_RNG_SEED_SIZE\t\t(TEGRA_SE_RNG_IV_SIZE + \\\n\t\t\t\t\t\tTEGRA_SE_RNG_KEY_SIZE + \\\n\t\t\t\t\t\tTEGRA_SE_RNG_DT_SIZE)\n\n#define TEGRA_SE_AES_CMAC_DIGEST_SIZE\t16\n#define TEGRA_SE_RSA512_DIGEST_SIZE\t64\n#define TEGRA_SE_RSA1024_DIGEST_SIZE\t128\n#define TEGRA_SE_RSA1536_DIGEST_SIZE\t192\n#define TEGRA_SE_RSA2048_DIGEST_SIZE\t256\n\n#define SE_KEY_TABLE_ACCESS_LOCK_OFFSET\t0x280\n#define SE_KEY_TABLE_ACCESS_REG_OFFSET\t0x284\n#define SE_KEY_READ_DISABLE_SHIFT\t\t0\n#define SE_KEY_UPDATE_DISABLE_SHIFT\t\t1\n\n#define SE_CONTEXT_BUFER_SIZE\t1072\n#define SE_CONTEXT_DRBG_BUFER_SIZE\t2112\n\n#define SE_CONTEXT_SAVE_RANDOM_DATA_OFFSET\t0\n#define SE_CONTEXT_SAVE_RANDOM_DATA_SIZE\t16\n#define SE_CONTEXT_SAVE_STICKY_BITS_OFFSET\t\\\n\t(SE_CONTEXT_SAVE_RANDOM_DATA_OFFSET + SE_CONTEXT_SAVE_RANDOM_DATA_SIZE)\n#define SE_CONTEXT_SAVE_STICKY_BITS_SIZE\t16\n\n#define SE_CONTEXT_SAVE_KEYS_OFFSET\t(SE_CONTEXT_SAVE_STICKY_BITS_OFFSET + \\\n\t\t\t\t\tSE_CONTEXT_SAVE_STICKY_BITS_SIZE)\n#define SE11_CONTEXT_SAVE_KEYS_OFFSET\t(SE_CONTEXT_SAVE_STICKY_BITS_OFFSET + \\\n\t\t\t\t\tSE_CONTEXT_SAVE_STICKY_BITS_SIZE + \\\n\t\t\t\t\tSE_CONTEXT_SAVE_STICKY_BITS_SIZE)\n\n#define SE_CONTEXT_SAVE_KEY_LENGTH\t512\n#define SE_CONTEXT_ORIGINAL_IV_OFFSET\t(SE_CONTEXT_SAVE_KEYS_OFFSET + \\\n\t\t\tSE_CONTEXT_SAVE_KEY_LENGTH)\n#define SE11_CONTEXT_ORIGINAL_IV_OFFSET\t(SE11_CONTEXT_SAVE_KEYS_OFFSET + \\\n\t\t\tSE_CONTEXT_SAVE_KEY_LENGTH)\n\n#define SE_CONTEXT_ORIGINAL_IV_LENGTH\t256\n\n#define SE_CONTEXT_UPDATED_IV_OFFSET\t(SE_CONTEXT_ORIGINAL_IV_OFFSET + \\\n\t\t\tSE_CONTEXT_ORIGINAL_IV_LENGTH)\n#define SE11_CONTEXT_UPDATED_IV_OFFSET\t(SE11_CONTEXT_ORIGINAL_IV_OFFSET + \\\n\t\t\tSE_CONTEXT_ORIGINAL_IV_LENGTH)\n\n#define SE_CONTEXT_UPDATED_IV_LENGTH\t256\n\n#define SE_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET (SE_CONTEXT_UPDATED_IV_OFFSET + \\\n\t\t\t\t\tSE_CONTEXT_UPDATED_IV_LENGTH)\n#define SE11_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET \\\n\t\t\t\t\t(SE11_CONTEXT_UPDATED_IV_OFFSET + \\\n\t\t\t\t\tSE_CONTEXT_UPDATED_IV_LENGTH)\n\n#define SE_CONTEXT_SAVE_RSA_KEYS_OFFSET\tSE11_CONTEXT_SAVE_KNOWN_PATTERN_OFFSET\n\n#define SE_CONTEXT_SAVE_RSA_KEY_LENGTH\t1024\n\n#define SE_CONTEXT_SAVE_RSA_KNOWN_PATTERN_OFFSET\t\\\n\t(SE_CONTEXT_SAVE_RSA_KEYS_OFFSET + SE_CONTEXT_SAVE_RSA_KEY_LENGTH)\n\n#define SE_CONTEXT_KNOWN_PATTERN_SIZE\t16\n\n#define TEGRA_SE_RSA_KEYSLOT_COUNT\t\t2\n\n#define SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET\t0x40C\n#define SE_RSA_KEYTABLE_ACCESS_REG_OFFSET\t0x410\n\n#define SE_RSA_KEYTABLE_ADDR\t0x420\n#define SE_RSA_KEYTABLE_DATA\t0x424\n#define SE_RSA_OUTPUT 0x428\n\n#define RSA_KEY_READ\t0\n#define RSA_KEY_WRITE\t1\n#define SE_RSA_KEY_OP_SHIFT\t10\n#define SE_RSA_KEY_OP(x)\t(x << SE_RSA_KEY_OP_SHIFT)\n\n#define RSA_KEY_INPUT_MODE_REG\t0\n#define RSA_KEY_INPUT_MODE_DMA\t1\n#define RSA_KEY_INPUT_MODE_SHIFT\t8\n#define RSA_KEY_INPUT_MODE(x)\t(x << RSA_KEY_INPUT_MODE_SHIFT)\n\n#define RSA_KEY_SLOT_ONE\t0\n#define RSA_KEY_SLOT_TW0\t1\n#define RSA_KEY_NUM_SHIFT\t7\n#define RSA_KEY_NUM(x)\t(x << RSA_KEY_NUM_SHIFT)\n\n#define RSA_KEY_TYPE_EXP\t0\n#define RSA_KEY_TYPE_MOD\t1\n#define RSA_KEY_TYPE_SHIFT\t6\n#define RSA_KEY_TYPE(x)\t(x << RSA_KEY_TYPE_SHIFT)\n\n#define SE_RSA_KEY_SIZE_REG_OFFSET\t0x404\n#define SE_RSA_EXP_SIZE_REG_OFFSET\t0x408\n\n#define RSA_KEY_SLOT_SHIFT\t24\n#define RSA_KEY_SLOT(x)\t(x << RSA_KEY_SLOT_SHIFT)\n#define SE_RSA_CONFIG\t0x400\n\n#define RSA_KEY_PKT_WORD_ADDR_SHIFT\t0\n#define RSA_KEY_PKT_WORD_ADDR(x)\t(x << RSA_KEY_PKT_WORD_ADDR_SHIFT)\n\n#define RSA_KEY_WORD_ADDR_SHIFT\t0\n#define RSA_KEY_WORD_ADDR(x)\t(x << RSA_KEY_WORD_ADDR_SHIFT)\n\n#define SE_RSA_KEYTABLE_PKT_SHIFT\t0\n#define SE_RSA_KEYTABLE_PKT(x)\t(x << SE_RSA_KEYTABLE_PKT_SHIFT)\n\n#endif /* _CRYPTO_TEGRA_SE_H */\n"
  },
  {
    "path": "argon-nx-gui/include/soc/bpmp.h",
    "content": "/*\n * BPMP-Lite Cache/MMU and Frequency driver for Tegra X1\n *\n * Copyright (c) 2019 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _BPMP_H_\n#define _BPMP_H_\n\n#include \"utils/types.h\"\n\n#define BPMP_MMU_MAINT_CLEAN_WAY   17\n#define BPMP_MMU_MAINT_INVALID_WAY 18\n#define BPMP_MMU_MAINT_CLN_INV_WAY 19\n\ntypedef struct _bpmp_mmu_entry_t\n{\n\tu32 min_addr;\n\tu32 max_addr;\n\tu32 attr;\n\tu32 enable;\n} bpmp_mmu_entry_t;\n\ntypedef enum\n{\n\tBPMP_CLK_NORMAL,      // 408MHz  0% - 136MHz APB.\n\tBPMP_CLK_LOW_BOOST,   // 544MHz 33% - 136MHz APB.\n\tBPMP_CLK_MID_BOOST,   // 576MHz 41% - 144MHz APB.\n\tBPMP_CLK_SUPER_BOOST, // 608MHz 49% - 152MHz APB.\n\tBPMP_CLK_MAX\n} bpmp_freq_t;\n\nvoid bpmp_mmu_maintenance(u32 op);\nvoid bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply);\nvoid bpmp_mmu_enable();\nvoid bpmp_mmu_disable();\nvoid bpmp_clk_rate_set(bpmp_freq_t fid);\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/soc/clock.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _CLOCK_H_\n#define _CLOCK_H_\n\n#include \"utils/types.h\"\n\n/*! Clock registers. */\n#define CLK_RST_CONTROLLER_RST_SOURCE 0x0\n#define CLK_RST_CONTROLLER_RST_DEVICES_L 0x4\n#define CLK_RST_CONTROLLER_RST_DEVICES_H 0x8\n#define CLK_RST_CONTROLLER_RST_DEVICES_U 0xC\n#define CLK_RST_CONTROLLER_CLK_OUT_ENB_L 0x10\n#define CLK_RST_CONTROLLER_CLK_OUT_ENB_H 0x14\n#define CLK_RST_CONTROLLER_CLK_OUT_ENB_U 0x18\n#define CLK_RST_CONTROLLER_CCLK_BURST_POLICY 0x20\n#define CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER 0x24\n#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY 0x28\n#define CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER 0x2C\n#define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE 0x30\n#define CLK_RST_CONTROLLER_MISC_CLK_ENB 0x48\n#define CLK_RST_CONTROLLER_OSC_CTRL 0x50\n#define CLK_RST_CONTROLLER_PLLC_BASE 0x80\n#define CLK_RST_CONTROLLER_PLLC_MISC 0x88\n#define CLK_RST_CONTROLLER_PLLM_BASE 0x90\n#define CLK_RST_CONTROLLER_PLLM_MISC1 0x98\n#define CLK_RST_CONTROLLER_PLLM_MISC2 0x9C\n#define CLK_RST_CONTROLLER_PLLP_BASE 0xA0\n#define CLK_RST_CONTROLLER_PLLD_BASE 0xD0\n#define CLK_RST_CONTROLLER_PLLX_BASE 0xE0\n#define CLK_RST_CONTROLLER_PLLX_MISC 0xE4\n#define CLK_RST_CONTROLLER_PLLE_BASE 0xE8\n#define CLK_RST_CONTROLLER_PLLE_MISC 0xEC\n#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA 0xF8\n#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB 0xFC\n#define CLK_RST_CONTROLLER_CLK_SOURCE_PWM 0x110\n#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C1 0x124\n#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C5 0x128\n#define CLK_RST_CONTROLLER_CLK_SOURCE_VI 0x148\n#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1 0x150\n#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2 0x154\n#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4 0x164\n#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTA 0x178\n#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTB 0x17C\n#define CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X 0x180\n#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTC 0x1A0\n#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C3 0x1B8\n#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3 0x1BC\n#define CLK_RST_CONTROLLER_CLK_SOURCE_CSITE 0x1D4\n#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC 0x19C\n#define CLK_RST_CONTROLLER_CLK_SOURCE_TSEC 0x1F4\n#define CLK_RST_CONTROLLER_CLK_OUT_ENB_X 0x280\n#define CLK_RST_CONTROLLER_CLK_ENB_X_SET 0x284\n#define CLK_RST_CONTROLLER_CLK_ENB_X_CLR 0x288\n#define CLK_RST_CONTROLLER_RST_DEVICES_X 0x28C\n#define CLK_RST_CONTROLLER_RST_DEV_X_SET 0x290\n#define CLK_RST_CONTROLLER_RST_DEV_X_CLR 0x294\n#define CLK_RST_CONTROLLER_CLK_OUT_ENB_Y 0x298\n#define CLK_RST_CONTROLLER_CLK_ENB_Y_SET 0x29C\n#define CLK_RST_CONTROLLER_CLK_ENB_Y_CLR 0x2A0\n#define CLK_RST_CONTROLLER_RST_DEVICES_Y 0x2A4\n#define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2A8\n#define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2AC\n#define CLK_RST_CONTROLLER_RST_DEV_L_SET 0x300\n#define CLK_RST_CONTROLLER_RST_DEV_L_CLR 0x304\n#define CLK_RST_CONTROLLER_RST_DEV_H_SET 0x308\n#define CLK_RST_CONTROLLER_RST_DEV_H_CLR 0x30C\n#define CLK_RST_CONTROLLER_RST_DEV_U_SET 0x310\n#define CLK_RST_CONTROLLER_RST_DEV_U_CLR 0x314\n#define CLK_RST_CONTROLLER_CLK_ENB_L_SET 0x320\n#define CLK_RST_CONTROLLER_CLK_ENB_L_CLR 0x324\n#define CLK_RST_CONTROLLER_CLK_ENB_H_SET 0x328\n#define CLK_RST_CONTROLLER_CLK_ENB_H_CLR 0x32C\n#define CLK_RST_CONTROLLER_CLK_ENB_U_SET 0x330\n#define CLK_RST_CONTROLLER_CLK_ENB_U_CLR 0x334\n#define CLK_RST_CONTROLLER_RST_DEVICES_V 0x358\n#define CLK_RST_CONTROLLER_RST_DEVICES_W 0x35C\n#define CLK_RST_CONTROLLER_CLK_OUT_ENB_V 0x360\n#define CLK_RST_CONTROLLER_CLK_OUT_ENB_W 0x364\n#define CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2 0x388\n#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC 0x3A0\n#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD 0x3A4\n#define CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT 0x3B4\n#define CLK_RST_CONTROLLER_CLK_SOURCE_SOR1 0x410\n#define CLK_RST_CONTROLLER_CLK_SOURCE_SE 0x42C\n#define CLK_RST_CONTROLLER_CLK_ENB_V_SET 0x440\n//#define CLK_RST_CONTROLLER_CLK_ENB_V_CLR 0x444\n#define CLK_RST_CONTROLLER_CLK_ENB_W_SET 0x448\n#define CLK_RST_CONTROLLER_CLK_ENB_W_CLR 0x44C\n#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET 0x450\n#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR 0x454\n#define CLK_RST_CONTROLLER_UTMIP_PLL_CFG2 0x488\n#define CLK_RST_CONTROLLER_PLLE_AUX 0x48C\n#define CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_I2S0 0x4A0\n#define CLK_RST_CONTROLLER_PLLX_MISC_3 0x518\n#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE 0x554\n#define CLK_RST_CONTROLLER_SPARE_REG0 0x55C\n#define CLK_RST_CONTROLLER_PLLC4_BASE 0x5A4\n#define CLK_RST_CONTROLLER_PLLC4_MISC 0x5A8\n#define CLK_RST_CONTROLLER_PLLC4_OUT 0x5E4\n#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8\n#define CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP 0x620\n//#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 0x65C\n#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664\n#define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIP_CAL 0x66C\n#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM 0x694\n#define CLK_RST_CONTROLLER_CLK_SOURCE_NVENC 0x6A0\n#define CLK_RST_CONTROLLER_SE_SUPER_CLK_DIVIDER 0x704\n\n#define CLK_NO_SOURCE 0x0\n\n/*! Generic clock descriptor. */\ntypedef struct _clock_t\n{\n\tu32 reset;\n\tu32 enable;\n\tu32 source;\n\tu8 index;\n\tu8 clk_src;\n\tu8 clk_div;\n} clock_t;\n\n/*! Generic clock enable/disable. */\nvoid clock_enable(const clock_t *clk);\nvoid clock_disable(const clock_t *clk);\n\n/*! Clock control for specific hardware portions. */\nvoid clock_enable_fuse(bool enable);\nvoid clock_enable_uart(u32 idx);\nvoid clock_enable_i2c(u32 idx);\nvoid clock_disable_i2c(u32 idx);\nvoid clock_enable_se();\nvoid clock_enable_tzram();\nvoid clock_enable_host1x();\nvoid clock_disable_host1x();\nvoid clock_enable_tsec();\nvoid clock_disable_tsec();\nvoid clock_enable_sor_safe();\nvoid clock_disable_sor_safe();\nvoid clock_enable_sor0();\nvoid clock_disable_sor0();\nvoid clock_enable_sor1();\nvoid clock_disable_sor1();\nvoid clock_enable_kfuse();\nvoid clock_disable_kfuse();\nvoid clock_enable_cl_dvfs();\nvoid clock_disable_cl_dvfs();\nvoid clock_enable_coresight();\nvoid clock_disable_coresight();\nvoid clock_enable_pwm();\nvoid clock_disable_pwm();\nvoid clock_sdmmc_config_clock_source(u32 *pout, u32 id, u32 val);\nvoid clock_sdmmc_get_params(u32 *pout, u16 *pdivisor, u32 type);\nint clock_sdmmc_is_not_reset_and_enabled(u32 id);\nvoid clock_sdmmc_enable(u32 id, u32 val);\nvoid clock_sdmmc_disable(u32 id);\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/soc/cluster.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _CLUSTER_H_\n#define _CLUSTER_H_\n\n#include \"utils/types.h\"\n\n/*! Flow controller registers. */\n#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0\n#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14\n#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C\n#define FLOW_CTLR_HALT_CPU3_EVENTS 0x24\n#define FLOW_CTLR_HALT_COP_EVENTS 0x4\n#define FLOW_CTLR_CPU0_CSR 0x8\n#define FLOW_CTLR_CPU1_CSR 0x18\n#define FLOW_CTLR_CPU2_CSR 0x20\n#define FLOW_CTLR_CPU3_CSR 0x28\n#define FLOW_CTLR_RAM_REPAIR 0x40\n#define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98\n\nvoid cluster_boot_cpu0(u32 entry);\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/soc/fuse.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 shuffle2\n * Copyright (c) 2018 balika011\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _FUSE_H_\n#define _FUSE_H_\n\n#include \"utils/types.h\"\n\n/*! Fuse registers. */\n#define FUSE_CTRL 0x0\n#define FUSE_ADDR 0x4\n#define FUSE_RDATA 0x8\n#define FUSE_WDATA 0xC\n#define FUSE_TIME_RD1 0x10\n#define FUSE_TIME_RD2 0x14\n#define FUSE_TIME_PGM1 0x18\n#define FUSE_TIME_PGM2 0x1C\n#define FUSE_PRIV2INTFC 0x20\n#define FUSE_FUSEBYPASS 0x24\n#define FUSE_PRIVATEKEYDISABLE 0x28\n#define FUSE_DISABLEREGPROGRAM 0x2C\n#define FUSE_WRITE_ACCESS_SW 0x30\n#define FUSE_PWR_GOOD_SW 0x34\n#define FUSE_SKU_INFO 0x110\n#define FUSE_FIRST_BOOTROM_PATCH_SIZE 0x19c\n#define FUSE_PRIVATE_KEY0 0x1A4\n#define FUSE_PRIVATE_KEY1 0x1A8\n#define FUSE_PRIVATE_KEY2 0x1AC\n#define FUSE_PRIVATE_KEY3 0x1B0\n\n/*! Fuse commands. */\n#define FUSE_READ 0x1\n#define FUSE_WRITE 0x2\n#define FUSE_SENSE 0x3\n#define FUSE_CMD_MASK 0x3\n\n/*! Fuse cache registers. */\n#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))\n\nvoid fuse_disable_program();\nu32 fuse_read_odm(u32 idx);\nvoid fuse_wait_idle();\nint fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value));\nint fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len);\nvoid read_raw_ipatch_fuses(u32 *words);\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/soc/gpio.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _GPIO_H_\n#define _GPIO_H_\n\n#include \"utils/types.h\"\n\n#define GPIO_MODE_SPIO 0\n#define GPIO_MODE_GPIO 1\n#define GPIO_OUTPUT_DISABLE 0\n#define GPIO_OUTPUT_ENABLE 1\n#define GPIO_LOW 0\n#define GPIO_HIGH 1\n\n/*! GPIO pins (0-7 for each port). */\n#define GPIO_PIN_0 (1 << 0)\n#define GPIO_PIN_1 (1 << 1)\n#define GPIO_PIN_2 (1 << 2)\n#define GPIO_PIN_3 (1 << 3)\n#define GPIO_PIN_4 (1 << 4)\n#define GPIO_PIN_5 (1 << 5)\n#define GPIO_PIN_6 (1 << 6)\n#define GPIO_PIN_7 (1 << 7)\n\n/*! GPIO ports (A-EE). */\n#define GPIO_PORT_A 0\n#define GPIO_PORT_B 1\n#define GPIO_PORT_C 2\n#define GPIO_PORT_D 3\n#define GPIO_PORT_E 4\n#define GPIO_PORT_F 5\n#define GPIO_PORT_G 6\n#define GPIO_PORT_H 7\n#define GPIO_PORT_I 8\n#define GPIO_PORT_J 9\n#define GPIO_PORT_K 10\n#define GPIO_PORT_L 11\n#define GPIO_PORT_M 12\n#define GPIO_PORT_N 13\n#define GPIO_PORT_O 14\n#define GPIO_PORT_P 15\n#define GPIO_PORT_Q 16\n#define GPIO_PORT_R 17\n#define GPIO_PORT_S 18\n#define GPIO_PORT_T 19\n#define GPIO_PORT_U 20\n#define GPIO_PORT_V 21\n#define GPIO_PORT_W 22\n#define GPIO_PORT_X 23\n#define GPIO_PORT_Y 24\n#define GPIO_PORT_Z 25\n#define GPIO_PORT_AA 26\n#define GPIO_PORT_BB 27\n#define GPIO_PORT_CC 28\n#define GPIO_PORT_DD 29\n#define GPIO_PORT_EE 30\n\nvoid gpio_config(u32 port, u32 pins, int mode);\nvoid gpio_output_enable(u32 port, u32 pins, int enable);\nvoid gpio_write(u32 port, u32 pins, int high);\nint gpio_read(u32 port, u32 pins);\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/soc/hw_init.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _HW_INIT_H_\n#define _HW_INIT_H_\n\n#include \"utils/types.h\"\n#include \"core/argon-ctxt.h\"\n\nvoid reconfig_hw_workaround(argon_ctxt_t* argon_ctxt_t, bool extra_reconfig, u32 magic);\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/soc/i2c.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _I2C_H_\n#define _I2C_H_\n\n#include \"utils/types.h\"\n\n#define I2C_1 0\n#define I2C_2 1\n#define I2C_3 2\n#define I2C_4 3\n#define I2C_5 4\n#define I2C_6 5\n\n#define I2C_CNFG        0x00\n#define I2C_CMD_ADDR0   0x01\n#define I2C_CMD_DATA1   0x03\n#define I2C_CMD_DATA2   0x04\n#define I2C_STATUS 0x07\n#define INTERRUPT_STATUS_REGISTER 0x1A\n#define I2C_CLK_DIVISOR_REGISTER 0x1B\n#define I2C_BUS_CLEAR_CONFIG 0x21\n#define I2C_BUS_CLEAR_STATUS 0x22\n#define I2C_CONFIG_LOAD 0x23\n\nvoid i2c_init(u32 idx);\nint i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size);\nint i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y);\nint i2c_send_byte(u32 idx, u32 x, u32 y, u8 b);\nu8 i2c_recv_byte(u32 idx, u32 x, u32 y);\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/soc/pinmux.h",
    "content": "#ifndef _PINMUX_H_\n#define _PINMUX_H_\n\n#include \"utils/types.h\"\n\n/*! APB MISC registers. */\n#define APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL 0x8D4\n#define APB_MISC_GP_SDMMC3_CLK_LPBK_CONTROL 0x8D8\n#define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL   0xA98\n#define APB_MISC_GP_VGPIO_GPIO_MUX_SEL      0xB74\n\n/*! Pinmux registers. */\n#define PINMUX_AUX_SDMMC1_CLK      0x00\n#define PINMUX_AUX_SDMMC1_CMD      0x04\n#define PINMUX_AUX_SDMMC1_DAT3     0x08\n#define PINMUX_AUX_SDMMC1_DAT2     0x0C\n#define PINMUX_AUX_SDMMC1_DAT1     0x10\n#define PINMUX_AUX_SDMMC1_DAT0     0x14\n#define PINMUX_AUX_SDMMC3_CLK      0x1C\n#define PINMUX_AUX_SDMMC3_CMD      0x20\n#define PINMUX_AUX_SDMMC3_DAT0     0x24\n#define PINMUX_AUX_SDMMC3_DAT1     0x28\n#define PINMUX_AUX_SDMMC3_DAT2     0x2C\n#define PINMUX_AUX_SDMMC3_DAT3     0x30\n#define PINMUX_AUX_SATA_LED_ACTIVE 0x4C\n#define PINMUX_AUX_DMIC3_CLK       0xB4\n#define PINMUX_AUX_DMIC3_DAT       0xB8\n#define PINMUX_AUX_CAM_I2C_SCL     0xD4\n#define PINMUX_AUX_CAM_I2C_SDA     0xD8\n#define PINMUX_AUX_UART2_TX        0xF4\n#define PINMUX_AUX_UART3_TX        0x104\n#define PINMUX_AUX_DAP4_DIN        0x148\n#define PINMUX_AUX_USB_VBUS_EN0    0x1A8\n#define PINMUX_AUX_WIFI_EN         0x1B4\n#define PINMUX_AUX_WIFI_RST        0x1B8\n#define PINMUX_AUX_DAP4_SCLK       0x150\n#define PINMUX_AUX_GPIO_X1_AUD     0x18C\n#define PINMUX_AUX_GPIO_X3_AUD     0x190\n#define PINMUX_AUX_SPDIF_IN        0x1A4\n#define PINMUX_AUX_AP_WAKE_NFC     0x1CC\n#define PINMUX_AUX_NFC_EN          0x1D0\n#define PINMUX_AUX_NFC_INT         0x1D4\n#define PINMUX_AUX_CAM1_PWDN       0x1EC\n#define PINMUX_AUX_LCD_BL_PWM      0x1FC\n#define PINMUX_AUX_LCD_BL_EN       0x200\n#define PINMUX_AUX_LCD_RST         0x204\n#define PINMUX_AUX_LCD_GPIO2       0x20C\n#define PINMUX_AUX_TOUCH_INT       0x220\n#define PINMUX_AUX_MOTION_INT      0x224\n#define PINMUX_AUX_GPIO_PE6        0x248\n#define PINMUX_AUX_GPIO_PH6        0x250\n#define PINMUX_AUX_GPIO_PZ1        0x280\n/*! 0:UART-A, 1:UART-B, 3:UART-C, 3:UART-D */\n#define PINMUX_AUX_UARTX_TX(x)  (0xE4 + 0x10 * (x))\n#define PINMUX_AUX_UARTX_RX(x)  (0xE8 + 0x10 * (x))\n#define PINMUX_AUX_UARTX_RTS(x) (0xEC + 0x10 * (x))\n#define PINMUX_AUX_UARTX_CTS(x) (0xF0 + 0x10 * (x))\n/*! 0:GEN1, 1:GEN2, 2:GEN3, 3:CAM, 4:PWR */\n#define PINMUX_AUX_X_I2C_SCL(x) (0xBC + 8 * (x))\n#define PINMUX_AUX_X_I2C_SDA(x) (0xC0 + 8 * (x))\n\n#define PINMUX_FUNC_MASK    (3 << 0)\n\n#define PINMUX_PULL_MASK    (3 << 2)\n#define PINMUX_PULL_NONE    (0 << 2)\n#define PINMUX_PULL_DOWN    (1 << 2)\n#define PINMUX_PULL_UP      (2 << 2)\n\n#define PINMUX_TRISTATE     (1 << 4)\n#define PINMUX_PARKED       (1 << 5)\n#define PINMUX_INPUT_ENABLE (1 << 6)\n#define PINMUX_LOCK         (1 << 7)\n#define PINMUX_LPDR         (1 << 8)\n#define PINMUX_HSM          (1 << 9)\n\n#define PINMUX_IO_HV        (1 << 10)\n#define PINMUX_OPEN_DRAIN   (1 << 11)\n#define PINMUX_SCHMT        (1 << 12)\n\n#define PINMUX_DRIVE_1X     (0 << 13) \n#define PINMUX_DRIVE_2X     (1 << 13)\n#define PINMUX_DRIVE_3X     (2 << 13)\n#define PINMUX_DRIVE_4X     (3 << 13)\n\nvoid pinmux_config_uart(u32 idx);\nvoid pinmux_config_i2c(u32 idx);\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/soc/pmc.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 st4rk\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _PMC_H_\n#define _PMC_H_\n\n/*! PMC registers. */\n#define APBDEV_PMC_CNTRL 0x0\n#define  PMC_CNTRL_MAIN_RST (1 << 4)\n#define APBDEV_PMC_SEC_DISABLE 0x4\n#define APBDEV_PMC_PWRGATE_TOGGLE 0x30\n#define APBDEV_PMC_PWRGATE_STATUS 0x38\n#define APBDEV_PMC_NO_IOPOWER 0x44\n#define APBDEV_PMC_SCRATCH0 0x50\n#define APBDEV_PMC_SCRATCH1 0x54\n#define APBDEV_PMC_SCRATCH20 0xA0\n#define APBDEV_PMC_PWR_DET_VAL 0xE4\n#define  PMC_PWR_DET_SDMMC1_IO_EN (1 << 12)\n#define APBDEV_PMC_DDR_PWR 0xE8\n#define APBDEV_PMC_CRYPTO_OP 0xF4\n#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4\n#define APBDEV_PMC_RST_STATUS 0x1B4\n#define APBDEV_PMC_IO_DPD_REQ 0x1B8\n#define APBDEV_PMC_IO_DPD2_REQ 0x1C0\n#define APBDEV_PMC_VDDP_SEL 0x1CC\n#define APBDEV_PMC_DDR_CFG 0x1D0\n#define APBDEV_PMC_SCRATCH49 0x244\n#define APBDEV_PMC_TSC_MULT 0x2B4\n#define APBDEV_PMC_SEC_DISABLE2 0x2C4\n#define APBDEV_PMC_WEAK_BIAS 0x2C8\n#define APBDEV_PMC_REG_SHORT 0x2CC\n#define APBDEV_PMC_SEC_DISABLE3 0x2D8\n#define APBDEV_PMC_SECURE_SCRATCH21 0x334\n#define APBDEV_PMC_SECURE_SCRATCH32 0x360\n#define APBDEV_PMC_SECURE_SCRATCH49 0x3A4\n#define APBDEV_PMC_CNTRL2 0x440\n#define APBDEV_PMC_IO_DPD3_REQ 0x45C\n#define APBDEV_PMC_IO_DPD4_REQ 0x464\n#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4\n#define APBDEV_PMC_UTMIP_PAD_CFG3 0x4CC\n#define APBDEV_PMC_DDR_CNTRL 0x4E4\n#define APBDEV_PMC_SEC_DISABLE4 0x5B0\n#define APBDEV_PMC_SEC_DISABLE5 0x5B4\n#define APBDEV_PMC_SEC_DISABLE6 0x5B8\n#define APBDEV_PMC_SEC_DISABLE7 0x5BC\n#define APBDEV_PMC_SEC_DISABLE8 0x5C0\n#define APBDEV_PMC_SCRATCH188 0x810\n#define APBDEV_PMC_SCRATCH190 0x818\n#define APBDEV_PMC_SCRATCH200 0x840\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/soc/pmc_lp0_t210.h",
    "content": "/*\n * Copyright (c) 2010-2015, NVIDIA CORPORATION.  All rights reserved.\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n */\n\n#ifndef _TEGRA210_PMC_H_\n#define _TEGRA210_PMC_H_\n\n#include \"utils/types.h\"\n\nstruct tegra_pmc_regs\n{\n\tu32 cntrl;\n\tu32 sec_disable;\n\tu32 pmc_swrst;\n\tu32 wake_mask;\n\tu32 wake_lvl;\n\tu32 wake_status;\n\tu32 sw_wake_status;\n\tu32 dpd_pads_oride;\n\tu32 dpd_sample;\n\tu32 dpd_enable;\n\tu32 pwrgate_timer_off;\n\tu32 clamp_status;\n\tu32 pwrgate_toggle;\n\tu32 remove_clamping_cmd;\n\tu32 pwrgate_status;\n\tu32 pwrgood_timer;\n\tu32 blink_timer;\n\tu32 no_iopower;\n\tu32 pwr_det;\n\tu32 pwr_det_latch;\n\tu32 scratch0;\n\tu32 scratch1;\n\tu32 scratch2;\n\tu32 scratch3;\n\tu32 scratch4;\n\tu32 scratch5;\n\tu32 scratch6;\n\tu32 scratch7;\n\tu32 scratch8;\n\tu32 scratch9;\n\tu32 scratch10;\n\tu32 scratch11;\n\tu32 scratch12;\n\tu32 scratch13;\n\tu32 scratch14;\n\tu32 scratch15;\n\tu32 scratch16;\n\tu32 scratch17;\n\tu32 scratch18;\n\tu32 scratch19;\n\tu32 odmdata;\n\tu32 scratch21;\n\tu32 scratch22;\n\tu32 scratch23;\n\tu32 secure_scratch0;\n\tu32 secure_scratch1;\n\tu32 secure_scratch2;\n\tu32 secure_scratch3;\n\tu32 secure_scratch4;\n\tu32 secure_scratch5;\n\tu32 cpupwrgood_timer;\n\tu32 cpupwroff_timer;\n\tu32 pg_mask;\n\tu32 pg_mask_1;\n\tu32 auto_wake_lvl;\n\tu32 auto_wake_lvl_mask;\n\tu32 wake_delay;\n\tu32 pwr_det_val;\n\tu32 ddr_pwr;\n\tu32 usb_debounce_del;\n\tu32 usb_a0;\n\tu32 crypto_op;\n\tu32 pllp_wb0_override;\n\tu32 scratch24;\n\tu32 scratch25;\n\tu32 scratch26;\n\tu32 scratch27;\n\tu32 scratch28;\n\tu32 scratch29;\n\tu32 scratch30;\n\tu32 scratch31;\n\tu32 scratch32;\n\tu32 scratch33;\n\tu32 scratch34;\n\tu32 scratch35;\n\tu32 scratch36;\n\tu32 scratch37;\n\tu32 scratch38;\n\tu32 scratch39;\n\tu32 scratch40;\n\tu32 scratch41;\n\tu32 scratch42;\n\tu32 bondout_mirror[3];\n\tu32 sys_33v_en;\n\tu32 bondout_mirror_access;\n\tu32 gate;\n\tu32 wake2_mask;\n\tu32 wake2_lvl;\n\tu32 wake2_status;\n\tu32 sw_wake2_status;\n\tu32 auto_wake2_lvl_mask;\n\tu32 pg_mask_2;\n\tu32 pg_mask_ce1;\n\tu32 pg_mask_ce2;\n\tu32 pg_mask_ce3;\n\tu32 pwrgate_timer_ce[7];\n\tu32 pcx_edpd_cntrl;\n\tu32 osc_edpd_over;\n\tu32 clk_out_cntrl;\n\tu32 sata_pwrgt;\n\tu32 sensor_ctrl;\n\tu32 rst_status;\n\tu32 io_dpd_req;\n\tu32 io_dpd_status;\n\tu32 io_dpd2_req;\n\tu32 io_dpd2_status;\n\tu32 sel_dpd_tim;\n\tu32 vddp_sel;\n\tu32 ddr_cfg;\n\tu32 e_no_vttgen;\n\tu8 _rsv0[4];\n\tu32 pllm_wb0_override_freq;\n\tu32 test_pwrgate;\n\tu32 pwrgate_timer_mult;\n\tu32 dis_sel_dpd;\n\tu32 utmip_uhsic_triggers;\n\tu32 utmip_uhsic_saved_state;\n\tu32 utmip_pad_cfg;\n\tu32 utmip_term_pad_cfg;\n\tu32 utmip_uhsic_sleep_cfg;\n\tu32 utmip_uhsic_sleepwalk_cfg;\n\tu32 utmip_sleepwalk_p[3];\n\tu32 uhsic_sleepwalk_p0;\n\tu32 utmip_uhsic_status;\n\tu32 utmip_uhsic_fake;\n\tu32 bondout_mirror3[5 - 3];\n\tu32 secure_scratch6;\n\tu32 secure_scratch7;\n\tu32 scratch43;\n\tu32 scratch44;\n\tu32 scratch45;\n\tu32 scratch46;\n\tu32 scratch47;\n\tu32 scratch48;\n\tu32 scratch49;\n\tu32 scratch50;\n\tu32 scratch51;\n\tu32 scratch52;\n\tu32 scratch53;\n\tu32 scratch54;\n\tu32 scratch55;\n\tu32 scratch0_eco;\n\tu32 por_dpd_ctrl;\n\tu32 scratch2_eco;\n\tu32 utmip_uhsic_line_wakeup;\n\tu32 utmip_bias_master_cntrl;\n\tu32 utmip_master_config;\n\tu32 td_pwrgate_inter_part_timer;\n\tu32 utmip_uhsic2_triggers;\n\tu32 utmip_uhsic2_saved_state;\n\tu32 utmip_uhsic2_sleep_cfg;\n\tu32 utmip_uhsic2_sleepwalk_cfg;\n\tu32 uhsic2_sleepwalk_p1;\n\tu32 utmip_uhsic2_status;\n\tu32 utmip_uhsic2_fake;\n\tu32 utmip_uhsic2_line_wakeup;\n\tu32 utmip_master2_config;\n\tu32 utmip_uhsic_rpd_cfg;\n\tu32 pg_mask_ce0;\n\tu32 pg_mask3[5 - 3];\n\tu32 pllm_wb0_override2;\n\tu32 tsc_mult;\n\tu32 cpu_vsense_override;\n\tu32 glb_amap_cfg;\n\tu32 sticky_bits;\n\tu32 sec_disable2;\n\tu32 weak_bias;\n\tu32 reg_short;\n\tu32 pg_mask_andor;\n\tu8 _rsv1[0x2c];\n\tu32 secure_scratch8;\t/* offset 0x300 */\n\tu32 secure_scratch9;\n\tu32 secure_scratch10;\n\tu32 secure_scratch11;\n\tu32 secure_scratch12;\n\tu32 secure_scratch13;\n\tu32 secure_scratch14;\n\tu32 secure_scratch15;\n\tu32 secure_scratch16;\n\tu32 secure_scratch17;\n\tu32 secure_scratch18;\n\tu32 secure_scratch19;\n\tu32 secure_scratch20;\n\tu32 secure_scratch21;\n\tu32 secure_scratch22;\n\tu32 secure_scratch23;\n\tu32 secure_scratch24;\n\tu32 secure_scratch25;\n\tu32 secure_scratch26;\n\tu32 secure_scratch27;\n\tu32 secure_scratch28;\n\tu32 secure_scratch29;\n\tu32 secure_scratch30;\n\tu32 secure_scratch31;\n\tu32 secure_scratch32;\n\tu32 secure_scratch33;\n\tu32 secure_scratch34;\n\tu32 secure_scratch35;\n\tu32 secure_scratch36;\n\tu32 secure_scratch37;\n\tu32 secure_scratch38;\n\tu32 secure_scratch39;\n\tu32 secure_scratch40;\n\tu32 secure_scratch41;\n\tu32 secure_scratch42;\n\tu32 secure_scratch43;\n\tu32 secure_scratch44;\n\tu32 secure_scratch45;\n\tu32 secure_scratch46;\n\tu32 secure_scratch47;\n\tu32 secure_scratch48;\n\tu32 secure_scratch49;\n\tu32 secure_scratch50;\n\tu32 secure_scratch51;\n\tu32 secure_scratch52;\n\tu32 secure_scratch53;\n\tu32 secure_scratch54;\n\tu32 secure_scratch55;\n\tu32 secure_scratch56;\n\tu32 secure_scratch57;\n\tu32 secure_scratch58;\n\tu32 secure_scratch59;\n\tu32 secure_scratch60;\n\tu32 secure_scratch61;\n\tu32 secure_scratch62;\n\tu32 secure_scratch63;\n\tu32 secure_scratch64;\n\tu32 secure_scratch65;\n\tu32 secure_scratch66;\n\tu32 secure_scratch67;\n\tu32 secure_scratch68;\n\tu32 secure_scratch69;\n\tu32 secure_scratch70;\n\tu32 secure_scratch71;\n\tu32 secure_scratch72;\n\tu32 secure_scratch73;\n\tu32 secure_scratch74;\n\tu32 secure_scratch75;\n\tu32 secure_scratch76;\n\tu32 secure_scratch77;\n\tu32 secure_scratch78;\n\tu32 secure_scratch79;\n\tu32 _rsv0x420[8];\n\tu32 cntrl2;\t\t\t/* 0x440 */\n\tu32 _rsv0x444[2];\n\tu32 event_counter;\t/* 0x44C */\n\tu32 fuse_control;\n\tu32 scratch1_eco;\n\tu32 _rsv0x458[1];\n\tu32 io_dpd3_req;\t/* 0x45C */\n\tu32 io_dpd3_status;\n\tu32 io_dpd4_req;\n\tu32 io_dpd4_status;\n\tu32 _rsv0x46C[30];\n\tu32 ddr_cntrl;\t\t/* 0x4E4 */\n\tu32 _rsv0x4E8[70];\n\tu32 scratch56;\t\t/* 0x600 */\n\tu32 scratch57;\n\tu32 scratch58;\n\tu32 scratch59;\n\tu32 scratch60;\n\tu32 scratch61;\n\tu32 scratch62;\n\tu32 scratch63;\n\tu32 scratch64;\n\tu32 scratch65;\n\tu32 scratch66;\n\tu32 scratch67;\n\tu32 scratch68;\n\tu32 scratch69;\n\tu32 scratch70;\n\tu32 scratch71;\n\tu32 scratch72;\n\tu32 scratch73;\n\tu32 scratch74;\n\tu32 scratch75;\n\tu32 scratch76;\n\tu32 scratch77;\n\tu32 scratch78;\n\tu32 scratch79;\n\tu32 scratch80;\n\tu32 scratch81;\n\tu32 scratch82;\n\tu32 scratch83;\n\tu32 scratch84;\n\tu32 scratch85;\n\tu32 scratch86;\n\tu32 scratch87;\n\tu32 scratch88;\n\tu32 scratch89;\n\tu32 scratch90;\n\tu32 scratch91;\n\tu32 scratch92;\n\tu32 scratch93;\n\tu32 scratch94;\n\tu32 scratch95;\n\tu32 scratch96;\n\tu32 scratch97;\n\tu32 scratch98;\n\tu32 scratch99;\n\tu32 scratch100;\n\tu32 scratch101;\n\tu32 scratch102;\n\tu32 scratch103;\n\tu32 scratch104;\n\tu32 scratch105;\n\tu32 scratch106;\n\tu32 scratch107;\n\tu32 scratch108;\n\tu32 scratch109;\n\tu32 scratch110;\n\tu32 scratch111;\n\tu32 scratch112;\n\tu32 scratch113;\n\tu32 scratch114;\n\tu32 scratch115;\n\tu32 scratch116;\n\tu32 scratch117;\n\tu32 scratch118;\n\tu32 scratch119;\n\tu32 scratch120;\t\t/* 0x700 */\n\tu32 scratch121;\n\tu32 scratch122;\n\tu32 scratch123;\n\tu32 scratch124;\n\tu32 scratch125;\n\tu32 scratch126;\n\tu32 scratch127;\n\tu32 scratch128;\n\tu32 scratch129;\n\tu32 scratch130;\n\tu32 scratch131;\n\tu32 scratch132;\n\tu32 scratch133;\n\tu32 scratch134;\n\tu32 scratch135;\n\tu32 scratch136;\n\tu32 scratch137;\n\tu32 scratch138;\n\tu32 scratch139;\n\tu32 scratch140;\n\tu32 scratch141;\n\tu32 scratch142;\n\tu32 scratch143;\n\tu32 scratch144;\n\tu32 scratch145;\n\tu32 scratch146;\n\tu32 scratch147;\n\tu32 scratch148;\n\tu32 scratch149;\n\tu32 scratch150;\n\tu32 scratch151;\n\tu32 scratch152;\n\tu32 scratch153;\n\tu32 scratch154;\n\tu32 scratch155;\n\tu32 scratch156;\n\tu32 scratch157;\n\tu32 scratch158;\n\tu32 scratch159;\n\tu32 scratch160;\n\tu32 scratch161;\n\tu32 scratch162;\n\tu32 scratch163;\n\tu32 scratch164;\n\tu32 scratch165;\n\tu32 scratch166;\n\tu32 scratch167;\n\tu32 scratch168;\n\tu32 scratch169;\n\tu32 scratch170;\n\tu32 scratch171;\n\tu32 scratch172;\n\tu32 scratch173;\n\tu32 scratch174;\n\tu32 scratch175;\n\tu32 scratch176;\n\tu32 scratch177;\n\tu32 scratch178;\n\tu32 scratch179;\n\tu32 scratch180;\n\tu32 scratch181;\n\tu32 scratch182;\n\tu32 scratch183;\n\tu32 scratch184;\n\tu32 scratch185;\n\tu32 scratch186;\n\tu32 scratch187;\n\tu32 scratch188;\n\tu32 scratch189;\n\tu32 scratch190;\n\tu32 scratch191;\n\tu32 scratch192;\n\tu32 scratch193;\n\tu32 scratch194;\n\tu32 scratch195;\n\tu32 scratch196;\n\tu32 scratch197;\n\tu32 scratch198;\n\tu32 scratch199;\n\tu32 scratch200;\n\tu32 scratch201;\n\tu32 scratch202;\n\tu32 scratch203;\n\tu32 scratch204;\n\tu32 scratch205;\n\tu32 scratch206;\n\tu32 scratch207;\n\tu32 scratch208;\n\tu32 scratch209;\n\tu32 scratch210;\n\tu32 scratch211;\n\tu32 scratch212;\n\tu32 scratch213;\n\tu32 scratch214;\n\tu32 scratch215;\n\tu32 scratch216;\n\tu32 scratch217;\n\tu32 scratch218;\n\tu32 scratch219;\n\tu32 scratch220;\n\tu32 scratch221;\n\tu32 scratch222;\n\tu32 scratch223;\n\tu32 scratch224;\n\tu32 scratch225;\n\tu32 scratch226;\n\tu32 scratch227;\n\tu32 scratch228;\n\tu32 scratch229;\n\tu32 scratch230;\n\tu32 scratch231;\n\tu32 scratch232;\n\tu32 scratch233;\n\tu32 scratch234;\n\tu32 scratch235;\n\tu32 scratch236;\n\tu32 scratch237;\n\tu32 scratch238;\n\tu32 scratch239;\n\tu32 scratch240;\n\tu32 scratch241;\n\tu32 scratch242;\n\tu32 scratch243;\n\tu32 scratch244;\n\tu32 scratch245;\n\tu32 scratch246;\n\tu32 scratch247;\n\tu32 scratch248;\n\tu32 scratch249;\n\tu32 scratch250;\n\tu32 scratch251;\n\tu32 scratch252;\n\tu32 scratch253;\n\tu32 scratch254;\n\tu32 scratch255;\n\tu32 scratch256;\n\tu32 scratch257;\n\tu32 scratch258;\n\tu32 scratch259;\n\tu32 scratch260;\n\tu32 scratch261;\n\tu32 scratch262;\n\tu32 scratch263;\n\tu32 scratch264;\n\tu32 scratch265;\n\tu32 scratch266;\n\tu32 scratch267;\n\tu32 scratch268;\n\tu32 scratch269;\n\tu32 scratch270;\n\tu32 scratch271;\n\tu32 scratch272;\n\tu32 scratch273;\n\tu32 scratch274;\n\tu32 scratch275;\n\tu32 scratch276;\n\tu32 scratch277;\n\tu32 scratch278;\n\tu32 scratch279;\n\tu32 scratch280;\n\tu32 scratch281;\n\tu32 scratch282;\n\tu32 scratch283;\n\tu32 scratch284;\n\tu32 scratch285;\n\tu32 scratch286;\n\tu32 scratch287;\n\tu32 scratch288;\n\tu32 scratch289;\n\tu32 scratch290;\n\tu32 scratch291;\n\tu32 scratch292;\n\tu32 scratch293;\n\tu32 scratch294;\n\tu32 scratch295;\n\tu32 scratch296;\n\tu32 scratch297;\n\tu32 scratch298;\n\tu32 scratch299;\t\t\t/* 0x9CC */\n\tu32 _rsv0x9D0[50];\n\tu32 secure_scratch80;\t/* 0xa98 */\n\tu32 secure_scratch81;\n\tu32 secure_scratch82;\n\tu32 secure_scratch83;\n\tu32 secure_scratch84;\n\tu32 secure_scratch85;\n\tu32 secure_scratch86;\n\tu32 secure_scratch87;\n\tu32 secure_scratch88;\n\tu32 secure_scratch89;\n\tu32 secure_scratch90;\n\tu32 secure_scratch91;\n\tu32 secure_scratch92;\n\tu32 secure_scratch93;\n\tu32 secure_scratch94;\n\tu32 secure_scratch95;\n\tu32 secure_scratch96;\n\tu32 secure_scratch97;\n\tu32 secure_scratch98;\n\tu32 secure_scratch99;\n\tu32 secure_scratch100;\n\tu32 secure_scratch101;\n\tu32 secure_scratch102;\n\tu32 secure_scratch103;\n\tu32 secure_scratch104;\n\tu32 secure_scratch105;\n\tu32 secure_scratch106;\n\tu32 secure_scratch107;\n\tu32 secure_scratch108;\n\tu32 secure_scratch109;\n\tu32 secure_scratch110;\n\tu32 secure_scratch111;\n\tu32 secure_scratch112;\n\tu32 secure_scratch113;\n\tu32 secure_scratch114;\n\tu32 secure_scratch115;\n\tu32 secure_scratch116;\n\tu32 secure_scratch117;\n\tu32 secure_scratch118;\n\tu32 secure_scratch119;\n};\n\n#endif\t/* _TEGRA210_PMC_H_ */\n"
  },
  {
    "path": "argon-nx-gui/include/soc/smmu.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"utils/types.h\"\n\n#define SMMU_HEAP_ADDR 0xA0000000\n\n#define MC_INTSTATUS                 0x0\n#define MC_INTMASK                   0x4\n#define MC_ERR_STATUS                0x8\n#define MC_ERR_ADR                   0xc\n#define MC_SMMU_CONFIG               0x10\n#define MC_SMMU_TLB_CONFIG           0x14\n#define MC_SMMU_PTC_CONFIG           0x18\n#define MC_SMMU_PTB_ASID             0x1c\n#define MC_SMMU_PTB_DATA             0x20\n#define MC_SMMU_TLB_FLUSH            0x30\n#define MC_SMMU_PTC_FLUSH            0x34\n#define MC_SMMU_ASID_SECURITY        0x38\n#define MC_SMMU_TSEC_ASID            0x294\n#define MC_SMMU_TRANSLATION_ENABLE_0 0x228\n#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c\n#define MC_SMMU_TRANSLATION_ENABLE_2 0x230\n#define MC_SMMU_TRANSLATION_ENABLE_3 0x234\n#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98\n\n#define SMMU_PDE_NEXT_SHIFT 28\n#define MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT 29\n#define MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT  30\n#define MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT  31\n#define SMMU_PAGE_SHIFT 12\n#define SMMU_PAGE_SIZE  (1 << SMMU_PAGE_SHIFT)\n#define SMMU_PDIR_COUNT 1024\n#define SMMU_PDIR_SIZE  (sizeof(u32) * SMMU_PDIR_COUNT)\n#define SMMU_PTBL_COUNT 1024\n#define SMMU_PTBL_SIZE  (sizeof(u32) * SMMU_PTBL_COUNT)\n#define SMMU_PDIR_SHIFT 12\n#define SMMU_PDE_SHIFT  12\n#define SMMU_PTE_SHIFT  12\n#define SMMU_PFN_MASK   0x000FFFFF\n#define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12)\n#define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22)\n#define SMMU_PDN_TO_ADDR(addr) ((pdn) << 22)\n#define _READABLE  (1 << MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT)\n#define _WRITABLE  (1 << MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT)\n#define _NONSECURE (1 << MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT)\n#define _PDE_NEXT  (1 << SMMU_PDE_NEXT_SHIFT)\n#define _MASK_ATTR (_READABLE | _WRITABLE | _NONSECURE)\n#define _PDIR_ATTR (_READABLE | _WRITABLE | _NONSECURE)\n#define _PDE_ATTR  (_READABLE | _WRITABLE | _NONSECURE)\n#define _PDE_VACANT(pdn) (((pdn) << 10) | _PDE_ATTR)\n#define _PTE_ATTR  (_READABLE | _WRITABLE | _NONSECURE)\n#define _PTE_VACANT(addr) (((addr) >> SMMU_PAGE_SHIFT) | _PTE_ATTR)\n#define SMMU_MK_PDIR(page, attr) (((page) >> SMMU_PDIR_SHIFT) | (attr))\n#define SMMU_MK_PDE(page, attr)  (((page) >> SMMU_PDE_SHIFT) | (attr))\n\nvoid *page_alloc(u32 num);\nu32 *smmu_alloc_pdir();\nvoid smmu_flush_regs();\nvoid smmu_flush_all();\nvoid smmu_init(u32 secmon_base);\nvoid smmu_enable();\nbool smmu_is_used();\nvoid smmu_exit();\nu32 *smmu_init_domain4(u32 dev_base, u32 asid);\nu32 *smmu_get_pte(u32 *pdir, u32 iova);\nvoid smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr);\nu32 *smmu_init_for_tsec();\nvoid smmu_deinit_for_tsec();\n"
  },
  {
    "path": "argon-nx-gui/include/soc/t210.h",
    "content": "/*\n* Copyright (c) 2018 naehrwert\n*\n* This program is free software; you can redistribute it and/or modify it\n* under the terms and conditions of the GNU General Public License,\n* version 2, as published by the Free Software Foundation.\n*\n* This program is distributed in the hope it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _T210_H_\n#define _T210_H_\n\n#include \"utils/types.h\"\n\n#define BOOTROM_BASE 0x100000\n#define HOST1X_BASE 0x50000000\n#define BPMP_CACHE_BASE 0x50040000\n#define DISPLAY_A_BASE 0x54200000\n#define DSI_BASE 0x54300000\n#define VIC_BASE 0x54340000\n#define TSEC_BASE 0x54500000\n#define SOR1_BASE 0x54580000\n#define TMR_BASE 0x60005000\n#define CLOCK_BASE 0x60006000\n#define FLOW_CTLR_BASE 0x60007000\n#define SYSREG_BASE 0x6000C000\n#define SB_BASE (SYSREG_BASE + 0x200)\n#define GPIO_BASE 0x6000D000\n#define GPIO_1_BASE (GPIO_BASE)\n#define GPIO_2_BASE (GPIO_BASE + 0x100)\n#define GPIO_3_BASE (GPIO_BASE + 0x200)\n#define GPIO_4_BASE (GPIO_BASE + 0x300)\n#define GPIO_5_BASE (GPIO_BASE + 0x400)\n#define GPIO_6_BASE (GPIO_BASE + 0x500)\n#define GPIO_7_BASE (GPIO_BASE + 0x600)\n#define GPIO_8_BASE (GPIO_BASE + 0x700)\n#define EXCP_VEC_BASE 0x6000F000\n#define IPATCH_BASE 0x6001DC00\n#define APB_MISC_BASE 0x70000000\n#define PINMUX_AUX_BASE 0x70003000\n#define UART_BASE 0x70006000\n#define PWM_BASE 0x7000A000\n#define RTC_BASE 0x7000E000\n#define PMC_BASE 0x7000E400\n#define SYSCTR0_BASE 0x700F0000\n#define FUSE_BASE 0x7000F800\n#define KFUSE_BASE 0x7000FC00\n#define SE_BASE 0x70012000\n#define MC_BASE 0x70019000\n#define EMC_BASE 0x7001B000\n#define MIPI_CAL_BASE 0x700E3000\n#define CL_DVFS_BASE 0x70110000\n#define I2S_BASE 0x702D1000\n#define TZRAM_BASE 0x7C010000\n\n#define _REG(base, off) *(vu32 *)((base) + (off))\n\n#define HOST1X(off) _REG(HOST1X_BASE, off)\n#define BPMP_CACHE_CTRL(off) _REG(BPMP_CACHE_BASE, off)\n#define DISPLAY_A(off) _REG(DISPLAY_A_BASE, off)\n#define DSI(off) _REG(DSI_BASE, off)\n#define VIC(off) _REG(VIC_BASE, off)\n#define TSEC(off) _REG(TSEC_BASE, off)\n#define SOR1(off) _REG(SOR1_BASE, off)\n#define TMR(off) _REG(TMR_BASE, off)\n#define CLOCK(off) _REG(CLOCK_BASE, off)\n#define FLOW_CTLR(off) _REG(FLOW_CTLR_BASE, off)\n#define SYSREG(off) _REG(SYSREG_BASE, off)\n#define SB(off) _REG(SB_BASE, off)\n#define GPIO(off) _REG(GPIO_BASE, off)\n#define GPIO_1(off) _REG(GPIO_1_BASE, off)\n#define GPIO_2(off) _REG(GPIO_2_BASE, off)\n#define GPIO_3(off) _REG(GPIO_3_BASE, off)\n#define GPIO_4(off) _REG(GPIO_4_BASE, off)\n#define GPIO_5(off) _REG(GPIO_5_BASE, off)\n#define GPIO_6(off) _REG(GPIO_6_BASE, off)\n#define GPIO_7(off) _REG(GPIO_7_BASE, off)\n#define GPIO_8(off) _REG(GPIO_8_BASE, off)\n#define EXCP_VEC(off) _REG(EXCP_VEC_BASE, off)\n#define APB_MISC(off) _REG(APB_MISC_BASE, off)\n#define PINMUX_AUX(off) _REG(PINMUX_AUX_BASE, off)\n#define PWM(off) _REG(PWM_BASE, off)\n#define RTC(off) _REG(RTC_BASE, off)\n#define PMC(off) _REG(PMC_BASE, off)\n#define SYSCTR0(off) _REG(SYSCTR0_BASE, off)\n#define FUSE(off) _REG(FUSE_BASE, off)\n#define KFUSE(off) _REG(KFUSE_BASE, off)\n#define SE(off) _REG(SE_BASE, off)\n#define MC(off) _REG(MC_BASE, off)\n#define EMC(off) _REG(EMC_BASE, off)\n#define MIPI_CAL(off) _REG(MIPI_CAL_BASE, off)\n#define I2S(off) _REG(I2S_BASE, off)\n#define CL_DVFS(off) _REG(CL_DVFS_BASE, off)\n#define TEST_REG(off) _REG(0x0, off)\n\n/*! EVP registers. */\n#define EVP_CPU_RESET_VECTOR 0x100\n\n/*! Misc registers. */\n#define APB_MISC_PP_STRAPPING_OPT_A 0x08\n#define APB_MISC_PP_PINMUX_GLOBAL 0x40\n#define APB_MISC_GP_LCD_BL_PWM_CFGPADCTRL 0xA34\n#define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL 0xA98\n#define APB_MISC_GP_EMMC4_PAD_CFGPADCTRL 0xAB4\n#define APB_MISC_GP_WIFI_EN_CFGPADCTRL 0xB64\n#define APB_MISC_GP_WIFI_RST_CFGPADCTRL 0xB68\n\n/*! System registers. */\n#define AHB_ARBITRATION_XBAR_CTRL 0xE0\n#define AHB_AHB_SPARE_REG 0x110\n\n/*! Secure boot registers. */\n#define SB_CSR 0x0\n#define SB_AA64_RESET_LOW  0x30\n#define SB_AA64_RESET_HIGH 0x34\n\n/*! SOR registers. */\n#define SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB   0x1E8\n#define SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB 0x21C\n#define SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB   0x208\n#define SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB   0x20C\n\n/*! RTC registers. */\n#define APBDEV_RTC_SECONDS        0x8\n#define APBDEV_RTC_SHADOW_SECONDS 0xC\n#define APBDEV_RTC_MILLI_SECONDS  0x10\n\n/*! SYSCTR0 registers. */\n#define SYSCTR0_CNTFID0     0x20\n#define SYSCTR0_CNTCR       0x00\n#define SYSCTR0_COUNTERID0  0xFE0\n#define SYSCTR0_COUNTERID1  0xFE4\n#define SYSCTR0_COUNTERID2  0xFE8\n#define SYSCTR0_COUNTERID3  0xFEC\n#define SYSCTR0_COUNTERID4  0xFD0\n#define SYSCTR0_COUNTERID5  0xFD4\n#define SYSCTR0_COUNTERID6  0xFD8\n#define SYSCTR0_COUNTERID7  0xFDC\n#define SYSCTR0_COUNTERID8  0xFF0\n#define SYSCTR0_COUNTERID9  0xFF4\n#define SYSCTR0_COUNTERID10 0xFF8 \n#define SYSCTR0_COUNTERID11 0xFFC\n\n/*! TMR registers. */\n#define TIMERUS_CNTR_1US          (0x10 + 0x0)\n#define TIMERUS_USEC_CFG          (0x10 + 0x4)\n#define TIMER_TMR9_TMR_PTV        0x80\n#define  TIMER_EN     (1 << 31)\n#define  TIMER_PER_EN (1 << 30)\n#define TIMER_WDT4_CONFIG         (0x100 + 0x80)\n#define  TIMER_SRC(TMR) (TMR & 0xF)\n#define  TIMER_PER(PER) ((PER & 0xFF) << 4)\n#define  TIMER_SYSRESET_EN (1 << 14)\n#define  TIMER_PMCRESET_EN (1 << 15)\n#define TIMER_WDT4_COMMAND        (0x108 + 0x80)\n#define  TIMER_START_CNT   (1 << 0)\n#define  TIMER_CNT_DISABLE (1 << 1)\n#define TIMER_WDT4_UNLOCK_PATTERN (0x10C + 0x80)\n#define  TIMER_MAGIC_PTRN 0xC45A\n\n/*! I2S registers. */\n#define I2S1_CG   0x88\n#define I2S1_CTRL 0xA0\n#define I2S2_CG   0x188\n#define I2S2_CTRL 0x1A0\n#define I2S3_CG   0x288\n#define I2S3_CTRL 0x2A0\n#define I2S4_CG   0x388\n#define I2S4_CTRL 0x3A0\n#define I2S5_CG   0x488\n#define I2S5_CTRL 0x4A0\n#define  I2S_CG_SLCG_ENABLE (1 << 0)\n#define  I2S_CTRL_MASTER_EN (1 << 10)\n\n/*! PWM registers. */\n#define PWM_CONTROLLER_PWM_CSR_0 0x00\n#define PWM_CONTROLLER_PWM_CSR_1 0x10\n\n/*! Special registers. */\n#define EMC_SCRATCH0 0x324\n#define  EMC_HEKA_UPD (1 << 30)\n#define  EMC_SEPT_RUN (1 << 31)\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/soc/uart.h",
    "content": "/*\n* Copyright (c) 2018 naehrwert\n*\n* This program is free software; you can redistribute it and/or modify it\n* under the terms and conditions of the GNU General Public License,\n* version 2, as published by the Free Software Foundation.\n*\n* This program is distributed in the hope it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _UART_H_\n#define _UART_H_\n\n#include \"utils/types.h\"\n\n#define UART_A 0\n#define UART_B 1\n#define UART_C 2\n//TODO: define clock inits for those.\n/*#define UART_D 3\n#define UART_E 4*/\n\n#define BAUD_115200 115200\n\n#define UART_TX_IDLE 0x1\n#define UART_RX_IDLE 0x2\n\n#define UART_TX_FIFO_FULL 0x100\n#define UART_RX_FIFO_EMPTY 0x200\n\n#define UART_LCR_DLAB 0x80\n#define UART_LCR_WORD_LENGTH_8 0x3\n#define UART_LSR_RDR 0x1\n#define UART_LSR_THRE 0x20\n#define UART_LSR_TMTY 0x40\n#define UART_IIR_FCR_TX_CLR 0x4\n#define UART_IIR_FCR_RX_CLR 0x2\n#define UART_IIR_FCR_EN_FIFO 0x1\n\ntypedef struct _uart_t\n{\n\t/* 0x00 */ vu32 UART_THR_DLAB;\n\t/* 0x04 */ vu32 UART_IER_DLAB;\n\t/* 0x08 */ vu32 UART_IIR_FCR;\n\t/* 0x0C */ vu32 UART_LCR;\n\t/* 0x10 */ vu32 UART_MCR;\n\t/* 0x14 */ vu32 UART_LSR;\n\t/* 0x18 */ vu32 UART_MSR;\n\t/* 0x1C */ vu32 UART_SPR;\n\t/* 0x20 */ vu32 UART_IRDA_CSR;\n\t/* 0x24 */ vu32 UART_RX_FIFO_CFG;\n\t/* 0x28 */ vu32 UART_MIE;\n\t/* 0x2C */ vu32 UART_VENDOR_STATUS;\n\t/* 0x30 */ u8 _pad_30[0xC];\n\t/* 0x3C */ vu32 UART_ASR;\n} uart_t;\n\nvoid uart_init(u32 idx, u32 baud);\nvoid uart_wait_idle(u32 idx, u32 which);\nvoid uart_send(u32 idx, u8 *buf, u32 len);\nvoid uart_recv(u32 idx, u8 *buf, u32 len);\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/storage/mmc.h",
    "content": "/*\n * Header for MultiMediaCard (MMC)\n *\n * Copyright 2002 Hewlett-Packard Company\n *\n * Use consistent with the GNU GPL is permitted,\n * provided that this copyright notice is\n * preserved in its entirety in all copies and derived works.\n *\n * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,\n * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS\n * FITNESS FOR ANY PARTICULAR PURPOSE.\n *\n * Many thanks to Alessandro Rubini and Jonathan Corbet!\n *\n * Based strongly on code by:\n *\n * Author: Yong-iL Joh <tolkien@mizi.com>\n *\n * Author:  Andrew Christian\n *          15 May 2002\n */\n\n#ifndef LINUX_MMC_MMC_H\n#define LINUX_MMC_MMC_H\n\n/* Standard MMC commands (4.1)           type  argument     response */\n/* class 1 */\n#define MMC_GO_IDLE_STATE         0   /* bc                          */\n#define MMC_SEND_OP_COND          1   /* bcr  [31:0] OCR         R3  */\n#define MMC_ALL_SEND_CID          2   /* bcr                     R2  */\n#define MMC_SET_RELATIVE_ADDR     3   /* ac   [31:16] RCA        R1  */\n#define MMC_SET_DSR               4   /* bc   [31:16] RCA            */\n#define MMC_SLEEP_AWAKE\t\t  5   /* ac   [31:16] RCA 15:flg R1b */\n#define MMC_SWITCH                6   /* ac   [31:0] See below   R1b */\n#define MMC_SELECT_CARD           7   /* ac   [31:16] RCA        R1  */\n#define MMC_SEND_EXT_CSD          8   /* adtc                    R1  */\n#define MMC_SEND_CSD              9   /* ac   [31:16] RCA        R2  */\n#define MMC_SEND_CID             10   /* ac   [31:16] RCA        R2  */\n#define MMC_READ_DAT_UNTIL_STOP  11   /* adtc [31:0] dadr        R1  */\n#define MMC_STOP_TRANSMISSION    12   /* ac                      R1b */\n#define MMC_SEND_STATUS          13   /* ac   [31:16] RCA        R1  */\n#define MMC_BUS_TEST_R           14   /* adtc                    R1  */\n#define MMC_GO_INACTIVE_STATE    15   /* ac   [31:16] RCA            */\n#define MMC_BUS_TEST_W           19   /* adtc                    R1  */\n#define MMC_SPI_READ_OCR         58   /* spi                  spi_R3 */\n#define MMC_SPI_CRC_ON_OFF       59   /* spi  [0:0] flag      spi_R1 */\n\n/* class 2 */\n#define MMC_SET_BLOCKLEN         16   /* ac   [31:0] block len   R1  */\n#define MMC_READ_SINGLE_BLOCK    17   /* adtc [31:0] data addr   R1  */\n#define MMC_READ_MULTIPLE_BLOCK  18   /* adtc [31:0] data addr   R1  */\n#define MMC_SEND_TUNING_BLOCK    19   /* adtc                    R1  */\n#define MMC_SEND_TUNING_BLOCK_HS200\t21\t/* adtc R1  */\n\n/* class 3 */\n#define MMC_WRITE_DAT_UNTIL_STOP 20   /* adtc [31:0] data addr   R1  */\n\n/* class 4 */\n#define MMC_SET_BLOCK_COUNT      23   /* adtc [31:0] data addr   R1  */\n#define MMC_WRITE_BLOCK          24   /* adtc [31:0] data addr   R1  */\n#define MMC_WRITE_MULTIPLE_BLOCK 25   /* adtc                    R1  */\n#define MMC_PROGRAM_CID          26   /* adtc                    R1  */\n#define MMC_PROGRAM_CSD          27   /* adtc                    R1  */\n\n/* class 6 */\n#define MMC_SET_WRITE_PROT       28   /* ac   [31:0] data addr   R1b */\n#define MMC_CLR_WRITE_PROT       29   /* ac   [31:0] data addr   R1b */\n#define MMC_SEND_WRITE_PROT      30   /* adtc [31:0] wpdata addr R1  */\n\n/* class 5 */\n#define MMC_ERASE_GROUP_START    35   /* ac   [31:0] data addr   R1  */\n#define MMC_ERASE_GROUP_END      36   /* ac   [31:0] data addr   R1  */\n#define MMC_ERASE                38   /* ac                      R1b */\n\n/* class 9 */\n#define MMC_FAST_IO              39   /* ac   <Complex>          R4  */\n#define MMC_GO_IRQ_STATE         40   /* bcr                     R5  */\n\n/* class 7 */\n#define MMC_LOCK_UNLOCK          42   /* adtc                    R1b */\n\n/* class 8 */\n#define MMC_APP_CMD              55   /* ac   [31:16] RCA        R1  */\n#define MMC_GEN_CMD              56   /* adtc [0] RD/WR          R1  */\n\n/* class 11 */\n#define MMC_QUE_TASK_PARAMS      44   /* ac   [20:16] task id    R1  */\n#define MMC_QUE_TASK_ADDR        45   /* ac   [31:0] data addr   R1  */\n#define MMC_EXECUTE_READ_TASK    46   /* adtc [20:16] task id    R1  */\n#define MMC_EXECUTE_WRITE_TASK   47   /* adtc [20:16] task id    R1  */\n#define MMC_CMDQ_TASK_MGMT       48   /* ac   [20:16] task id    R1b */\n\n/*\n* MMC_SWITCH argument format:\n*\n*\t[31:26] Always 0\n*\t[25:24] Access Mode\n*\t[23:16] Location of target Byte in EXT_CSD\n*\t[15:08] Value Byte\n*\t[07:03] Always 0\n*\t[02:00] Command Set\n*/\n\n/*\nMMC status in R1, for native mode (SPI bits are different)\nType\ne : error bit\ns : status bit\nr : detected and set for the actual command response\nx : detected and set during command execution. the host must poll\nthe card by sending status command in order to read these bits.\nClear condition\na : according to the card state\nb : always related to the previous command. Reception of\na valid command will clear it (with a delay of one command)\nc : clear by read\n*/\n\n#define R1_OUT_OF_RANGE\t\t(1 << 31)\t/* er, c */\n#define R1_ADDRESS_ERROR\t(1 << 30)\t/* erx, c */\n#define R1_BLOCK_LEN_ERROR\t(1 << 29)\t/* er, c */\n#define R1_ERASE_SEQ_ERROR      (1 << 28)\t/* er, c */\n#define R1_ERASE_PARAM\t\t(1 << 27)\t/* ex, c */\n#define R1_WP_VIOLATION\t\t(1 << 26)\t/* erx, c */\n#define R1_CARD_IS_LOCKED\t(1 << 25)\t/* sx, a */\n#define R1_LOCK_UNLOCK_FAILED\t(1 << 24)\t/* erx, c */\n#define R1_COM_CRC_ERROR\t(1 << 23)\t/* er, b */\n#define R1_ILLEGAL_COMMAND\t(1 << 22)\t/* er, b */\n#define R1_CARD_ECC_FAILED\t(1 << 21)\t/* ex, c */\n#define R1_CC_ERROR\t\t(1 << 20)\t/* erx, c */\n#define R1_ERROR\t\t(1 << 19)\t/* erx, c */\n#define R1_UNDERRUN\t\t(1 << 18)\t/* ex, c */\n#define R1_OVERRUN\t\t(1 << 17)\t/* ex, c */\n#define R1_CID_CSD_OVERWRITE\t(1 << 16)\t/* erx, c, CID/CSD overwrite */\n#define R1_WP_ERASE_SKIP\t(1 << 15)\t/* sx, c */\n#define R1_CARD_ECC_DISABLED\t(1 << 14)\t/* sx, a */\n#define R1_ERASE_RESET\t\t(1 << 13)\t/* sr, c */\n#define R1_STATUS(x)            (x & 0xFFFFE000)\n#define R1_CURRENT_STATE(x)\t((x & 0x00001E00) >> 9)\t/* sx, b (4 bits) */\n#define R1_READY_FOR_DATA\t(1 << 8)\t/* sx, a */\n#define R1_SWITCH_ERROR\t\t(1 << 7)\t/* sx, c */\n#define R1_EXCEPTION_EVENT\t(1 << 6)\t/* sr, a */\n#define R1_APP_CMD\t\t(1 << 5)\t/* sr, c */\n\n#define R1_STATE_IDLE\t0\n#define R1_STATE_READY\t1\n#define R1_STATE_IDENT\t2\n#define R1_STATE_STBY\t3\n#define R1_STATE_TRAN\t4\n#define R1_STATE_DATA\t5\n#define R1_STATE_RCV\t6\n#define R1_STATE_PRG\t7\n#define R1_STATE_DIS\t8\n\n/*\n* MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS\n* R1 is the low order byte; R2 is the next highest byte, when present.\n*/\n#define R1_SPI_IDLE\t\t(1 << 0)\n#define R1_SPI_ERASE_RESET\t(1 << 1)\n#define R1_SPI_ILLEGAL_COMMAND\t(1 << 2)\n#define R1_SPI_COM_CRC\t\t(1 << 3)\n#define R1_SPI_ERASE_SEQ\t(1 << 4)\n#define R1_SPI_ADDRESS\t\t(1 << 5)\n#define R1_SPI_PARAMETER\t(1 << 6)\n/* R1 bit 7 is always zero */\n#define R2_SPI_CARD_LOCKED\t(1 << 8)\n#define R2_SPI_WP_ERASE_SKIP\t(1 << 9)\t/* or lock/unlock fail */\n#define R2_SPI_LOCK_UNLOCK_FAIL\tR2_SPI_WP_ERASE_SKIP\n#define R2_SPI_ERROR\t\t(1 << 10)\n#define R2_SPI_CC_ERROR\t\t(1 << 11)\n#define R2_SPI_CARD_ECC_ERROR\t(1 << 12)\n#define R2_SPI_WP_VIOLATION\t(1 << 13)\n#define R2_SPI_ERASE_PARAM\t(1 << 14)\n#define R2_SPI_OUT_OF_RANGE\t(1 << 15)\t/* or CSD overwrite */\n#define R2_SPI_CSD_OVERWRITE\tR2_SPI_OUT_OF_RANGE\n\n/*\n* OCR bits are mostly in host.h\n*/\n#define MMC_CARD_BUSY\t0x80000000\t/* Card Power up status bit */\n\n/*\n* Card Command Classes (CCC)\n*/\n#define CCC_BASIC\t\t(1<<0)\t/* (0) Basic protocol functions */\n/* (CMD0,1,2,3,4,7,9,10,12,13,15) */\n/* (and for SPI, CMD58,59) */\n#define CCC_STREAM_READ\t\t(1<<1)\t/* (1) Stream read commands */\n/* (CMD11) */\n#define CCC_BLOCK_READ\t\t(1<<2)\t/* (2) Block read commands */\n/* (CMD16,17,18) */\n#define CCC_STREAM_WRITE\t(1<<3)\t/* (3) Stream write commands */\n/* (CMD20) */\n#define CCC_BLOCK_WRITE\t\t(1<<4)\t/* (4) Block write commands */\n/* (CMD16,24,25,26,27) */\n#define CCC_ERASE\t\t(1<<5)\t/* (5) Ability to erase blocks */\n/* (CMD32,33,34,35,36,37,38,39) */\n#define CCC_WRITE_PROT\t\t(1<<6)\t/* (6) Able to write protect blocks */\n/* (CMD28,29,30) */\n#define CCC_LOCK_CARD\t\t(1<<7)\t/* (7) Able to lock down card */\n/* (CMD16,CMD42) */\n#define CCC_APP_SPEC\t\t(1<<8)\t/* (8) Application specific */\n/* (CMD55,56,57,ACMD*) */\n#define CCC_IO_MODE\t\t(1<<9)\t/* (9) I/O mode */\n/* (CMD5,39,40,52,53) */\n#define CCC_SWITCH\t\t(1<<10)\t/* (10) High speed switch */\n/* (CMD6,34,35,36,37,50) */\n/* (11) Reserved */\n/* (CMD?) */\n\n/*\n* CSD field definitions\n*/\n\n#define CSD_STRUCT_VER_1_0  0           /* Valid for system specification 1.0 - 1.2 */\n#define CSD_STRUCT_VER_1_1  1           /* Valid for system specification 1.4 - 2.2 */\n#define CSD_STRUCT_VER_1_2  2           /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */\n#define CSD_STRUCT_EXT_CSD  3           /* Version is coded in CSD_STRUCTURE in EXT_CSD */\n\n#define CSD_SPEC_VER_0      0           /* Implements system specification 1.0 - 1.2 */\n#define CSD_SPEC_VER_1      1           /* Implements system specification 1.4 */\n#define CSD_SPEC_VER_2      2           /* Implements system specification 2.0 - 2.2 */\n#define CSD_SPEC_VER_3      3           /* Implements system specification 3.1 - 3.2 - 3.31 */\n#define CSD_SPEC_VER_4      4           /* Implements system specification 4.0 - 4.1 */\n\n/*\n* EXT_CSD fields\n*/\n\n#define EXT_CSD_CMDQ_MODE_EN\t\t15\t/* R/W */\n#define EXT_CSD_FLUSH_CACHE\t\t32      /* W */\n#define EXT_CSD_CACHE_CTRL\t\t33      /* R/W */\n#define EXT_CSD_POWER_OFF_NOTIFICATION\t34\t/* R/W */\n#define EXT_CSD_PACKED_FAILURE_INDEX\t35\t/* RO */\n#define EXT_CSD_PACKED_CMD_STATUS\t36\t/* RO */\n#define EXT_CSD_EXP_EVENTS_STATUS\t54\t/* RO, 2 bytes */\n#define EXT_CSD_EXP_EVENTS_CTRL\t\t56\t/* R/W, 2 bytes */\n#define EXT_CSD_DATA_SECTOR_SIZE\t61\t/* R */\n#define EXT_CSD_GP_SIZE_MULT\t\t143\t/* R/W */\n#define EXT_CSD_PARTITION_SETTING_COMPLETED 155\t/* R/W */\n#define EXT_CSD_PARTITION_ATTRIBUTE\t156\t/* R/W */\n#define EXT_CSD_PARTITION_SUPPORT\t160\t/* RO */\n#define EXT_CSD_HPI_MGMT\t\t161\t/* R/W */\n#define EXT_CSD_RST_N_FUNCTION\t\t162\t/* R/W */\n#define EXT_CSD_BKOPS_EN\t\t163\t/* R/W */\n#define EXT_CSD_BKOPS_START\t\t164\t/* W */\n#define EXT_CSD_SANITIZE_START\t\t165     /* W */\n#define EXT_CSD_WR_REL_PARAM\t\t166\t/* RO */\n#define EXT_CSD_RPMB_MULT\t\t168\t/* RO */\n#define EXT_CSD_FW_CONFIG\t\t169\t/* R/W */\n#define EXT_CSD_BOOT_WP\t\t\t173\t/* R/W */\n#define EXT_CSD_ERASE_GROUP_DEF\t\t175\t/* R/W */\n#define EXT_CSD_PART_CONFIG\t\t179\t/* R/W */\n#define EXT_CSD_ERASED_MEM_CONT\t\t181\t/* RO */\n#define EXT_CSD_BUS_WIDTH\t\t183\t/* R/W */\n#define EXT_CSD_STROBE_SUPPORT\t\t184\t/* RO */\n#define EXT_CSD_HS_TIMING\t\t185\t/* R/W */\n#define EXT_CSD_POWER_CLASS\t\t187\t/* R/W */\n#define EXT_CSD_REV\t\t\t192\t/* RO */\n#define EXT_CSD_STRUCTURE\t\t194\t/* RO */\n#define EXT_CSD_CARD_TYPE\t\t196\t/* RO */\n#define EXT_CSD_DRIVER_STRENGTH\t\t197\t/* RO */\n#define EXT_CSD_OUT_OF_INTERRUPT_TIME\t198\t/* RO */\n#define EXT_CSD_PART_SWITCH_TIME        199     /* RO */\n#define EXT_CSD_PWR_CL_52_195\t\t200\t/* RO */\n#define EXT_CSD_PWR_CL_26_195\t\t201\t/* RO */\n#define EXT_CSD_PWR_CL_52_360\t\t202\t/* RO */\n#define EXT_CSD_PWR_CL_26_360\t\t203\t/* RO */\n#define EXT_CSD_SEC_CNT\t\t\t212\t/* RO, 4 bytes */\n#define EXT_CSD_S_A_TIMEOUT\t\t217\t/* RO */\n#define EXT_CSD_REL_WR_SEC_C\t\t222\t/* RO */\n#define EXT_CSD_HC_WP_GRP_SIZE\t\t221\t/* RO */\n#define EXT_CSD_ERASE_TIMEOUT_MULT\t223\t/* RO */\n#define EXT_CSD_HC_ERASE_GRP_SIZE\t224\t/* RO */\n#define EXT_CSD_BOOT_MULT\t\t226\t/* RO */\n#define EXT_CSD_SEC_TRIM_MULT\t\t229\t/* RO */\n#define EXT_CSD_SEC_ERASE_MULT\t\t230\t/* RO */\n#define EXT_CSD_SEC_FEATURE_SUPPORT\t231\t/* RO */\n#define EXT_CSD_TRIM_MULT\t\t232\t/* RO */\n#define EXT_CSD_PWR_CL_200_195\t\t236\t/* RO */\n#define EXT_CSD_PWR_CL_200_360\t\t237\t/* RO */\n#define EXT_CSD_PWR_CL_DDR_52_195\t238\t/* RO */\n#define EXT_CSD_PWR_CL_DDR_52_360\t239\t/* RO */\n#define EXT_CSD_BKOPS_STATUS\t\t246\t/* RO */\n#define EXT_CSD_POWER_OFF_LONG_TIME\t247\t/* RO */\n#define EXT_CSD_GENERIC_CMD6_TIME\t248\t/* RO */\n#define EXT_CSD_CACHE_SIZE\t\t249\t/* RO, 4 bytes */\n#define EXT_CSD_PWR_CL_DDR_200_360\t253\t/* RO */\n#define EXT_CSD_FIRMWARE_VERSION\t254\t/* RO, 8 bytes */\n#define EXT_CSD_DEVICE_VERSION\t\t262\t/* RO, 2 bytes */\n#define EXT_CSD_PRE_EOL_INFO\t\t267\t/* RO */\n#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A\t268\t/* RO */\n#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B\t269\t/* RO */\n#define EXT_CSD_CMDQ_DEPTH\t\t307\t/* RO */\n#define EXT_CSD_CMDQ_SUPPORT\t\t308\t/* RO */\n#define EXT_CSD_SUPPORTED_MODE\t\t493\t/* RO */\n#define EXT_CSD_TAG_UNIT_SIZE\t\t498\t/* RO */\n#define EXT_CSD_DATA_TAG_SUPPORT\t499\t/* RO */\n#define EXT_CSD_MAX_PACKED_WRITES\t500\t/* RO */\n#define EXT_CSD_MAX_PACKED_READS\t501\t/* RO */\n#define EXT_CSD_BKOPS_SUPPORT\t\t502\t/* RO */\n#define EXT_CSD_HPI_FEATURES\t\t503\t/* RO */\n\n/*\n* EXT_CSD field definitions\n*/\n\n#define EXT_CSD_WR_REL_PARAM_EN\t\t(1<<2)\n\n#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS\t(0x40)\n#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS\t(0x10)\n#define EXT_CSD_BOOT_WP_B_PERM_WP_EN\t(0x04)\n#define EXT_CSD_BOOT_WP_B_PWR_WP_EN\t(0x01)\n\n#define EXT_CSD_PART_CONFIG_ACC_MASK\t(0x7)\n#define EXT_CSD_PART_CONFIG_ACC_BOOT0\t(0x1)\n#define EXT_CSD_PART_CONFIG_ACC_RPMB\t(0x3)\n#define EXT_CSD_PART_CONFIG_ACC_GP0\t(0x4)\n\n#define EXT_CSD_PART_SETTING_COMPLETED\t(0x1)\n#define EXT_CSD_PART_SUPPORT_PART_EN\t(0x1)\n\n#define EXT_CSD_CMD_SET_NORMAL\t\t(1<<0)\n#define EXT_CSD_CMD_SET_SECURE\t\t(1<<1)\n#define EXT_CSD_CMD_SET_CPSECURE\t(1<<2)\n\n#define EXT_CSD_CARD_TYPE_HS_26\t(1<<0)\t/* Card can run at 26MHz */\n#define EXT_CSD_CARD_TYPE_HS_52\t(1<<1)\t/* Card can run at 52MHz */\n#define EXT_CSD_CARD_TYPE_HS\t(EXT_CSD_CARD_TYPE_HS_26 | \\\n\t\t\t\t EXT_CSD_CARD_TYPE_HS_52)\n#define EXT_CSD_CARD_TYPE_DDR_1_8V  (1<<2)   /* Card can run at 52MHz */\n/* DDR mode @1.8V or 3V I/O */\n#define EXT_CSD_CARD_TYPE_DDR_1_2V  (1<<3)   /* Card can run at 52MHz */\n/* DDR mode @1.2V I/O */\n#define EXT_CSD_CARD_TYPE_DDR_52       (EXT_CSD_CARD_TYPE_DDR_1_8V  \\\n\t\t\t\t\t| EXT_CSD_CARD_TYPE_DDR_1_2V)\n#define EXT_CSD_CARD_TYPE_HS200_1_8V\t(1<<4)\t/* Card can run at 200MHz */\n#define EXT_CSD_CARD_TYPE_HS200_1_2V\t(1<<5)\t/* Card can run at 200MHz */\n/* SDR mode @1.2V I/O */\n#define EXT_CSD_CARD_TYPE_HS200\t\t(EXT_CSD_CARD_TYPE_HS200_1_8V | \\\n\t\t\t\t\t EXT_CSD_CARD_TYPE_HS200_1_2V)\n#define EXT_CSD_CARD_TYPE_HS400_1_8V\t(1<<6)\t/* Card can run at 200MHz DDR, 1.8V */\n#define EXT_CSD_CARD_TYPE_HS400_1_2V\t(1<<7)\t/* Card can run at 200MHz DDR, 1.2V */\n#define EXT_CSD_CARD_TYPE_HS400\t\t(EXT_CSD_CARD_TYPE_HS400_1_8V | \\\n\t\t\t\t\t EXT_CSD_CARD_TYPE_HS400_1_2V)\n#define EXT_CSD_CARD_TYPE_HS400ES\t(1<<8)\t/* Card can run at HS400ES */\n\n#define EXT_CSD_BUS_WIDTH_1\t0\t/* Card is in 1 bit mode */\n#define EXT_CSD_BUS_WIDTH_4\t1\t/* Card is in 4 bit mode */\n#define EXT_CSD_BUS_WIDTH_8\t2\t/* Card is in 8 bit mode */\n#define EXT_CSD_DDR_BUS_WIDTH_4\t5\t/* Card is in 4 bit DDR mode */\n#define EXT_CSD_DDR_BUS_WIDTH_8\t6\t/* Card is in 8 bit DDR mode */\n#define EXT_CSD_BUS_WIDTH_STROBE (1<<7)\t/* Enhanced strobe mode */\n\n#define EXT_CSD_TIMING_BC\t0\t/* Backwards compatility */\n#define EXT_CSD_TIMING_HS\t1\t/* High speed */\n#define EXT_CSD_TIMING_HS200\t2\t/* HS200 */\n#define EXT_CSD_TIMING_HS400\t3\t/* HS400 */\n#define EXT_CSD_DRV_STR_SHIFT\t4\t/* Driver Strength shift */\n\n#define EXT_CSD_SEC_ER_EN\t(1<<0)\n#define EXT_CSD_SEC_BD_BLK_EN\t(1<<2)\n#define EXT_CSD_SEC_GB_CL_EN\t(1<<4)\n#define EXT_CSD_SEC_SANITIZE\t(1<<6)  /* v4.5 only */\n\n#define EXT_CSD_RST_N_EN_MASK\t0x3\n#define EXT_CSD_RST_N_ENABLED\t1\t/* RST_n is enabled on card */\n\n#define EXT_CSD_NO_POWER_NOTIFICATION\t0\n#define EXT_CSD_POWER_ON\t\t1\n#define EXT_CSD_POWER_OFF_SHORT\t\t2\n#define EXT_CSD_POWER_OFF_LONG\t\t3\n\n#define EXT_CSD_PWR_CL_8BIT_MASK\t0xF0\t/* 8 bit PWR CLS */\n#define EXT_CSD_PWR_CL_4BIT_MASK\t0x0F\t/* 8 bit PWR CLS */\n#define EXT_CSD_PWR_CL_8BIT_SHIFT\t4\n#define EXT_CSD_PWR_CL_4BIT_SHIFT\t0\n\n#define EXT_CSD_PACKED_EVENT_EN\t(1<<3)\n\n/*\n* EXCEPTION_EVENT_STATUS field\n*/\n#define EXT_CSD_URGENT_BKOPS\t\t(1<<0)\n#define EXT_CSD_DYNCAP_NEEDED\t\t(1<<1)\n#define EXT_CSD_SYSPOOL_EXHAUSTED\t(1<<2)\n#define EXT_CSD_PACKED_FAILURE\t\t(1<<3)\n\n#define EXT_CSD_PACKED_GENERIC_ERROR\t(1<<0)\n#define EXT_CSD_PACKED_INDEXED_ERROR\t(1<<1)\n\n/*\n* BKOPS status level\n*/\n#define EXT_CSD_BKOPS_LEVEL_2\t\t0x2\n\n/*\n* BKOPS modes\n*/\n#define EXT_CSD_MANUAL_BKOPS_MASK\t0x01\n#define EXT_CSD_AUTO_BKOPS_MASK\t\t0x02\n\n/*\n* Command Queue\n*/\n#define EXT_CSD_CMDQ_MODE_ENABLED\t(1<<0)\n#define EXT_CSD_CMDQ_DEPTH_MASK\t\t0x1F\n#define EXT_CSD_CMDQ_SUPPORTED\t\t(1<<0)\n\n/*\n* MMC_SWITCH access modes\n*/\n#define MMC_SWITCH_MODE_CMD_SET\t\t0x00\t/* Change the command set */\n#define MMC_SWITCH_MODE_SET_BITS\t0x01\t/* Set bits which are 1 in value */\n#define MMC_SWITCH_MODE_CLEAR_BITS\t0x02\t/* Clear bits which are 1 in value */\n#define MMC_SWITCH_MODE_WRITE_BYTE\t0x03\t/* Set target to value */\n\n/*\n* Erase/trim/discard\n*/\n#define MMC_ERASE_ARG\t\t\t0x00000000\n#define MMC_SECURE_ERASE_ARG\t\t0x80000000\n#define MMC_TRIM_ARG\t\t\t0x00000001\n#define MMC_DISCARD_ARG\t\t\t0x00000003\n#define MMC_SECURE_TRIM1_ARG\t\t0x80000001\n#define MMC_SECURE_TRIM2_ARG\t\t0x80008000\n#define MMC_SECURE_ARGS\t\t\t0x80000000\n#define MMC_TRIM_ARGS\t\t\t0x00008001\n\n#endif /* LINUX_MMC_MMC_H */\n"
  },
  {
    "path": "argon-nx-gui/include/storage/sd.h",
    "content": "/*\n *  include/linux/mmc/sd.h\n *\n *  Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved.\n *  Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or (at\n * your option) any later version.\n */\n\n#ifndef LINUX_MMC_SD_H\n#define LINUX_MMC_SD_H\n\n/* SD commands                           type  argument     response */\n/* class 0 */\n/* This is basically the same command as for MMC with some quirks. */\n#define SD_SEND_RELATIVE_ADDR     3   /* bcr                     R6  */\n#define SD_SEND_IF_COND           8   /* bcr  [11:0] See below   R7  */\n#define SD_SWITCH_VOLTAGE         11  /* ac                      R1  */\n\n/* class 10 */\n#define SD_SWITCH                 6   /* adtc [31:0] See below   R1  */\n\n/* class 5 */\n#define SD_ERASE_WR_BLK_START    32   /* ac   [31:0] data addr   R1  */\n#define SD_ERASE_WR_BLK_END      33   /* ac   [31:0] data addr   R1  */\n\n/* Application commands */\n#define SD_APP_SET_BUS_WIDTH      6   /* ac   [1:0] bus width    R1  */\n#define SD_APP_SD_STATUS         13   /* adtc                    R1  */\n#define SD_APP_SEND_NUM_WR_BLKS  22   /* adtc                    R1  */\n#define SD_APP_OP_COND           41   /* bcr  [31:0] OCR         R3  */\n#define SD_APP_SET_CLR_CARD_DETECT 42\n#define SD_APP_SEND_SCR          51   /* adtc                    R1  */\n\n/* OCR bit definitions */\n#define SD_OCR_S18R         (1 << 24)    /* 1.8V switching request */\n#define SD_ROCR_S18A        SD_OCR_S18R  /* 1.8V switching accepted by card */\n#define SD_OCR_XPC          (1 << 28)    /* SDXC power control */\n#define SD_OCR_CCS          (1 << 30)    /* Card Capacity Status */\n#define SD_OCR_VDD_32_33    (1 << 20)\t /* VDD voltage 3.2 ~ 3.3 */\n\n/*\n* SD_SWITCH argument format:\n*\n*      [31] Check (0) or switch (1)\n*      [30:24] Reserved (0)\n*      [23:20] Function group 6\n*      [19:16] Function group 5\n*      [15:12] Function group 4\n*      [11:8] Function group 3\n*      [7:4] Function group 2\n*      [3:0] Function group 1\n*/\n\n/*\n* SD_SEND_IF_COND argument format:\n*\n*\t[31:12] Reserved (0)\n*\t[11:8] Host Voltage Supply Flags\n*\t[7:0] Check Pattern (0xAA)\n*/\n\n/*\n* SCR field definitions\n*/\n#define SCR_SPEC_VER_0\t\t0\t/* Implements system specification 1.0 - 1.01 */\n#define SCR_SPEC_VER_1\t\t1\t/* Implements system specification 1.10 */\n#define SCR_SPEC_VER_2\t\t2\t/* Implements system specification 2.00-3.0X */\n#define SD_SCR_BUS_WIDTH_1\t(1<<0)\n#define SD_SCR_BUS_WIDTH_4\t(1<<2)\n\n/*\n* SD bus widths\n*/\n#define SD_BUS_WIDTH_1\t\t0\n#define SD_BUS_WIDTH_4\t\t2\n\n/*\n* SD bus speeds\n*/\n#define UHS_SDR12_BUS_SPEED\t\t0\n#define HIGH_SPEED_BUS_SPEED\t1\n#define UHS_SDR25_BUS_SPEED\t\t1\n#define UHS_SDR50_BUS_SPEED\t\t2\n#define UHS_SDR104_BUS_SPEED\t3\n#define UHS_DDR50_BUS_SPEED\t\t4\n#define HS400_BUS_SPEED \t\t5\n\n#define SD_MODE_HIGH_SPEED\t(1 << HIGH_SPEED_BUS_SPEED)\n#define SD_MODE_UHS_SDR12\t(1 << UHS_SDR12_BUS_SPEED)\n#define SD_MODE_UHS_SDR25\t(1 << UHS_SDR25_BUS_SPEED)\n#define SD_MODE_UHS_SDR50\t(1 << UHS_SDR50_BUS_SPEED)\n#define SD_MODE_UHS_SDR104\t(1 << UHS_SDR104_BUS_SPEED)\n#define SD_MODE_UHS_DDR50\t(1 << UHS_DDR50_BUS_SPEED)\n\n#define SD_DRIVER_TYPE_B\t0x01\n#define SD_DRIVER_TYPE_A\t0x02\n\n#define SD_SET_CURRENT_LIMIT_200\t0\n#define SD_SET_CURRENT_LIMIT_400\t1\n#define SD_SET_CURRENT_LIMIT_600\t2\n#define SD_SET_CURRENT_LIMIT_800\t3\n\n/*\n* SD_SWITCH mode\n*/\n#define SD_SWITCH_CHECK\t\t0\n#define SD_SWITCH_SET\t\t1\n\n/*\n* SD_SWITCH function groups\n*/\n#define SD_SWITCH_GRP_ACCESS\t0\n\n/*\n* SD_SWITCH access modes\n*/\n#define SD_SWITCH_ACCESS_DEF\t0\n#define SD_SWITCH_ACCESS_HS\t\t1\n\n#endif /* LINUX_MMC_SD_H */"
  },
  {
    "path": "argon-nx-gui/include/storage/sdmmc.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _SDMMC_H_\n#define _SDMMC_H_\n\n#include \"utils/types.h\"\n#include \"sdmmc_driver.h\"\n\ntypedef struct _mmc_cid\n{\n\tu32 manfid;\n\tu8  prod_name[8];\n\tu8  card_bga;\n\tu8  prv;\n\tu32 serial;\n\tu16 oemid;\n\tu16\tyear;\n\tu8  hwrev;\n\tu8  fwrev;\n\tu8  month;\n} mmc_cid_t;\n\ntypedef struct _mmc_csd\n{\n\tu8  structure;\n\tu8  mmca_vsn;\n\tu16 cmdclass;\n\tu32 c_size;\n\tu32 r2w_factor;\n\tu32 max_dtr;\n\tu32 erase_size;\t\t/* In sectors */\n\tu32 read_blkbits;\n\tu32 write_blkbits;\n\tu32 capacity;\n\tu8  write_protect;\n\tu16 busspeed;\n} mmc_csd_t;\n\ntypedef struct _mmc_ext_csd\n{\n\tu8  rev;\n\tu32 sectors;\n\tint bkops;        /* background support bit */\n\tint bkops_en;     /* manual bkops enable bit */\n\tu8  ext_struct;   /* 194 */\n\tu8  card_type;    /* 196 */\n\tu8  bkops_status; /* 246 */\n\tu16 dev_version;\n\tu8  boot_mult;\n\tu8  rpmb_mult;\n} mmc_ext_csd_t;\n\ntypedef struct _sd_scr\n{\n\tu8 sda_vsn;\n\tu8 sda_spec3;\n\tu8 bus_widths;\n\tu8 cmds;\n} sd_scr_t;\n\ntypedef struct _sd_ssr\n{\n\tu8 bus_width;\n\tu8 speed_class;\n\tu8 uhs_grade;\n\tu8 video_class;\n\tu8 app_class;\n} sd_ssr_t;\n\n/*! SDMMC storage context. */\ntypedef struct _sdmmc_storage_t\n{\n\tsdmmc_t *sdmmc;\n\tu32 rca;\n\tint has_sector_access;\n\tu32 sec_cnt;\n\tint is_low_voltage;\n\tu32 partition;\n\tu8  raw_cid[0x10];\n\tu8  raw_csd[0x10];\n\tu8  raw_scr[8];\n\tu8  raw_ssr[0x40];\n\tmmc_cid_t     cid;\n\tmmc_csd_t     csd;\n\tmmc_ext_csd_t ext_csd;\n\tsd_scr_t      scr;\n\tsd_ssr_t      ssr;\n} sdmmc_storage_t;\n\nint sdmmc_storage_end(sdmmc_storage_t *storage);\nint sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);\nint sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);\nint sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type);\nint sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition);\nint sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type);\nint sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc);\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/storage/sdmmc_driver.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _SDMMC_DRIVER_H_\n#define _SDMMC_DRIVER_H_\n\n#include \"../utils/types.h\"\n#include \"sdmmc_t210.h\"\n\n/*! SDMMC controller IDs. */\n#define SDMMC_1 0\n#define SDMMC_2 1\n#define SDMMC_3 2\n#define SDMMC_4 3\n\n/*! SDMMC power types. */\n#define SDMMC_POWER_OFF 0\n#define SDMMC_POWER_1_8 1\n#define SDMMC_POWER_3_3 2\n\n/*! SDMMC bus widths. */\n#define SDMMC_BUS_WIDTH_1 0\n#define SDMMC_BUS_WIDTH_4 1\n#define SDMMC_BUS_WIDTH_8 2\n\n/*! SDMMC response types. */\n#define SDMMC_RSP_TYPE_0 0\n#define SDMMC_RSP_TYPE_1 1\n#define SDMMC_RSP_TYPE_2 2\n#define SDMMC_RSP_TYPE_3 3\n#define SDMMC_RSP_TYPE_4 4\n#define SDMMC_RSP_TYPE_5 5\n\n/*! SDMMC mask interrupt status. */\n#define SDMMC_MASKINT_MASKED   0\n#define SDMMC_MASKINT_NOERROR -1\n#define SDMMC_MASKINT_ERROR   -2\n\n/*! SDMMC host control 2 */\n#define SDHCI_CTRL_UHS_MASK\t\t\t0xFFF8\n#define SDHCI_CTRL_VDD_330\t\t\t0xFFF7\n#define SDHCI_CTRL_VDD_180\t\t\t8\n#define SDHCI_CTRL_EXEC_TUNING\t\t0x40\n#define SDHCI_CTRL_TUNED_CLK\t\t0x80\n#define SDHCI_HOST_VERSION_4_EN\t\t0x1000\n#define SDHCI_ADDRESSING_64BIT_EN\t0x2000\n#define SDHCI_CTRL_PRESET_VAL_EN\t0x8000\n\n/*! SD bus speeds. */\n#define UHS_SDR12_BUS_SPEED\t\t0\n#define HIGH_SPEED_BUS_SPEED\t1\n#define UHS_SDR25_BUS_SPEED\t\t1\n#define UHS_SDR50_BUS_SPEED\t\t2\n#define UHS_SDR104_BUS_SPEED\t3\n#define UHS_DDR50_BUS_SPEED\t\t4\n#define HS400_BUS_SPEED \t\t5\n\n/*! Helper for SWITCH command argument. */\n#define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8))\n\n/*! SDMMC controller context. */\ntypedef struct _sdmmc_t\n{\n\tt210_sdmmc_t *regs;\n\tu32 id;\n\tu32 divisor;\n\tu32 clock_stopped;\n\tint no_sd;\n\tint sd_clock_enabled;\n\tint venclkctl_set;\n\tu32 venclkctl_tap;\n\tu32 expected_rsp_type;\n\tu32 dma_addr_next;\n\tu32 rsp[4];\n\tu32 rsp3;\n} sdmmc_t;\n\n/*! SDMMC command. */\ntypedef struct _sdmmc_cmd_t\n{\n\tu16 cmd;\n\tu32 arg;\n\tu32 rsp_type;\n\tu32 check_busy;\n} sdmmc_cmd_t;\n\n/*! SDMMC request. */\ntypedef struct _sdmmc_req_t\n{\n\tvoid *buf;\n\tu32 blksize;\n\tu32 num_sectors;\n\tint is_write;\n\tint is_multi_block;\n\tint is_auto_cmd12;\n} sdmmc_req_t;\n\nint sdmmc_get_voltage(sdmmc_t *sdmmc);\nu32 sdmmc_get_bus_width(sdmmc_t *sdmmc);\nvoid sdmmc_set_bus_width(sdmmc_t *sdmmc, u32 bus_width);\nvoid sdmmc_get_venclkctl(sdmmc_t *sdmmc);\nint sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type);\nvoid sdmmc_sd_clock_ctrl(sdmmc_t *sdmmc, int no_sd);\nint sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type);\nint sdmmc_config_tuning(sdmmc_t *sdmmc, u32 type, u32 cmd);\nint sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp);\nint sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int no_sd);\nvoid sdmmc_end(sdmmc_t *sdmmc);\nvoid sdmmc_init_cmd(sdmmc_cmd_t *cmdbuf, u16 cmd, u32 arg, u32 rsp_type, u32 check_busy);\nint sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out);\nint sdmmc_enable_low_voltage(sdmmc_t *sdmmc);\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/storage/sdmmc_t210.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _SDMMC_T210_H_\n#define _SDMMC_T210_H_\n\n#include \"../utils/types.h\"\n\n#define TEGRA_MMC_PWRCTL_SD_BUS_POWER 0x1\n#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8 0xA\n#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_0 0xC\n#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3 0xE\n#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_MASK 0xF1\n\n#define TEGRA_MMC_HOSTCTL_1BIT 0x00\n#define TEGRA_MMC_HOSTCTL_4BIT 0x02\n#define TEGRA_MMC_HOSTCTL_8BIT 0x20\n\n#define TEGRA_MMC_CLKCON_INTERNAL_CLOCK_ENABLE 0x1\n#define TEGRA_MMC_CLKCON_INTERNAL_CLOCK_STABLE 0x2\n#define TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE 0x4\n#define TEGRA_MMC_CLKCON_CLKGEN_SELECT 0x20\n\n#define TEGRA_MMC_SWRST_SW_RESET_FOR_ALL 0x1\n#define TEGRA_MMC_SWRST_SW_RESET_FOR_CMD_LINE 0x2\n#define TEGRA_MMC_SWRST_SW_RESET_FOR_DAT_LINE 0x4\n\n#define TEGRA_MMC_TRNMOD_DMA_ENABLE 0x1\n#define TEGRA_MMC_TRNMOD_BLOCK_COUNT_ENABLE 0x2\n#define TEGRA_MMC_TRNMOD_AUTO_CMD12 0x4\n#define TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_WRITE 0x0\n#define TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ 0x10\n#define TEGRA_MMC_TRNMOD_MULTI_BLOCK_SELECT 0x20\n\n#define TEGRA_MMC_TRNMOD_CMD_CRC_CHECK 0x8\n#define TEGRA_MMC_TRNMOD_CMD_INDEX_CHECK 0x10\n#define TEGRA_MMC_TRNMOD_DATA_PRESENT_SELECT_DATA_TRANSFER 0x20\n\n#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_MASK 0x3\n#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_NO_RESPONSE 0x0\n#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_136 0x1\n#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48 0x2\n#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48_BUSY 0x3\n\n#define TEGRA_MMC_NORINTSTS_CMD_COMPLETE 0x1\n#define TEGRA_MMC_NORINTSTS_XFER_COMPLETE 0x2\n#define TEGRA_MMC_NORINTSTS_DMA_INTERRUPT 0x8\n#define TEGRA_MMC_NORINTSTS_ERR_INTERRUPT 0x8000\n#define TEGRA_MMC_NORINTSTS_CMD_TIMEOUT 0x10000\n\n#define TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY 0x20\n\ntypedef struct _t210_sdmmc_t\n{\n\tvu32 sysad;\n\tvu16 blksize;\n\tvu16 blkcnt;\n\tvu32 argument;\n\tvu16 trnmod;\n\tvu16 cmdreg;\n\tvu32 rspreg0;\n\tvu32 rspreg1;\n\tvu32 rspreg2;\n\tvu32 rspreg3;\n\tvu32 bdata;\n\tvu32 prnsts;\n\tvu8 hostctl;\n\tvu8 pwrcon;\n\tvu8 blkgap;\n\tvu8 wakcon;\n\tvu16 clkcon;\n\tvu8 timeoutcon;\n\tvu8 swrst;\n\tvu16 norintsts;\n\tvu16 errintsts;\n\tvu16 norintstsen;\n\tvu16 errintstsen;\n\tvu16 norintsigen;\n\tvu16 errintsigen;\n\tvu16 acmd12errsts;\n\tvu16 hostctl2;\n\tvu32 capareg;\n\tvu32 capareg_1;\n\tvu32 maxcurr;\n\tvu8 res3[4];\n\tvu16 setacmd12err;\n\tvu16 setinterr;\n\tvu8 admaerr;\n\tvu8 res4[3];\n\tvu32 admaaddr;\n\tvu32 admaaddr_hi;\n\tvu8 res5[156];\n\tvu16 slotintstatus;\n\tvu16 hcver;\n\tvu32 venclkctl;\n\tvu32 venspictl;\n\tvu32 venspiintsts;\n\tvu32 venceatactl;\n\tvu32 venbootctl;\n\tvu32 venbootacktout;\n\tvu32 venbootdattout;\n\tvu32 vendebouncecnt;\n\tvu32 venmiscctl;\n\tvu32 res6[34];\n\tvu32 veniotrimctl;\n\tvu32 vendllcal;\n\tvu8 res7[8];\n\tvu32 dllcfgstatus;\n\tvu32 ventunctl0;\n\tvu32 field_1C4;\n\tvu8 field_1C8[24];\n\tvu32 sdmemcmppadctl;\n\tvu32 autocalcfg;\n\tvu32 autocalintval;\n\tvu32 autocalsts;\n\tvu32 iospare;\n} t210_sdmmc_t;\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/utils/aarch64_util.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _ARM64_H_\n#define _ARM64_H_\n\n#include \"utils/types.h\"\n\n#define LSL0 0\n#define LSL16 16\n#define LSL32 32\n\n#define _PAGEOFF(x) ((x) & 0xFFFFF000)\n\n#define _ADRP(r, o) 0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F)\n#define _BL(a, o) 0x94000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)\n#define _B(a, o) 0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)\n#define _MOVKX(r, i, s) 0xF2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)\n#define _MOVZX(r, i, s) 0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)\n#define _NOP() 0xD503201F\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/utils/btn.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _BTN_H_\n#define _BTN_H_\n\n#include \"utils/types.h\"\n\n#define BTN_POWER 0x1\n#define BTN_VOL_DOWN 0x2\n#define BTN_VOL_UP 0x4\n\nu32 btn_read();\nu32 btn_wait();\nu32 btn_wait_timeout(u32 time_ms, u32 mask);\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/utils/dirlist.h",
    "content": "/*\n * Copyright (c) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"utils/types.h\"\n\nchar *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles);\n"
  },
  {
    "path": "argon-nx-gui/include/utils/fs_utils.h",
    "content": "#ifndef _FS_UTILS_H_\n#define _FS_UTILS_H_\n\n#include \"utils/types.h\"\n#include \"libs/fatfs/ff.h\"\n#include \"storage/sdmmc.h\"\n#include \"storage/sdmmc_driver.h\"\n\nsdmmc_t g_sd_sdmmc;\nsdmmc_storage_t g_sd_storage;\nFATFS g_sd_fs;\nbool g_sd_mounted;\n\nbool sd_mount();\nvoid sd_unmount();\nvoid *sd_file_read(char *path);\nint sd_save_to_file(void *buf, u32 size, const char *filename);\nbool sd_file_exists(const char* filename);\nvoid s_printf(char *out_buf, const char *fmt, ...);\n\n#endif"
  },
  {
    "path": "argon-nx-gui/include/utils/touch.h",
    "content": "/*\n * Copyright (c) 2018 langerhans\n * Copyright (C) 2018 Guillem96\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _TOUCH_H_\n#define _TOUCH_H_\n \n#include \"soc/i2c.h\"\n#include \"utils/util.h\"\n#include \"utils/types.h\"\n\n#define STMFTS_I2C_ADDR 0x49\n\n/* I2C commands */\n#define STMFTS_READ_INFO\t\t\t    0x80\n#define STMFTS_READ_STATUS\t\t\t    0x84\n#define STMFTS_READ_ONE_EVENT\t\t\t0x85\n#define STMFTS_READ_ALL_EVENT\t\t\t0x86\n#define STMFTS_LATEST_EVENT\t\t\t    0x87\n#define STMFTS_SLEEP_IN\t\t\t\t    0x90\n#define STMFTS_SLEEP_OUT\t\t\t    0x91\n#define STMFTS_MS_MT_SENSE_OFF\t\t\t0x92\n#define STMFTS_MS_MT_SENSE_ON\t\t\t0x93\n#define STMFTS_SS_HOVER_SENSE_OFF\t\t0x94\n#define STMFTS_SS_HOVER_SENSE_ON\t\t0x95\n#define STMFTS_MS_KEY_SENSE_OFF\t\t\t0x9a\n#define STMFTS_MS_KEY_SENSE_ON\t\t\t0x9b\n#define STMFTS_SYSTEM_RESET\t\t\t    0xa0\n#define STMFTS_CLEAR_EVENT_STACK\t\t0xa1\n#define STMFTS_FULL_FORCE_CALIBRATION\t0xa2\n#define STMFTS_MS_CX_TUNING\t\t\t    0xa3\n#define STMFTS_SS_CX_TUNING\t\t\t    0xa4\n#define STMFTS_WRITE_REGISTER\t\t\t0xb6\n\n/* events */\n#define STMFTS_EV_NO_EVENT\t\t\t    0x00\n#define STMFTS_EV_MULTI_TOUCH_DETECTED\t0x02\n#define STMFTS_EV_MULTI_TOUCH_ENTER\t\t0x03\n#define STMFTS_EV_MULTI_TOUCH_LEAVE\t\t0x04\n#define STMFTS_EV_MULTI_TOUCH_MOTION\t0x05\n#define STMFTS_EV_HOVER_ENTER\t\t\t0x07\n#define STMFTS_EV_HOVER_LEAVE\t\t\t0x08\n#define STMFTS_EV_HOVER_MOTION\t\t\t0x09\n#define STMFTS_EV_KEY_STATUS\t\t\t0x0e\n#define STMFTS_EV_ERROR\t\t\t\t    0x0f\n#define STMFTS_EV_CONTROLLER_READY\t\t0x10\n#define STMFTS_EV_SLEEP_OUT_CONTROLLER_READY    0x11\n#define STMFTS_EV_STATUS\t\t\t    0x16\n#define STMFTS_EV_DEBUG\t\t\t\t    0xdb\n\n/* multi touch related event masks */\n#define STMFTS_MASK_EVENT_ID\t\t\t0x0f\n#define STMFTS_MASK_TOUCH_ID\t\t\t0xf0\n#define STMFTS_MASK_LEFT_EVENT\t\t\t0x0f\n#define STMFTS_MASK_X_MSB\t\t\t    0x0f\n#define STMFTS_MASK_Y_LSB\t\t\t    0xf0\n\n/* key related event masks */\n#define STMFTS_MASK_KEY_NO_TOUCH\t\t0x00\n#define STMFTS_MASK_KEY_MENU\t\t\t0x01\n#define STMFTS_MASK_KEY_BACK\t\t\t0x02\n\n#define STMFTS_EVENT_SIZE\t    8\n#define STMFTS_STACK_DEPTH\t    32\n#define STMFTS_DATA_MAX_SIZE    (STMFTS_EVENT_SIZE * STMFTS_STACK_DEPTH)\n#define STMFTS_MAX_FINGERS\t    10\n#define STMFTS_DEV_NAME\t\t    \"stmfts\"\n\n/* TOUCH SUPPORT ONLY WORKS WHEN A GC IS INSIDE NINTENDO SWITCH */\n\n\ntypedef struct _touch_event {\n\tu8   raw[8];\n\tu16  type; // Event type.\n\tu16  x;    // Horizontal coordinates.\n\tu16  y;    // Vertical coordinates.\n\tu8   z;\n\tu8   fingers;\n\tbool touch;\n} touch_event_t;\n\ntypedef struct _touch_info {\n\tu16 chip_id;\n\tu16 fw_ver;\n\tu16 config_id;\n\tu16 config_ver;\n} touch_info_t;\n\nvoid touch_poll(touch_event_t *event);\ntouch_event_t touch_poll_wait();\ntouch_info_t touch_get_info();\n\n\n/* Init touch support */\nint touch_power_on();\nvoid touch_power_off();\n\n/* Wait for touch input */\ntouch_event_t touch_wait();\n\n/**\n * Checks if touch event is produced inside a rectangle\n * x, y are the top left coordinates of the rect\n */\nbool is_rect_touched(touch_event_t* event, u32 x, u32 y, u32 width, u32 height);\n\n#endif /* _TOUCH_H_ */ \n"
  },
  {
    "path": "argon-nx-gui/include/utils/types.h",
    "content": "/*\n* Copyright (c) 2018 naehrwert\n*\n* This program is free software; you can redistribute it and/or modify it\n* under the terms and conditions of the GNU General Public License,\n* version 2, as published by the Free Software Foundation.\n*\n* This program is distributed in the hope it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _TYPES_H_\n#define _TYPES_H_\n\n#define NULL ((void *)0)\n\n#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))\n#define MAX(a, b) ((a) > (b) ? (a) : (b))\n#define MIN(a, b) ((a) < (b) ? (a) : (b))\n\n#define OFFSET_OF(t, m) ((u32)&((t *)NULL)->m)\n#define CONTAINER_OF(mp, t, mn) ((t *)((u32)mp - OFFSET_OF(t, mn)))\n\ntypedef signed char s8;\ntypedef short s16;\ntypedef short SHORT;\ntypedef int s32;\ntypedef int INT;\ntypedef long LONG;\ntypedef long long int s64;\ntypedef unsigned char u8;\ntypedef unsigned char BYTE;\ntypedef unsigned short u16;\ntypedef unsigned short WORD;\ntypedef unsigned short WCHAR;\ntypedef unsigned int u32;\ntypedef unsigned int UINT;\ntypedef unsigned long DWORD;\ntypedef unsigned long long QWORD;\ntypedef unsigned long long int u64;\ntypedef volatile unsigned char vu8;\ntypedef volatile unsigned short vu16;\ntypedef volatile unsigned int vu32;\n\ntypedef int bool;\n#define true  1\n#define false 0\n\n#define BOOT_CFG_AUTOBOOT_EN (1 << 0)\n#define BOOT_CFG_FROM_LAUNCH (1 << 1)\n#define BOOT_CFG_SEPT_RUN    (1 << 7)\n\n#define EXTRA_CFG_KEYS    (1 << 0)\n#define EXTRA_CFG_PAYLOAD (1 << 1)\n#define EXTRA_CFG_MODULE  (1 << 2)\n\ntypedef struct __attribute__((__packed__)) _boot_cfg_t\n{\n\tu8  boot_cfg;\n\tu8  autoboot;\n\tu8  autoboot_list;\n\tu8  extra_cfg;\n\tu8  rsvd[128];\n} boot_cfg_t;\n\ntypedef struct __attribute__((__packed__)) _ipl_ver_meta_t\n{\n\tu32 magic;\n\tu32 version;\n\tu16 rsvd0;\n\tu16 rsvd1;\n} ipl_ver_meta_t;\n\ntypedef struct __attribute__((__packed__)) _reloc_meta_t\n{\n\tu32 start;\n\tu32 stack;\n\tu32 end;\n\tu32 ep;\n} reloc_meta_t;\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/include/utils/util.h",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018 CTCaer\n * Copyright (C) 2018 Guillem96\n * \n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _UTIL_H_\n#define _UTIL_H_\n\n#include \"utils/types.h\"\n\n#define MAKE_REG32(a) (*(vu32 *)(a))\n\n#define byte_swap_32(num) ((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \\\n\t\t\t\t\t\t((num >> 8 )& 0xff00) | ((num << 24) & 0xff000000)\n\ntypedef struct _cfg_op_t\n{\n\tu32 off;\n\tu32 val;\n} cfg_op_t;\n\nu32 get_tmr_us();\nu32 get_tmr_ms();\nu32 get_tmr_s();\nvoid usleep(u32 ticks);\nvoid msleep(u32 milliseconds);\nvoid exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);\nu32 crc32c(const void *buf, u32 len);\n\nvoid reboot_normal(void);\nvoid reboot_rcm(void);\nvoid power_off(void);\n\n/* This is a faster implementation of memcmp that checks two u32 values */\n/* every 128 Bytes block. Intented only for Backup and Restore          */\nu32 memcmp32sparse(const u32 *buf1, const u32 *buf2, u32 len);\n\n__attribute__((noreturn)) void wait_for_button_and_reboot(void);\n\n/**\n * Replace a pattern of string for another string\n */\nchar *str_replace(char *orig, char *rep, char *with);\n\nvoid panic(u32 val);\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\n 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Lesser General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n                            NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc.,\n    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.\n"
  },
  {
    "path": "argon-nx-gui/src/core/argon-ctxt.c",
    "content": "#include \"core/argon-ctxt.h\"\n#include \"mem/heap.h\"\n#include \"libs/lvgl/lvgl.h\"\n\nvoid argon_ctxt_init(argon_ctxt_t* argon_ctxt)\n{\n    /* Screen setting init */\n    argon_ctxt->is_display_init = false;\n    argon_ctxt->vdb = (u32*)malloc(sizeof(u32) * LV_HOR_RES_MAX * LV_VER_RES_MAX);\n    \n    /* Lv objects pool */\n    argon_ctxt->pool = (gui_menu_pool_t*)malloc(sizeof(gui_menu_pool_t));\n    gui_menu_pool_init(argon_ctxt->pool);\n\n    /* Minerva */\n    argon_ctxt->mtc_conf = (mtc_config_t*)malloc(sizeof(mtc_config_t));\n}\n\nvoid argon_ctxt_destroy(argon_ctxt_t* argon_ctxt)\n{\n    free(argon_ctxt->vdb);\n\n    free(argon_ctxt->mtc_conf);\n\n    gui_menu_pool_cleanup(argon_ctxt->pool);\n    \n    free(argon_ctxt);\n}"
  },
  {
    "path": "argon-nx-gui/src/core/argon-resources.c",
    "content": "#include \"core/argon-resources.h\"\n#include \"libs/fatfs/ff.h\"\n\nvoid argon_resources_init() \n{\n    FIL fp;\n\tf_open(&fp, \"argon/sys/resources.argon\", FA_READ);\n\tf_read(&fp, (void *)ARGON_RES_ADDR, f_size(&fp), NULL);\n\tf_close(&fp);\n}"
  },
  {
    "path": "argon-nx-gui/src/core/custom-gui.c",
    "content": "/*\n * Copyright (c) 2018 Guillem96\n * \n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"core/custom-gui.h\"\n#include \"gfx/gfx.h\"\n#include \"mem/heap.h\"\n#include \"gfx/lvgl_adapter.h\"\n#include \"utils/fs_utils.h\"\n#include \"utils/util.h\"\n\n#include \"libs/lvgl/lvgl.h\"\n\n#include <string.h>\n\n\ncustom_gui_t* custom_gui_load()\n{\n    custom_gui_t* custom_gui = (custom_gui_t*)malloc(sizeof(custom_gui_t));\n    custom_gui->custom_bg = bmp_to_lvimg_obj(CUSTOM_BG_PATH);\n    return custom_gui;\n}\n\nvoid custom_gui_end(custom_gui_t* cg)\n{\n    free(cg->custom_bg);\n    free(cg);\n}\n\nbool render_custom_background(custom_gui_t* cg, lv_obj_t* par)\n{\n    if (cg->custom_bg == NULL)\n        return false;\n        \n    lv_obj_t *img = lv_img_create(par, NULL);\n    lv_img_set_src(img, cg->custom_bg);\n    lv_obj_set_pos(img, 0, 0);\n    lv_obj_set_width(img, LV_HOR_RES);\n    return true;\n}\n\nvoid take_screenshot()\n{\n    static lv_style_t bg;\n    lv_style_copy(&bg, &lv_style_pretty);\n    bg.text.color = LV_COLOR_WHITE;\n    bg.body.opa = LV_OPA_0;\n    \n    const u32 file_size = 0x384000 + 0x36;\n    u8 *bitmap = malloc(file_size);\n    u32 *fb = malloc(0x384000);\n    u32 *fb_ptr = g_gfx_ctxt.fb;\n\n    // Reconstruct FB for bottom-top, landscape bmp.\n    for (u32 x = 0; x < 1280; x++)\n    {\n        for (int y = 719; y > -1; y--)\n            fb[y * 1280 + x] = *fb_ptr++;\n    }\n\n    memcpy(bitmap + 0x36, fb, 0x384000);\n\n    typedef struct _bmp_t\n    {\n        u16 magic;\n        u32 size;\n        u32 rsvd;\n        u32 data_off;\n        u32 hdr_size;\n        u32 width;\n        u32 height;\n        u16 planes;\n        u16 pxl_bits;\n        u32 comp;\n        u32 img_size;\n        u32 res_h;\n        u32 res_v;\n        u64 rsvd2;\n    } __attribute__((packed)) bmp_t;\n\n    bmp_t *bmp = (bmp_t *)bitmap;\n\n    bmp->magic    = 0x4D42;\n    bmp->size     = file_size;\n    bmp->rsvd     = 0;\n    bmp->data_off = 0x36;\n    bmp->hdr_size = 40;\n    bmp->width    = 1280;\n    bmp->height   = 720;\n    bmp->planes   = 1;\n    bmp->pxl_bits = 32;\n    bmp->comp     = 0;\n    bmp->img_size = 0x384000;\n    bmp->res_h    = 2834;\n    bmp->res_v    = 2834;\n    bmp->rsvd2    = 0;\n\n    char path[0x80];\n\n    strcpy(path, \"argon/screenshots\");\n    f_mkdir(path);\n    s_printf(path + strlen(path), \"/screen_%08X.bmp\", get_tmr_us());\n    sd_save_to_file(bitmap, file_size, path);\n\n    free(bitmap);\n    free(fb);\n\n    lv_obj_t * mbox = lv_mbox_create(lv_layer_top(), NULL);\n    lv_mbox_set_recolor(mbox, true);\n    lv_obj_set_width(mbox, LV_DPI * 4);\n    lv_obj_set_top(mbox, true);\n    lv_obj_set_auto_realign(mbox, true);\n    lv_obj_align(mbox, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 50);\n    lv_mbox_set_text(mbox, \"Screenshot saved!\");\n    lv_mbox_set_style(mbox, LV_MBOX_STYLE_BG, &bg);\n    lv_mbox_start_auto_close(mbox, 4000);\n}"
  },
  {
    "path": "argon-nx-gui/src/core/launcher.c",
    "content": "/*\n * Copyright (c) 2018 Guillem96\n * Copyright (c) 2018 CTCaer\n * \n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n#include \"core/launcher.h\"\n\n#include <string.h>\n\n#include \"libs/fatfs/ff.h\"\n\n#include \"utils/types.h\"\n#include \"utils/util.h\"\n#include \"utils/fs_utils.h\"\n\n#include \"soc/hw_init.h\"\n#include \"soc/bpmp.h\"\n\n#include \"gfx/gfx.h\"\n\n#include \"gfx/di.h\"\n\n#include \"mem/heap.h\"\n\n// This is a safe and unused DRAM region for our payloads.\n#define IPL_LOAD_ADDR      0x40003000\n#define EXT_PAYLOAD_ADDR   0xC03C0000\n#define PATCHED_RELOC_SZ   0x94\n#define RCM_PAYLOAD_ADDR   (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))\n#define PAYLOAD_ENTRY      0x40010000\n#define CBFS_SDRAM_EN_ADDR 0x4003e000\n#define COREBOOT_ADDR      (0xD0000000 - 0x100000)\n\nvoid (*ext_payload_ptr)() = (void *)EXT_PAYLOAD_ADDR;\n\nvoid reloc_patcher(u32 payload_size)\n{\n\tstatic const u32 START_OFF = 0x7C;\n\tstatic const u32 PAYLOAD_END_OFF = 0x84;\n\tstatic const u32 IPL_START_OFF = 0x88;\n\n\tmemcpy((u8 *)EXT_PAYLOAD_ADDR, (u8 *)IPL_LOAD_ADDR, PATCHED_RELOC_SZ);\n\n\t*(vu32 *)(EXT_PAYLOAD_ADDR + START_OFF) = PAYLOAD_ENTRY - ALIGN(PATCHED_RELOC_SZ, 0x10);\n\t*(vu32 *)(EXT_PAYLOAD_ADDR + PAYLOAD_END_OFF) = PAYLOAD_ENTRY + payload_size;\n\t*(vu32 *)(EXT_PAYLOAD_ADDR + IPL_START_OFF) = PAYLOAD_ENTRY;\n\n\tif (payload_size == 0x7000)\n\t{\n\t\tmemcpy((u8 *)(EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10)), (u8 *)COREBOOT_ADDR, 0x7000); //Bootblock\n\t\t*(vu32 *)CBFS_SDRAM_EN_ADDR = 0x4452414D;\n\t}\n}\n\nint launch_payload(argon_ctxt_t* argon_ctxt, char *path)\n{\n    FIL fp;\n    if (f_open(&fp, path, FA_READ))\n    {\n        gfx_printf(\"Cannot find %s\\n\", path);\n        return 1;\n    }\n\n    // Read and copy the payload to our chosen address\n    void *buf;\n    u32 size = f_size(&fp);\n\n    if (size < 0x30000)\n        buf = (void *)RCM_PAYLOAD_ADDR;\n    else\n        buf = (void *)COREBOOT_ADDR;\n\n    if (f_read(&fp, buf, size, NULL))\n    {\n        f_close(&fp);\n        gfx_printf(\"Error loading %s\\n\", path);\n        return 1;\n    }\n\n    f_close(&fp);\t\n    free(path);\n    path = NULL;\n\n    sd_unmount();\n\n    if (size < 0x30000)\n    {\n        reloc_patcher(ALIGN(size, 0x10));\n        reconfig_hw_workaround(argon_ctxt, false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32))));\n    }\n    else\n    {\n        reloc_patcher(0x7000);\n        if (*(vu32 *)CBFS_SDRAM_EN_ADDR != 0x4452414D)\n            return 1;\n        reconfig_hw_workaround(argon_ctxt, true, 0);\n    }\n\n    display_end();\n    argon_ctxt_destroy(argon_ctxt);\n    bpmp_mmu_disable();\n\tbpmp_clk_rate_set(BPMP_CLK_NORMAL);\n    // Launch our payload.\n    (*ext_payload_ptr)();\n\n\treturn 1;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/core/payloads.c",
    "content": "#include \"core/payloads.h\"\n#include <string.h>\n#include \"utils/dirlist.h\"\n#include \"mem/heap.h\"\n#include \"utils/util.h\"\n#include \"gfx/gfx.h\"\n\nvoid payload_full_path(const char* payload, char* result)\n{\n    strcpy(result, PAYLOADS_DIR);\n    strcat(result, \"/\");\n    strcat(result, payload);\n}\n\nvoid payload_logo_path(const char* payload, char* result)\n{   \n    char tmp[256];\n    strcpy(tmp, PAYLOADS_LOGOS_DIR);\n    strcat(tmp, \"/\");\n    strcat(tmp, payload);\n\n    strcpy(result, str_replace(tmp, \".bin\", \".bmp\"));\n}\n\n"
  },
  {
    "path": "argon-nx-gui/src/gfx/di.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"gfx/di.h\"\n#include \"gfx/gfx.h\"\n#include \"power/max77620.h\"\n#include \"power/max7762x.h\"\n#include \"soc/clock.h\"\n#include \"soc/gpio.h\"\n#include \"soc/i2c.h\"\n#include \"soc/pinmux.h\"\n#include \"soc/pmc.h\"\n#include \"soc/t210.h\"\n#include \"utils/util.h\"\n\n#pragma GCC push_options\n#pragma GCC target (\"thumb\")\n#pragma GCC optimize (\"Os\")\n\n#include \"gfx/di.inl\"\n\nstatic u32 _display_ver = 0;\n\nstatic void _display_dsi_wait(u32 timeout, u32 off, u32 mask)\n{\n\tu32 end = get_tmr_us() + timeout;\n\twhile (get_tmr_us() < end && DSI(off) & mask)\n\t\t;\n\tusleep(5);\n}\n\nvoid display_init()\n{\n\t// Power on.\n\tmax77620_regulator_set_volt_and_flags(REGULATOR_LDO0, 1200000, MAX77620_POWER_MODE_NORMAL); // Configure to 1.2V.\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO7, MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH | MAX77620_CNFG_GPIO_DRV_PUSHPULL);\n\n\t// Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks.\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x1010000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x1010000;\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = 0x18000000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = 0x18000000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x20000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIP_CAL) = 0xA;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = 0x80000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 0xA;\n\n\t// DPD idle.\n\tPMC(APBDEV_PMC_IO_DPD_REQ) = 0x40000000;\n\tPMC(APBDEV_PMC_IO_DPD2_REQ) = 0x40000000;\n\n\t// Config pins.\n\tPINMUX_AUX(PINMUX_AUX_NFC_EN) &= ~PINMUX_TRISTATE;\n\tPINMUX_AUX(PINMUX_AUX_NFC_INT) &= ~PINMUX_TRISTATE;\n\tPINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) &= ~PINMUX_TRISTATE;\n\tPINMUX_AUX(PINMUX_AUX_LCD_BL_EN) &= ~PINMUX_TRISTATE;\n\tPINMUX_AUX(PINMUX_AUX_LCD_RST) &= ~PINMUX_TRISTATE;\n\n\tgpio_config(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_MODE_GPIO); // Backlight +-5V.\n\tgpio_output_enable(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_OUTPUT_ENABLE); // Backlight +-5V.\n\tgpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_HIGH); // Backlight +5V enable.\n\n\tusleep(10000);\n\n\tgpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_HIGH); // Backlight -5V enable.\n\n\tusleep(10000);\n\n\tgpio_config(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_MODE_GPIO); // Backlight PWM, Enable, Reset.\n\tgpio_output_enable(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_OUTPUT_ENABLE);\n\tgpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH); // Backlight Enable enable.\n\n\t// Config display interface and display.\n\tMIPI_CAL(MIPI_CAL_MIPI_BIAS_PAD_CFG2) = 0;\n\n\texec_cfg((u32 *)CLOCK_BASE, _display_config_1, 4);\n\texec_cfg((u32 *)DISPLAY_A_BASE, _display_config_2, 94);\n\texec_cfg((u32 *)DSI_BASE, _display_config_3, 61);\n\n\tusleep(10000);\n\n\tgpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_HIGH); // Backlight Reset enable.\n\n\tusleep(60000);\n\n\tDSI(_DSIREG(DSI_BTA_TIMING)) = 0x50204;\n\tDSI(_DSIREG(DSI_WR_DATA)) = 0x337; // MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE\n\tDSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;\n\t_display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);\n\n\tDSI(_DSIREG(DSI_WR_DATA)) = 0x406; // MIPI_DCS_GET_DISPLAY_ID\n\tDSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;\n\t_display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);\n\n\tDSI(_DSIREG(DSI_HOST_CONTROL)) = DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC;\n\t_display_dsi_wait(150000, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA);\n\n\tusleep(5000);\n\n\t_display_ver = DSI(_DSIREG(DSI_RD_DATA));\n\tif (_display_ver == 0x10)\n\t\texec_cfg((u32 *)DSI_BASE, _display_config_4, 43);\n\n\tDSI(_DSIREG(DSI_WR_DATA)) = 0x1105; // MIPI_DCS_EXIT_SLEEP_MODE\n\tDSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;\n\n\tusleep(180000);\n\n\tDSI(_DSIREG(DSI_WR_DATA)) = 0x2905; // MIPI_DCS_SET_DISPLAY_ON\n\tDSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;\n\n\tusleep(20000);\n\n\texec_cfg((u32 *)CLOCK_BASE, _display_config_6, 3);\n\texec_cfg((u32 *)DSI_BASE, _display_config_5, 21);\n\tDISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = 4;\n\texec_cfg((u32 *)DSI_BASE, _display_config_7, 10);\n\n\tusleep(10000);\n\n\texec_cfg((u32 *)MIPI_CAL_BASE, _display_config_8, 6);\n\texec_cfg((u32 *)DSI_BASE, _display_config_9, 4);\n\texec_cfg((u32 *)MIPI_CAL_BASE, _display_config_10, 16);\n\n\tusleep(10000);\n\n\texec_cfg((u32 *)DISPLAY_A_BASE, _display_config_11, 113);\n}\n\nvoid display_backlight_pwm_init()\n{\n\tclock_enable_pwm();\n\n\tPWM(PWM_CONTROLLER_PWM_CSR_0) = (1 << 31); // Enable PWM\n\n\tPINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) >> 2) << 2 | 1; // PWM clock source.\n\tgpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight power mode.\n\t\n}\n\nvoid display_backlight(bool enable)\n{\n\tgpio_write(GPIO_PORT_V, GPIO_PIN_0, enable ? GPIO_HIGH : GPIO_LOW); // Backlight PWM GPIO.\n}\n\nvoid display_backlight_brightness(u32 brightness, u32 step_delay)\n{\n\tu32 old_value = (PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF;\n\tif (brightness == old_value)\n\t\treturn;\n\n\tif (brightness > 255)\n\t\tbrightness = 255;\n\n\tif (old_value < brightness)\n\t{\n\t\tfor (u32 i = old_value; i < brightness + 1; i++)\n\t\t{\n\t\t\tPWM(PWM_CONTROLLER_PWM_CSR_0) = (1 << 31) | (i << 16); // Enable PWM\n\t\t\tusleep(step_delay);\n\t\t}\n\t}\n\telse\n\t{\n\t\tfor (u32 i = old_value; i > brightness; i--)\n\t\t{\n\t\t\tPWM(PWM_CONTROLLER_PWM_CSR_0) = (1 << 31) | (i << 16); // Enable PWM\n\t\t\tusleep(step_delay);\n\t\t}\n\t}\n\tif (!brightness)\n\t\tPWM(PWM_CONTROLLER_PWM_CSR_0) = 0;\n}\n\nvoid display_end()\n{\n\tdisplay_backlight_brightness(0, 1000);\n\n\tDSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 1;\n\tDSI(_DSIREG(DSI_WR_DATA)) = 0x2805; // MIPI_DCS_SET_DISPLAY_OFF\n\n\tDISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX | WRITE_MUX;\n\tDSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;\n\n\texec_cfg((u32 *)DISPLAY_A_BASE, _display_config_12, 17);\n\texec_cfg((u32 *)DSI_BASE, _display_config_13, 16);\n\n\tusleep(10000);\n\n\tif (_display_ver == 0x10)\n\t\texec_cfg((u32 *)DSI_BASE, _display_config_14, 22);\n\n\tDSI(_DSIREG(DSI_WR_DATA)) = 0x1005; // MIPI_DCS_ENTER_SLEEP_MODE\n\tDSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;\n\n\tusleep(50000);\n\n\tgpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); //Backlight Reset disable.\n\n\tusleep(10000);\n\n\tgpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); //Backlight -5V disable.\n\n\tusleep(10000);\n\n\tgpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); //Backlight +5V disable.\n\n\tusleep(10000);\n\n\t// Disable clocks.\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = 0x1010000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = 0x1010000;\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = 0x18000000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = 0x18000000;\n\n\tDSI(_DSIREG(DSI_PAD_CONTROL_0)) = DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF);\n\tDSI(_DSIREG(DSI_POWER_CONTROL)) = 0;\n\n\tgpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight PWM.\n\n\tPINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_TRISTATE) | PINMUX_TRISTATE;\n\tPINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) >> 2) << 2 | 1;\n}\n\nvoid display_color_screen(u32 color)\n{\n\texec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_one_color, 8);\n\n\t// Configure display to show single color.\n\tDISPLAY_A(_DIREG(DC_WIN_AD_WIN_OPTIONS)) = 0;\n\tDISPLAY_A(_DIREG(DC_WIN_BD_WIN_OPTIONS)) = 0;\n\tDISPLAY_A(_DIREG(DC_WIN_CD_WIN_OPTIONS)) = 0;\n\tDISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color;\n\tDISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = (DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE) | GENERAL_ACT_REQ;\n\n\tusleep(35000);\n\n\tdisplay_backlight(true);\n}\n\nu32 *display_init_framebuffer()\n{\n\t// Sanitize framebuffer area.\n\t// memset((u32 *)FB_ADDRESS, 0, 0x3C0000);\n\t// This configures the framebuffer @ FB_ADDRESS with a resolution of 1280x720 (line stride 720).\n\texec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer, 32);\n\n\tusleep(35000);\n\n\treturn (u32 *)FB_ADDRESS;\n}\n\nu32 *display_init_framebuffer2()\n{\n\t// Sanitize framebuffer area.\n\tmemset((u32 *)FB_ADDRESS, 0, 0x3C0000);\n\t// This configures the framebuffer @ FB_ADDRESS with a resolution of 1280x720 (line stride 720).\n\texec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer2, 32);\n\n\tusleep(35000);\n\n\treturn (u32 *)FB_ADDRESS;\n}\n\n#pragma GCC pop_options\n"
  },
  {
    "path": "argon-nx-gui/src/gfx/gfx.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018-2019 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdarg.h>\n#include <string.h>\n#include \"gfx/gfx.h\"\n\n#pragma GCC push_options\n#pragma GCC target (\"thumb\")\n#pragma GCC optimize (\"Os\")\n\nstatic const u8 _gfx_font[] = {\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 032 ( )\n\t0x00, 0x30, 0x30, 0x18, 0x18, 0x00, 0x0C, 0x00, // Char 033 (!)\n\t0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, // Char 034 (\")\n\t0x00, 0x66, 0x66, 0xFF, 0x66, 0xFF, 0x66, 0x66, // Char 035 (#)\n\t0x00, 0x18, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x18, // Char 036 ($)\n\t0x00, 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62, // Char 037 (%)\n\t0x00, 0x3C, 0x66, 0x3C, 0x1C, 0xE6, 0x66, 0xFC, // Char 038 (&)\n\t0x00, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, // Char 039 (')\n\t0x00, 0x30, 0x18, 0x0C, 0x0C, 0x18, 0x30, 0x00, // Char 040 (()\n\t0x00, 0x0C, 0x18, 0x30, 0x30, 0x18, 0x0C, 0x00, // Char 041 ())\n\t0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, // Char 042 (*)\n\t0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, // Char 043 (+)\n\t0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0C, 0x00, // Char 044 (,)\n\t0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, // Char 045 (-)\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, // Char 046 (.)\n\t0x00, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, // Char 047 (/)\n\t0x00, 0x3C, 0x66, 0x76, 0x6E, 0x66, 0x3C, 0x00, // Char 048 (0)\n\t0x00, 0x18, 0x1C, 0x18, 0x18, 0x18, 0x7E, 0x00, // Char 049 (1)\n\t0x00, 0x3C, 0x62, 0x30, 0x0C, 0x06, 0x7E, 0x00, // Char 050 (2)\n\t0x00, 0x3C, 0x62, 0x38, 0x60, 0x66, 0x3C, 0x00, // Char 051 (3)\n\t0x00, 0x6C, 0x6C, 0x66, 0xFE, 0x60, 0x60, 0x00, // Char 052 (4)\n\t0x00, 0x7E, 0x06, 0x7E, 0x60, 0x66, 0x3C, 0x00, // Char 053 (5)\n\t0x00, 0x3C, 0x06, 0x3E, 0x66, 0x66, 0x3C, 0x00, // Char 054 (6)\n\t0x00, 0x7E, 0x30, 0x30, 0x18, 0x18, 0x18, 0x00, // Char 055 (7)\n\t0x00, 0x3C, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, // Char 056 (8)\n\t0x00, 0x3C, 0x66, 0x7C, 0x60, 0x66, 0x3C, 0x00, // Char 057 (9)\n\t0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, // Char 058 (:)\n\t0x00, 0x00, 0x18, 0x00, 0x18, 0x18, 0x0C, 0x00, // Char 059 (;)\n\t0x00, 0x70, 0x1C, 0x06, 0x06, 0x1C, 0x70, 0x00, // Char 060 (<)\n\t0x00, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x00, 0x00, // Char 061 (=)\n\t0x00, 0x0E, 0x38, 0x60, 0x60, 0x38, 0x0E, 0x00, // Char 062 (>)\n\t0x00, 0x3C, 0x66, 0x30, 0x18, 0x00, 0x18, 0x00, // Char 063 (?)\n\t0x00, 0x3C, 0x66, 0x76, 0x76, 0x06, 0x46, 0x3C, // Char 064 (@)\n\t0x00, 0x3C, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, // Char 065 (A)\n\t0x00, 0x3E, 0x66, 0x3E, 0x66, 0x66, 0x3E, 0x00, // Char 066 (B)\n\t0x00, 0x3C, 0x66, 0x06, 0x06, 0x66, 0x3C, 0x00, // Char 067 (C)\n\t0x00, 0x1E, 0x36, 0x66, 0x66, 0x36, 0x1E, 0x00, // Char 068 (D)\n\t0x00, 0x7E, 0x06, 0x1E, 0x06, 0x06, 0x7E, 0x00, // Char 069 (E)\n\t0x00, 0x3E, 0x06, 0x1E, 0x06, 0x06, 0x06, 0x00, // Char 070 (F)\n\t0x00, 0x3C, 0x66, 0x06, 0x76, 0x66, 0x3C, 0x00, // Char 071 (G)\n\t0x00, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, // Char 072 (H)\n\t0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, // Char 073 (I)\n\t0x00, 0x78, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, // Char 074 (J)\n\t0x00, 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x00, // Char 075 (K)\n\t0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7E, 0x00, // Char 076 (L)\n\t0x00, 0x46, 0x6E, 0x7E, 0x56, 0x46, 0x46, 0x00, // Char 077 (M)\n\t0x00, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x66, 0x00, // Char 078 (N)\n\t0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, // Char 079 (O)\n\t0x00, 0x3E, 0x66, 0x3E, 0x06, 0x06, 0x06, 0x00, // Char 080 (P)\n\t0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x70, 0x00, // Char 081 (Q)\n\t0x00, 0x3E, 0x66, 0x3E, 0x1E, 0x36, 0x66, 0x00, // Char 082 (R)\n\t0x00, 0x3C, 0x66, 0x0C, 0x30, 0x66, 0x3C, 0x00, // Char 083 (S)\n\t0x00, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, // Char 084 (T)\n\t0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, // Char 085 (U)\n\t0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, // Char 086 (V)\n\t0x00, 0x46, 0x46, 0x56, 0x7E, 0x6E, 0x46, 0x00, // Char 087 (W)\n\t0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00, // Char 088 (X)\n\t0x00, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00, // Char 089 (Y)\n\t0x00, 0x7E, 0x30, 0x18, 0x0C, 0x06, 0x7E, 0x00, // Char 090 (Z)\n\t0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, // Char 091 ([)\n\t0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00, // Char 092 (\\)\n\t0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, // Char 093 (])\n\t0x00, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, // Char 094 (^)\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, // Char 095 (_)\n\t0x00, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, // Char 096 (`)\n\t0x00, 0x00, 0x3C, 0x60, 0x7C, 0x66, 0x7C, 0x00, // Char 097 (a)\n\t0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x00, // Char 098 (b)\n\t0x00, 0x00, 0x3C, 0x06, 0x06, 0x06, 0x3C, 0x00, // Char 099 (c)\n\t0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00, // Char 100 (d)\n\t0x00, 0x00, 0x3C, 0x66, 0x7E, 0x06, 0x3C, 0x00, // Char 101 (e)\n\t0x00, 0x38, 0x0C, 0x3E, 0x0C, 0x0C, 0x0C, 0x00, // Char 102 (f)\n\t0x00, 0x00, 0x7C, 0x66, 0x7C, 0x40, 0x3C, 0x00, // Char 103 (g)\n\t0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x00, // Char 104 (h)\n\t0x00, 0x18, 0x00, 0x1C, 0x18, 0x18, 0x3C, 0x00, // Char 105 (i)\n\t0x00, 0x30, 0x00, 0x30, 0x30, 0x30, 0x1E, 0x00, // Char 106 (j)\n\t0x00, 0x06, 0x06, 0x36, 0x1E, 0x36, 0x66, 0x00, // Char 107 (k)\n\t0x00, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, // Char 108 (l)\n\t0x00, 0x00, 0x66, 0xFE, 0xFE, 0xD6, 0xC6, 0x00, // Char 109 (m)\n\t0x00, 0x00, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x00, // Char 110 (n)\n\t0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00, // Char 111 (o)\n\t0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x00, // Char 112 (p)\n\t0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x00, // Char 113 (q)\n\t0x00, 0x00, 0x3E, 0x66, 0x06, 0x06, 0x06, 0x00, // Char 114 (r)\n\t0x00, 0x00, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x00, // Char 115 (s)\n\t0x00, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x70, 0x00, // Char 116 (t)\n\t0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x00, // Char 117 (u)\n\t0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, // Char 118 (v)\n\t0x00, 0x00, 0xC6, 0xD6, 0xFE, 0x7C, 0x6C, 0x00, // Char 119 (w)\n\t0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, // Char 120 (x)\n\t0x00, 0x00, 0x66, 0x66, 0x7C, 0x60, 0x3C, 0x00, // Char 121 (y)\n\t0x00, 0x00, 0x7E, 0x30, 0x18, 0x0C, 0x7E, 0x00, // Char 122 (z)\n\t0x00, 0x18, 0x08, 0x08, 0x04, 0x08, 0x08, 0x18, // Char 123 ({)\n\t0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, // Char 124 (|)\n\t0x00, 0x0C, 0x08, 0x08, 0x10, 0x08, 0x08, 0x0C, // Char 125 (})\n\t0x00, 0x00, 0x00, 0x4C, 0x32, 0x00, 0x00, 0x00  // Char 126 (~)\n};\n\nvoid gfx_init_ctxt(u32 *fb, u32 width, u32 height, u32 stride)\n{\n\tg_gfx_ctxt.fb = fb;\n\tg_gfx_ctxt.width = width;\n\tg_gfx_ctxt.height = height;\n\tg_gfx_ctxt.stride = stride;\n}\n\nvoid gfx_clear_grey(u8 color)\n{\n\tmemset(g_gfx_ctxt.fb, color, 0x3C0000);\n}\n\nvoid gfx_clear_color(u32 color)\n{\n\tfor (u32 i = 0; i < g_gfx_ctxt.height * g_gfx_ctxt.stride; i++)\n\t\tg_gfx_ctxt.fb[i] = color;\n}\n\nvoid gfx_clear_partial_grey(u8 color, u32 pos_x, u32 height)\n{\n\tmemset(g_gfx_ctxt.fb + pos_x * g_gfx_ctxt.stride, color, height * 4 * g_gfx_ctxt.stride);\n}\n\nvoid gfx_con_init()\n{\n\tg_gfx_con.gfx_ctxt = &g_gfx_ctxt;\n\tg_gfx_con.fntsz = 16;\n\tg_gfx_con.x = 0;\n\tg_gfx_con.y = 0;\n\tg_gfx_con.savedx = 0;\n\tg_gfx_con.savedy = 0;\n\tg_gfx_con.fgcol = 0xFFCCCCCC;\n\tg_gfx_con.fillbg = 1;\n\tg_gfx_con.bgcol = 0xFF1B1B1B;\n\tg_gfx_con.mute = 0;\n}\n\nvoid gfx_con_setcol(u32 fgcol, int fillbg, u32 bgcol)\n{\n\tg_gfx_con.fgcol = fgcol;\n\tg_gfx_con.fillbg = fillbg;\n\tg_gfx_con.bgcol = bgcol;\n}\n\nvoid gfx_con_getpos(u32 *x, u32 *y)\n{\n\t*x = g_gfx_con.x;\n\t*y = g_gfx_con.y;\n}\n\nvoid gfx_con_setpos(u32 x, u32 y)\n{\n\tg_gfx_con.x = x;\n\tg_gfx_con.y = y;\n}\n\nvoid gfx_putc(char c)\n{\n\t// Duplicate code for performance reasons.\n\tswitch (g_gfx_con.fntsz)\n\t{\n\tcase 16:\n\t\tif (c >= 32 && c <= 126)\n\t\t{\n\t\t\tu8 *cbuf = (u8 *)&_gfx_font[8 * (c - 32)];\n\t\t\tu32 *fb = g_gfx_ctxt.fb + g_gfx_con.x + g_gfx_con.y * g_gfx_ctxt.stride;\n\n\t\t\tfor (u32 i = 0; i < 16; i+=2)\n\t\t\t{\n\t\t\t\tu8 v = *cbuf++;\n\t\t\t\tfor (u32 k = 0; k < 2; k++)\n\t\t\t\t{\n\t\t\t\t\tfor (u32 j = 0; j < 8; j++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (v & 1)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t*fb = g_gfx_con.fgcol;\n\t\t\t\t\t\t\tfb++;\n\t\t\t\t\t\t\t*fb = g_gfx_con.fgcol;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (g_gfx_con.fillbg)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t*fb = g_gfx_con.bgcol;\n\t\t\t\t\t\t\tfb++;\n\t\t\t\t\t\t\t*fb = g_gfx_con.bgcol;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tfb++;\n\t\t\t\t\t\tv >>= 1;\n\t\t\t\t\t\tfb++;\n\t\t\t\t\t}\n\t\t\t\t\tfb += g_gfx_ctxt.stride - 16;\n\t\t\t\t\tv = *cbuf;\n\t\t\t\t}\n\t\t\t}\n\t\t\tg_gfx_con.x += 16;\n\t\t}\n\t\telse if (c == '\\n')\n\t\t{\n\t\t\tg_gfx_con.x = 0;\n\t\t\tg_gfx_con.y +=16;\n\t\t\tif (g_gfx_con.y > g_gfx_ctxt.height - 16)\n\t\t\t\tg_gfx_con.y = 0;\n\t\t}\n\t\tbreak;\n\tcase 8:\n\tdefault:\n\t\tif (c >= 32 && c <= 126)\n\t\t{\n\t\t\tu8 *cbuf = (u8 *)&_gfx_font[8 * (c - 32)];\n\t\t\tu32 *fb = g_gfx_ctxt.fb + g_gfx_con.x + g_gfx_con.y * g_gfx_ctxt.stride;\n\t\t\tfor (u32 i = 0; i < 8; i++)\n\t\t\t{\n\t\t\t\tu8 v = *cbuf++;\n\t\t\t\tfor (u32 j = 0; j < 8; j++)\n\t\t\t\t{\n\t\t\t\t\tif (v & 1)\n\t\t\t\t\t\t*fb = g_gfx_con.fgcol;\n\t\t\t\t\telse if (g_gfx_con.fillbg)\n\t\t\t\t\t\t*fb = g_gfx_con.bgcol;\n\t\t\t\t\tv >>= 1;\n\t\t\t\t\tfb++;\n\t\t\t\t}\n\t\t\t\tfb += g_gfx_ctxt.stride - 8;\n\t\t\t}\n\t\t\tg_gfx_con.x += 8;\n\t\t}\n\t\telse if (c == '\\n')\n\t\t{\n\t\t\tg_gfx_con.x = 0;\n\t\t\tg_gfx_con.y += 8;\n\t\t\tif (g_gfx_con.y > g_gfx_ctxt.height - 8)\n\t\t\t\tg_gfx_con.y = 0;\n\t\t}\n\t\tbreak;\n\t}\n\t\n}\n\nvoid gfx_puts(const char *s)\n{\n\tif (!s || g_gfx_con.mute)\n\t\treturn;\n\n\tfor (; *s; s++)\n\t\tgfx_putc(*s);\n}\n\nstatic void _gfx_putn(u32 v, int base, char fill, int fcnt)\n{\n\tchar buf[65];\n\tstatic const char digits[] = \"0123456789ABCDEFghijklmnopqrstuvwxyz\";\n\tchar *p;\n\tint c = fcnt;\n\n\tif (base > 36)\n\t\treturn;\n\n\tp = buf + 64;\n\t*p = 0;\n\tdo\n\t{\n\t\tc--;\n\t\t*--p = digits[v % base];\n\t\tv /= base;\n\t} while (v);\n\n\tif (fill != 0)\n\t{\n\t\twhile (c > 0)\n\t\t{\n\t\t\t*--p = fill;\n\t\t\tc--;\n\t\t}\n\t}\n\n\tgfx_puts(p);\n}\n\nvoid gfx_put_small_sep()\n{\n\tu8 prevFontSize = g_gfx_con.fntsz;\n\tg_gfx_con.fntsz = 8;\n\tgfx_putc('\\n');\n\tg_gfx_con.fntsz = prevFontSize;\n}\n\nvoid gfx_put_big_sep()\n{\n\tu8 prevFontSize = g_gfx_con.fntsz;\n\tg_gfx_con.fntsz = 16;\n\tgfx_putc('\\n');\n\tg_gfx_con.fntsz = prevFontSize;\n}\n\nvoid gfx_printf(const char *fmt, ...)\n{\n\tif (g_gfx_con.mute)\n\t\treturn;\n\n\tva_list ap;\n\tint fill, fcnt;\n\n\tva_start(ap, fmt);\n\twhile(*fmt)\n\t{\n\t\tif(*fmt == '%')\n\t\t{\n\t\t\tfmt++;\n\t\t\tfill = 0;\n\t\t\tfcnt = 0;\n\t\t\tif ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ')\n\t\t\t{\n\t\t\t\tfcnt = *fmt;\n\t\t\t\tfmt++;\n\t\t\t\tif (*fmt >= '0' && *fmt <= '9')\n\t\t\t\t{\n\t\t\t\t\tfill = fcnt;\n\t\t\t\t\tfcnt = *fmt - '0';\n\t\t\t\t\tfmt++;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfill = ' ';\n\t\t\t\t\tfcnt -= '0';\n\t\t\t\t}\n\t\t\t}\n\t\t\tswitch(*fmt)\n\t\t\t{\n\t\t\tcase 'c':\n\t\t\t\tgfx_putc(va_arg(ap, u32));\n\t\t\t\tbreak;\n\t\t\tcase 's':\n\t\t\t\tgfx_puts(va_arg(ap, char *));\n\t\t\t\tbreak;\n\t\t\tcase 'd':\n\t\t\t\t_gfx_putn(va_arg(ap, u32), 10, fill, fcnt);\n\t\t\t\tbreak;\n\t\t\tcase 'p':\n\t\t\tcase 'P':\n\t\t\tcase 'x':\n\t\t\tcase 'X':\n\t\t\t\t_gfx_putn(va_arg(ap, u32), 16, fill, fcnt);\n\t\t\t\tbreak;\n\t\t\tcase 'k':\n\t\t\t\tg_gfx_con.fgcol = va_arg(ap, u32);\n\t\t\t\tbreak;\n\t\t\tcase 'K':\n\t\t\t\tg_gfx_con.bgcol = va_arg(ap, u32);\n\t\t\t\tg_gfx_con.fillbg = 1;\n\t\t\t\tbreak;\n\t\t\tcase '%':\n\t\t\t\tgfx_putc('%');\n\t\t\t\tbreak;\n\t\t\tcase '\\0':\n\t\t\t\tgoto out;\n\t\t\tdefault:\n\t\t\t\tgfx_putc('%');\n\t\t\t\tgfx_putc(*fmt);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tgfx_putc(*fmt);\n\t\tfmt++;\n\t}\n\n\tout:\n\tva_end(ap);\n}\n\nvoid gfx_hexdump(u32 base, const u8 *buf, u32 len)\n{\n\tif (g_gfx_con.mute)\n\t\treturn;\n\n\tu8 prevFontSize = g_gfx_con.fntsz;\n\tg_gfx_con.fntsz = 8;\n\tfor(u32 i = 0; i < len; i++)\n\t{\n\t\tif(i % 0x10 == 0)\n\t\t{\n\t\t\tif(i != 0)\n\t\t\t{\n\t\t\t\tgfx_puts(\"| \");\n\t\t\t\tfor(u32 j = 0; j < 0x10; j++)\n\t\t\t\t{\n\t\t\t\t\tu8 c = buf[i - 0x10 + j];\n\t\t\t\t\tif(c >= 32 && c <= 126)\n\t\t\t\t\t\tgfx_putc(c);\n\t\t\t\t\telse\n\t\t\t\t\t\tgfx_putc('.');\n\t\t\t\t}\n\t\t\t\tgfx_putc('\\n');\n\t\t\t}\n\t\t\tgfx_printf(\"%08x: \", base + i);\n\t\t}\n\t\tgfx_printf(\"%02x \", buf[i]);\n\t\tif (i == len - 1)\n\t\t{\n\t\t\tint ln = len % 0x10 != 0;\n\t\t\tu32 k = 0x10 - 1;\n\t\t\tif (ln)\n\t\t\t{\n\t\t\t\tk = (len & 0xF) - 1;\n\t\t\t\tfor (u32 j = 0; j < 0x10 - k; j++)\n\t\t\t\t\tgfx_puts(\"   \");\n\t\t\t}\n\t\t\tgfx_puts(\"| \");\n\t\t\tfor(u32 j = 0; j < (ln ? k : k + 1); j++)\n\t\t\t{\n\t\t\t\tu8 c = buf[i - k + j];\n\t\t\t\tif(c >= 32 && c <= 126)\n\t\t\t\t\tgfx_putc(c);\n\t\t\t\telse\n\t\t\t\t\tgfx_putc('.');\n\t\t\t}\n\t\t\tgfx_putc('\\n');\n\t\t}\n\t}\n\tgfx_putc('\\n');\n\tg_gfx_con.fntsz = prevFontSize;\n}\n\nstatic int abs(int x)\n{\n\tif (x < 0)\n\t\treturn -x;\n\treturn x;\n}\n\nvoid gfx_set_pixel(u32 x, u32 y, u32 color)\n{\n\tg_gfx_ctxt.fb[x + y * g_gfx_ctxt.stride] = color;\n}\n\nvoid gfx_line(int x0, int y0, int x1, int y1, u32 color)\n{\n\tint dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;\n\tint dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1;\n\tint err = (dx > dy ? dx : -dy) / 2, e2;\n\n\twhile (1)\n\t{\n\t\tgfx_set_pixel(x0, y0, color);\n\t\tif (x0 == x1 && y0 == y1)\n\t\t\tbreak;\n\t\te2 = err;\n\t\tif (e2 >-dx)\n\t\t{\n\t\t\terr -= dy;\n\t\t\tx0 += sx;\n\t\t}\n\t\tif (e2 < dy)\n\t\t{\n\t\t\terr += dx;\n\t\t\ty0 += sy;\n\t\t}\n\t}\n}\n\n#pragma GCC pop_options\n\nvoid gfx_set_rect_grey(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)\n{\n\tu32 pos = 0;\n\tfor (u32 y = pos_y; y < (pos_y + size_y); y++)\n\t{\n\t\tfor (u32 x = pos_x; x < (pos_x + size_x); x++)\n\t\t{\n\t\t\tmemset(&g_gfx_ctxt.fb[x + y*g_gfx_ctxt.stride], buf[pos], 4);\n\t\t\tpos++;\n\t\t}\n\t}\n}\n\n\nvoid gfx_set_rect_rgb(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)\n{\n\tu32 pos = 0;\n\tfor (u32 y = pos_y; y < (pos_y + size_y); y++)\n\t{\n\t\tfor (u32 x = pos_x; x < (pos_x + size_x); x++)\n\t\t{\n\t\t\tg_gfx_ctxt.fb[x + y * g_gfx_ctxt.stride] = buf[pos + 2] | (buf[pos + 1] << 8) | (buf[pos] << 16);\n\t\t\tpos+=3;\n\t\t}\n\t}\n}\n\nvoid gfx_set_rect_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)\n{\n\tu32 *ptr = (u32 *)buf;\n\tfor (u32 y = pos_y; y < (pos_y + size_y); y++)\n\t\tfor (u32 x = pos_x; x < (pos_x + size_x); x++)\n\t\t\tg_gfx_ctxt.fb[x + y * g_gfx_ctxt.stride] = *ptr++;\n}\n\nvoid gfx_set_rect_argb_land(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)\n{\n\tu32 pos = 0;\n\tfor (u32 y = pos_y; y < (pos_y + size_y); y++)\n\t{\n\t\tfor (u32 x = pos_x; x < (pos_x + size_x); x++)\n\t\t{\n\t\t\tg_gfx_ctxt.fb[y + (g_gfx_ctxt.width - x) * g_gfx_ctxt.stride] = buf[pos];\n\t\t\tpos+=1;\n\t\t}\n\t}\n}\n\nvoid gfx_fill_rect_argb(const u32 color, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)\n{\n\tfor (u32 y = pos_y; y < (pos_y + size_y); y++)\n\t\tfor (u32 x = pos_x; x < (pos_x + size_x); x++)\n\t\t\tg_gfx_ctxt.fb[x + y * g_gfx_ctxt.stride] = color;\n}\n\nvoid gfx_render_bmp_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)\n{\n\tfor (u32 y = pos_y; y < (pos_y + size_y); y++)\n\t{\n\t\tfor (u32 x = pos_x; x < (pos_x + size_x); x++)\n\t\t\tg_gfx_ctxt.fb[x + y * g_gfx_ctxt.stride] = buf[(size_y + pos_y - 1 - y ) * size_x + x - pos_x];\n\t}\n}\n\n__attribute__((target(\"arm\"))) void gfx_set_rect_land_pitch(u32 *fb, const u32 *buf, u32 pos_x, u32 pos_y, u32 pos_x2, u32 pos_y2)\n{\n\tu32 *ptr = (u32 *)buf;\n\n\tu32 pixels_w = pos_x2 - pos_x + 1;\n\n\tif (!(pixels_w % 8))\n\t{\n\t\tfor (u32 y = pos_y; y < (pos_y2 + 1); y++)\n\t\t\tfor (u32 x = pos_x; x < (pos_x2 + 1); x+=8)\n\t\t\t{\n\t\t\t\tu32 *fbx = &fb[x * g_gfx_ctxt.stride + y];\n\n\t\t\t\tfbx[0]                   = *ptr++;\n\t\t\t\tfbx[g_gfx_ctxt.stride]     = *ptr++;\n\t\t\t\tfbx[g_gfx_ctxt.stride * 2] = *ptr++;\n\t\t\t\tfbx[g_gfx_ctxt.stride * 3] = *ptr++;\n\t\t\t\tfbx[g_gfx_ctxt.stride * 4] = *ptr++;\n\t\t\t\tfbx[g_gfx_ctxt.stride * 5] = *ptr++;\n\t\t\t\tfbx[g_gfx_ctxt.stride * 6] = *ptr++;\n\t\t\t\tfbx[g_gfx_ctxt.stride * 7] = *ptr++;\n\t\t\t}\n\t}\n\telse\n\t{\n\t\tfor (u32 y = pos_y; y < (pos_y2 + 1); y++)\n\t\t\tfor (u32 x = pos_x; x < (pos_x2 + 1); x++)\n\t\t\t\tfb[x * g_gfx_ctxt.stride + y] = *ptr++;\n\t}\n}\n\n__attribute__((target(\"arm\"))) void gfx_set_rect_land_block(const u32 *buf, u32 pos_x, u32 pos_y, u32 pos_x2, u32 pos_y2)\n{\n\tu32 *ptr = (u32 *)buf;\n\tu32 GOB_address = 0;\n\tu32 addr = 0;\n\tu32 x2 = 0;\n\n\t// Optimized\n\tu32 image_width_in_gobs = 655360; //1280\n\tfor (u32 y = pos_y; y < (pos_y2 + 1); y++)\n\t{\n\t\tfor (u32 x = pos_x; x < (pos_x2 + 1); x++)\n\t\t{\n\t\t\tGOB_address = (y >> 7) * image_width_in_gobs + ((x >> 4) << 13) + (((y % 128) >> 3) << 9);\n\n\t\t\tx2 = x << 2;\n\t\t\taddr = GOB_address \n\t\t\t\t+ (((x2 % 64) >> 5) << 8)\n\t\t\t\t+ (((y % 8) >> 1) << 6)\n\t\t\t\t+ (((x2 % 32) >> 4) << 5)\n\t\t\t\t+ ((y % 2) << 4) + (x2 % 16);\n\n\t\t\t*(u32 *)(g_gfx_ctxt.fb + (addr >> 2)) = *ptr++;\n\t\t}\n\t}\n\n\t// Proper\n\t// u32 block_height = 16;\n\t// u32 image_width_in_gobs = (512 * block_height * 1280 * 4) / 64;\n\t// for (u32 y = pos_y; y <= pos_y2; y++)\n\t// {\n\t// \tfor (int x = pos_x; x <= pos_x2; x++)\n\t// \t{\n\t// \t\tGOB_address = (y / (8 * block_height)) * image_width_in_gobs + ((x * 4 / 64) * 512 * block_height) + ((y % (8 * block_height) / 8) * 512);\n\n\t// \t\tx2 = x << 2;\n\t// \t\taddr = GOB_address \n\t// \t\t\t+ (((x2 % 64) >> 5) << 8)\n\t// \t\t\t+ (((y % 8) >> 1) << 6)\n\t// \t\t\t+ (((x2 % 32) >> 4) << 5)\n\t// \t\t\t+ ((y % 2) << 4) + (x2 % 16);\n\n\t// \t\t*(u32 *)(g_gfx_ctxt.fb + (addr >> 2)) = *ptr++;\n\t// \t}\n\t// }\n}\n"
  },
  {
    "path": "argon-nx-gui/src/gfx/lvgl_adapter.c",
    "content": "#include \"gfx/gfx.h\"\n#include \"gfx/di.h\"\n\n#include \"gfx/lvgl_adapter.h\"\n#include \"libs/lvgl/lvgl.h\"\n#include \"minerva/minerva.h\"\n#include \"utils/touch.h\"\n#include \"utils/util.h\"\n#include \"utils/fs_utils.h\"\n\n#include \"core/custom-gui.h\"\n\n#include \"mem/heap.h\"\n\nstatic touch_event_t touchpad;\nstatic bool first_print = false;\n\nvoid display_flush(lv_disp_drv_t *disp,\n                   const lv_area_t *area,\n                   lv_color_t *color_p)\n{\n    gfx_set_rect_land_pitch(g_gfx_ctxt.fb, (u32 *)color_p,\n                            area->x1,\n                            area->y1,\n                            area->x2, area->y2);\n\n    if (!first_print)\n    {\n        first_print = true;\n        display_backlight_brightness(100, 1000);\n        display_init_framebuffer();\n    }\n\n    lv_disp_flush_ready(disp);\n}\n\nbool handle_touch(lv_indev_drv_t *indev, lv_indev_data_t *data)\n{\n    touch_poll(&touchpad);\n\n    if (touchpad.fingers >= 2)\n\t\ttake_screenshot();\n\n    switch (touchpad.type & STMFTS_MASK_EVENT_ID)\n    {\n    case STMFTS_EV_MULTI_TOUCH_ENTER:\n    case STMFTS_EV_MULTI_TOUCH_MOTION:\n        data->state = LV_INDEV_STATE_PR;\n        data->point.x = touchpad.x;\n        data->point.y = touchpad.y;\n\n        break;\n    case STMFTS_EV_MULTI_TOUCH_LEAVE:\n        data->state = LV_INDEV_STATE_REL;\n        data->point.x = touchpad.x;\n        data->point.y = touchpad.y;\n        break;\n    case STMFTS_EV_NO_EVENT:\n    default:\n        if (touchpad.touch)\n        {\n            data->state = LV_INDEV_STATE_PR;\n        }\n        else\n        {\n            data->point.x = touchpad.x;\n            data->point.y = touchpad.y;\n            data->state = LV_INDEV_STATE_REL;\n            //return true;\n        }\n        break;\n    }\n\n    return false; /*Return `false` because we are not buffering and no more data to read*/\n}\n\nvoid lvgl_adapter_init(argon_ctxt_t *argon_ctxt)\n{\n    lv_init();\n\n    static lv_disp_buf_t disp_buf;\n    lv_disp_buf_init(&disp_buf,\n                     argon_ctxt->vdb,\n                     NULL,\n                     LV_HOR_RES_MAX * LV_VER_RES_MAX);\n\n    // Initialize framebuffer drawing functions.\n    lv_disp_drv_t disp_drv;            /*Descriptor of a display driver*/\n    lv_disp_drv_init(&disp_drv);       /*Basic initialization*/\n    disp_drv.flush_cb = display_flush; /*Set your driver function*/\n    disp_drv.buffer = &disp_buf;       /*Assign the buffer to the display*/\n    lv_disp_drv_register(&disp_drv);   /*Finally register the driver*/\n\n    // Touch support\n    lv_indev_drv_t indev_drv;\n    lv_indev_drv_init(&indev_drv);\n    indev_drv.type = LV_INDEV_TYPE_POINTER;\n    indev_drv.read_cb = handle_touch;\n    lv_indev_drv_register(&indev_drv);\n    touchpad.touch = false;\n\n    lv_task_create(minerva_periodic_training,\n                   500,\n                   LV_TASK_PRIO_HIGHEST,\n                   argon_ctxt->mtc_conf);\n\n    lv_theme_t *th = lv_theme_argon_init(10, NULL);\n    lv_theme_set_current(th);\n}\n\nlv_img_dsc_t *bmp_to_lvimg_obj(const char *path)\n{\n\tu8 *bitmap = sd_file_read((char*)path);\n\tif (!bitmap) \n    {\n        gfx_printf(\"Not found\\n\");\n        return NULL;\n    }\n\n\tstruct _bmp_data\n\t{\n\t\tu32 size;\n\t\tu32 size_x;\n\t\tu32 size_y;\n\t\tu32 offset;\n\t};\n\n\tstruct _bmp_data bmpData;\n\n\t// Get values manually to avoid unaligned access.\n\tbmpData.size = bitmap[2] | bitmap[3] << 8 |\n\t\tbitmap[4] << 16 | bitmap[5] << 24;\n\tbmpData.offset = bitmap[10] | bitmap[11] << 8 |\n\t\tbitmap[12] << 16 | bitmap[13] << 24;\n\tbmpData.size_x = bitmap[18] | bitmap[19] << 8 |\n\t\tbitmap[20] << 16 | bitmap[21] << 24;\n\tbmpData.size_y = bitmap[22] | bitmap[23] << 8 |\n\t\tbitmap[24] << 16 | bitmap[25] << 24;\n\t// Sanity check.\n\tif (bitmap[0] == 'B' &&\n\t\tbitmap[1] == 'M' &&\n\t\tbitmap[28] == 32) // Only 32 bit BMPs allowed.\n\t{\n\t\t// Check if non-default Bottom-Top.\n\t\tbool flipped = false;\n\t\tif (bmpData.size_y & 0x80000000)\n\t\t{\n\t\t\tbmpData.size_y = ~(bmpData.size_y) + 1;\n\t\t\tflipped = true;\n\t\t}\n\n\t\tlv_img_dsc_t *img_desc = (lv_img_dsc_t *)bitmap;\n\t\tu32 offset_copy = ALIGN((u32)bitmap + sizeof(lv_img_dsc_t), 0x10);\n\t\n\t\timg_desc->header.always_zero = 0;\n\t\timg_desc->header.w = bmpData.size_x;\n\t\timg_desc->header.h = bmpData.size_y;\n\t\timg_desc->header.cf = (bitmap[28] == 32) ? LV_IMG_CF_TRUE_COLOR_ALPHA : LV_IMG_CF_TRUE_COLOR;\n\t\timg_desc->data_size = bmpData.size - bmpData.offset;\n\t\timg_desc->data = (u8 *)offset_copy;\n\n\t\tu32 *tmp = malloc(bmpData.size);\n\t\tu32 *tmp2 = (u32 *)offset_copy;\n\n\t\t// Copy the unaligned data to an aligned buffer.\n\t\tmemcpy((u8 *)tmp, bitmap + bmpData.offset, img_desc->data_size);\n\t\tu32 j = 0;\n\n\t\tif (!flipped)\n\t\t{\n\t\t\tfor (u32 y = 0; y < bmpData.size_y; y++)\n\t\t\t{\n\t\t\t\tfor (u32 x = 0; x < bmpData.size_x; x++)\n\t\t\t\t\ttmp2[j++] = tmp[(bmpData.size_y - 1 - y ) * bmpData.size_x + x];\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor (u32 y = 0; y < bmpData.size_y; y++)\n\t\t\t{\n\t\t\t\tfor (u32 x = 0; x < bmpData.size_x; x++)\n\t\t\t\t\ttmp2[j++] = tmp[y * bmpData.size_x + x];\n\t\t\t}\n\t\t}\n\t\t\n\t\tfree(tmp);\n\t}\n\telse\n\t{\n\t\tfree(bitmap);\n        gfx_printf(\"Failed sanitize\\n\");\n\t\treturn NULL;\n\t}\n\t\n\treturn (lv_img_dsc_t *)bitmap;\n}"
  },
  {
    "path": "argon-nx-gui/src/ianos/ianos.c",
    "content": "/*\n * Copyright (c) 2018 M4xw\n * Copyright (c) 2018-2019 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"ianos/ianos.h\"\n#include \"utils/types.h\"\n#include \"libs/elfload/elfload.h\"\n#include \"mem/heap.h\"\n#include \"gfx/gfx.h\"\n\n#define IRAM_LIB_ADDR 0x4002B000\n#define DRAM_LIB_ADDR 0xE0000000\n\n// Module Callback\ntypedef void (*cbMainModule_t)(const char *s);\ntypedef void (*memcpy_t)(void *, void *, size_t);\ntypedef void (*memset_t)(void *, int, size_t);\n\ntypedef struct _bdkParams_t\n{\n\tgfx_con_t *gfxCon;\n\tgfx_ctxt_t *gfxCtx;\n\theap_t *sharedHeap;\n\tmemcpy_t memcpy;\n\tmemset_t memset;\n} *bdkParams_t;\n\n// Module Entrypoint\ntypedef void (*moduleEntrypoint_t)(void *, bdkParams_t);\n\nextern heap_t _heap;\n\nextern void *sd_file_read(const char *path, u32 *fsize);\nextern bool sd_mount();\nextern void sd_unmount(bool deinit);\n\nvoid *elfBuf = NULL;\nvoid *fileBuf = NULL;\n\nstatic void _ianos_call_ep(moduleEntrypoint_t entrypoint, void *moduleConfig)\n{\n\tbdkParams_t bdkParameters = (bdkParams_t)malloc(sizeof(struct _bdkParams_t));\n\tbdkParameters->gfxCon = &g_gfx_con;\n\tbdkParameters->gfxCtx = &g_gfx_ctxt;\n\tbdkParameters->memcpy = (memcpy_t)&memcpy;\n\tbdkParameters->memset = (memset_t)&memset;\n\tbdkParameters->sharedHeap = &_heap;\n\n\tentrypoint(moduleConfig, bdkParameters);\n}\n\nstatic void *_ianos_alloc_cb(el_ctx *ctx, Elf_Addr phys, Elf_Addr virt, Elf_Addr size)\n{\n\t(void)ctx;\n\t(void)phys;\n\t(void)size;\n\treturn (void *)virt;\n}\n\nstatic bool _ianos_read_cb(el_ctx *ctx, void *dest, size_t numberBytes, size_t offset)\n{\n\t(void)ctx;\n\n\tmemcpy(dest, fileBuf + offset, numberBytes);\n\n\treturn true;\n}\n\n//TODO: Support shared libraries.\nuintptr_t ianos_loader(bool sdmount, char *path, elfType_t type, void *moduleConfig)\n{\n\tuintptr_t epaddr = 0;\n\n\tif (sdmount)\n\t{\n\t\tif (!sd_mount())\n\t\t\tgoto elfLoadFinalOut;\n\t}\n\n\tfileBuf = sd_file_read(path, NULL);\n\n\tif (sdmount)\n\t\tsd_unmount(true);\n\n\tif (!fileBuf)\n\t\tgoto elfLoadFinalOut;\n\n\n\tel_ctx ctx;\n\tctx.pread = _ianos_read_cb;\n\n\tif (el_init(&ctx))\n\t\tgoto elfLoadFinalOut;\n\n\t// Set our relocated library's buffer.\n\tswitch (type & 0xFFFF)\n\t{\n\tcase EXEC_ELF:\n\tcase AR64_ELF:\n\t\telfBuf = (void *)DRAM_LIB_ADDR;\n\t\tsd_unmount(true);\n\t\tbreak;\n\tdefault:\n\t\telfBuf = memalign(ctx.align, ctx.memsz);\n\t}\n\n\tif (!elfBuf)\n\t\tgoto elfLoadFinalOut;\n\n\t// Load and relocate library.\n\tctx.base_load_vaddr = ctx.base_load_paddr = (uintptr_t)elfBuf;\n\tif (el_load(&ctx, _ianos_alloc_cb))\n\t\tgoto elfFreeOut;\n\n\tif (el_relocate(&ctx))\n\t\tgoto elfFreeOut;\n\n\t// Launch.\n\tepaddr = ctx.ehdr.e_entry + (uintptr_t)elfBuf;\n\tmoduleEntrypoint_t ep = (moduleEntrypoint_t)epaddr;\n\n\t_ianos_call_ep(ep, moduleConfig);\n\nelfFreeOut:\n\tfree(fileBuf);\n\telfBuf = NULL;\n\tfileBuf = NULL;\n\nelfLoadFinalOut:\n\n\treturn epaddr;\n}"
  },
  {
    "path": "argon-nx-gui/src/libs/compr/blz.c",
    "content": "/*\n * Copyright (c) 2018 rajkosto\n * Copyright (c) 2018 SciresM\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdlib.h>\n#include <string.h>\n\n#include \"libs/compr/blz.h\"\n\nconst blz_footer *blz_get_footer(const unsigned char *compData, unsigned int compDataLen, blz_footer *outFooter)\n{\n\tif (compDataLen < sizeof(blz_footer))\n\t\treturn NULL;\n\n\tconst blz_footer *srcFooter = (const blz_footer*)&compData[compDataLen - sizeof(blz_footer)];\n\tif (outFooter != NULL)\n\t\tmemcpy(outFooter, srcFooter, sizeof(blz_footer)); // Must be a memcpy because no umaligned accesses on ARMv4.\n\n\treturn srcFooter;\n}\n\n// From https://github.com/SciresM/hactool/blob/master/kip.c which is exactly how kernel does it, thanks SciresM!\nint blz_uncompress_inplace(unsigned char *dataBuf, unsigned int compSize, const blz_footer *footer) \n{\n\tu32 addl_size = footer->addl_size;\n\tu32 header_size = footer->header_size;\n\tu32 cmp_and_hdr_size = footer->cmp_and_hdr_size;\n\t\n\tunsigned char* cmp_start = &dataBuf[compSize] - cmp_and_hdr_size;\n\tu32 cmp_ofs = cmp_and_hdr_size - header_size;\n\tu32 out_ofs = cmp_and_hdr_size + addl_size;\n\t\n\twhile (out_ofs) \n\t{\n\t\tunsigned char control = cmp_start[--cmp_ofs];\n\t\tfor (unsigned int i=0; i<8; i++) \n\t\t{\n\t\t\tif (control & 0x80) \n\t\t\t{\n\t\t\t\tif (cmp_ofs < 2) \n\t\t\t\t\treturn 0; // Out of bounds.\n\n\t\t\t\tcmp_ofs -= 2;\n\t\t\t\tu16 seg_val = ((unsigned int)(cmp_start[cmp_ofs + 1]) << 8) | cmp_start[cmp_ofs];\n\t\t\t\tu32 seg_size = ((seg_val >> 12) & 0xF) + 3;\n\t\t\t\tu32 seg_ofs = (seg_val & 0x0FFF) + 3;\n\t\t\t\tif (out_ofs < seg_size) // Kernel restricts segment copy to stay in bounds.\n\t\t\t\t\tseg_size = out_ofs;\n\n\t\t\t\tout_ofs -= seg_size;\n\n\t\t\t\tfor (unsigned int j = 0; j < seg_size; j++)\n\t\t\t\t\tcmp_start[out_ofs + j] = cmp_start[out_ofs + j + seg_ofs];\n\t\t\t}\n\t\t\telse \n\t\t\t{\n\t\t\t\t// Copy directly.\n\t\t\t\tif (cmp_ofs < 1) \n\t\t\t\t\treturn 0; //out of bounds\n\n\t\t\t\tcmp_start[--out_ofs] = cmp_start[--cmp_ofs];\n\t\t\t}\n\t\t\tcontrol <<= 1;\n\t\t\tif (out_ofs == 0) // Blz works backwards, so if it reaches byte 0, it's done.\n\t\t\t\treturn 1; \n\t\t\t}\n\t\t}\n\n\treturn 1;\n}\n\nint blz_uncompress_srcdest(const unsigned char *compData, unsigned int compDataLen, unsigned char *dstData, unsigned int dstSize)\n{\n\tblz_footer footer;\n\tconst blz_footer *compFooterPtr = blz_get_footer(compData, compDataLen, &footer);\n\tif (compFooterPtr == NULL)\n\t\treturn 0;\n\n\t// Decompression must be done in-place, so need to copy the relevant compressed data first.\n\tunsigned int numCompBytes = (const unsigned char*)(compFooterPtr)-compData;\n\tmemcpy(dstData, compData, numCompBytes);\n\tmemset(&dstData[numCompBytes], 0, dstSize - numCompBytes);\n\n\treturn blz_uncompress_inplace(dstData, compDataLen, &footer);\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/compr/lz.c",
    "content": "/*************************************************************************\n* Name:        lz.c\n* Author:      Marcus Geelnard\n* Description: LZ77 coder/decoder implementation.\n* Reentrant:   Yes\n*\n* The LZ77 compression scheme is a substitutional compression scheme\n* proposed by Abraham Lempel and Jakob Ziv in 1977. It is very simple in\n* its design, and uses no fancy bit level compression.\n*\n* This is my first attempt at an implementation of a LZ77 code/decoder.\n*\n* The principle of the LZ77 compression algorithm is to store repeated\n* occurrences of strings as references to previous occurrences of the same\n* string. The point is that the reference consumes less space than the\n* string itself, provided that the string is long enough (in this\n* implementation, the string has to be at least 4 bytes long, since the\n* minimum coded reference is 3 bytes long). Also note that the term\n* \"string\" refers to any kind of byte sequence (it does not have to be\n* an ASCII string, for instance).\n*\n* The coder uses a brute force approach to finding string matches in the\n* history buffer (or \"sliding window\", if you wish), which is very, very\n* slow. I recon the complexity is somewhere between O(n^2) and O(n^3),\n* depending on the input data.\n*\n* There is also a faster implementation that uses a large working buffer\n* in which a \"jump table\" is stored, which is used to quickly find\n* possible string matches (see the source code for LZ_CompressFast() for\n* more information). The faster method is an order of magnitude faster,\n* but still quite slow compared to other compression methods.\n*\n* The upside is that decompression is very fast, and the compression ratio\n* is often very good.\n*\n* The reference to a string is coded as a (length,offset) pair, where the\n* length indicates the length of the string, and the offset gives the\n* offset from the current data position. To distinguish between string\n* references and literal strings (uncompressed bytes), a string reference\n* is preceded by a marker byte, which is chosen as the least common byte\n* symbol in the input data stream (this marker byte is stored in the\n* output stream as the first byte).\n*\n* Occurrences of the marker byte in the stream are encoded as the marker\n* byte followed by a zero byte, which means that occurrences of the marker\n* byte have to be coded with two bytes.\n*\n* The lengths and offsets are coded in a variable length fashion, allowing\n* values of any magnitude (up to 4294967295 in this implementation).\n*\n* With this compression scheme, the worst case compression result is\n* (257/256)*insize + 1.\n*\n*-------------------------------------------------------------------------\n* Copyright (c) 2003-2006 Marcus Geelnard\n*\n* This software is provided 'as-is', without any express or implied\n* warranty. In no event will the authors be held liable for any damages\n* arising from the use of this software.\n*\n* Permission is granted to anyone to use this software for any purpose,\n* including commercial applications, and to alter it and redistribute it\n* freely, subject to the following restrictions:\n*\n* 1. The origin of this software must not be misrepresented; you must not\n*    claim that you wrote the original software. If you use this software\n*    in a product, an acknowledgment in the product documentation would\n*    be appreciated but is not required.\n*\n* 2. Altered source versions must be plainly marked as such, and must not\n*    be misrepresented as being the original software.\n*\n* 3. This notice may not be removed or altered from any source\n*    distribution.\n*\n* Marcus Geelnard\n* marcus.geelnard at home.se\n*************************************************************************/\n\n\n/*************************************************************************\n*                           INTERNAL FUNCTIONS                           *\n*************************************************************************/\n\n\n/*************************************************************************\n* _LZ_ReadVarSize() - Read unsigned integer with variable number of\n* bytes depending on value.\n*************************************************************************/\n\nstatic int _LZ_ReadVarSize( unsigned int * x, const unsigned char * buf )\n{\n    unsigned int y, b, num_bytes;\n\n    /* Read complete value (stop when byte contains zero in 8:th bit) */\n    y = 0;\n    num_bytes = 0;\n    do\n    {\n        b = (unsigned int) (*buf ++);\n        y = (y << 7) | (b & 0x0000007f);\n        ++ num_bytes;\n    }\n    while( b & 0x00000080 );\n\n    /* Store value in x */\n    *x = y;\n\n    /* Return number of bytes read */\n    return num_bytes;\n}\n\n\n\n/*************************************************************************\n*                            PUBLIC FUNCTIONS                            *\n*************************************************************************/\n\n\n/*************************************************************************\n* LZ_Uncompress() - Uncompress a block of data using an LZ77 decoder.\n*  in      - Input (compressed) buffer.\n*  out     - Output (uncompressed) buffer. This buffer must be large\n*            enough to hold the uncompressed data.\n*  insize  - Number of input bytes.\n*************************************************************************/\n\nvoid LZ_Uncompress( const unsigned char *in, unsigned char *out,\n    unsigned int insize )\n{\n    unsigned char marker, symbol;\n    unsigned int  i, inpos, outpos, length, offset;\n\n    /* Do we have anything to uncompress? */\n    if( insize < 1 )\n    {\n        return;\n    }\n\n    /* Get marker symbol from input stream */\n    marker = in[ 0 ];\n    inpos = 1;\n\n    /* Main decompression loop */\n    outpos = 0;\n    do\n    {\n        symbol = in[ inpos ++ ];\n        if( symbol == marker )\n        {\n            /* We had a marker byte */\n            if( in[ inpos ] == 0 )\n            {\n                /* It was a single occurrence of the marker byte */\n                out[ outpos ++ ] = marker;\n                ++ inpos;\n            }\n            else\n            {\n                /* Extract true length and offset */\n                inpos += _LZ_ReadVarSize( &length, &in[ inpos ] );\n                inpos += _LZ_ReadVarSize( &offset, &in[ inpos ] );\n\n                /* Copy corresponding data from history window */\n                for( i = 0; i < length; ++ i )\n                {\n                    out[ outpos ] = out[ outpos - offset ];\n                    ++ outpos;\n                }\n            }\n        }\n        else\n        {\n            /* No marker, plain copy */\n            out[ outpos ++ ] = symbol;\n        }\n    }\n    while( inpos < insize );\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/elfload/elfload.c",
    "content": "/*\n * Copyright © 2018, M4xw\n * Copyright © 2014, Owen Shepherd\n *\n * Permission to use, copy, modify, and/or distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\n * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\n * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n * PERFORMANCE OF THIS SOFTWARE.\n */\n \n#include <string.h>\n\n#include \"libs/elfload/elfload.h\"\n\nel_status el_pread(el_ctx *ctx, void *def, size_t nb, size_t offset)\n{\n\treturn ctx->pread(ctx, def, nb, offset) ? EL_OK : EL_EIO;\n}\n\n#define EL_PHOFF(ctx, num) (((ctx)->ehdr.e_phoff + (num) *(ctx)->ehdr.e_phentsize))\nel_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, uint32_t type, unsigned *i)\n{\n\tel_status rv = EL_OK;\n\tfor (; *i < ctx->ehdr.e_phnum; (*i)++)\n\t{\n\t\tif ((rv = el_pread(ctx, phdr, sizeof *phdr, EL_PHOFF(ctx, *i))))\n\t\t\treturn rv;\n\n\t\tif (phdr->p_type == type)\n\t\t{\n\t\t\treturn rv;\n\t\t}\n\t}\n\n\t*i = -1;\n\treturn rv;\n}\n\n#define EL_SHOFF(ctx, num) (((ctx)->ehdr.e_shoff + (num) *(ctx)->ehdr.e_shentsize))\nel_status el_findshdr(el_ctx *ctx, Elf_Shdr *shdr, uint32_t type, unsigned *i)\n{\n\tel_status rv = EL_OK;\n\n\tfor (; *i < ctx->ehdr.e_shnum; (*i)++)\n\t{\n\t\tif ((rv = el_pread(ctx, shdr, sizeof *shdr, EL_SHOFF(ctx, *i))))\n\n\t\t\treturn rv;\n\n\t\tif (shdr->sh_type == type)\n\t\t{\n\t\t\treturn rv;\n\t\t}\n\t}\n\n\t*i = -1;\n\n\treturn rv;\n}\n\nel_status el_init(el_ctx *ctx)\n{\n\tel_status rv = EL_OK;\n\tif ((rv = el_pread(ctx, &ctx->ehdr, sizeof ctx->ehdr, 0)))\n\t\treturn rv;\n\n\t/* validate header */\n\n\tif (!IS_ELF(ctx->ehdr))\n\t\treturn EL_NOTELF;\n\n\tif (ctx->ehdr.e_ident[EI_CLASS] != ELFCLASS)\n\t\treturn EL_WRONGBITS;\n\n\tif (ctx->ehdr.e_ident[EI_DATA] != ELFDATATHIS)\n\t\treturn EL_WRONGENDIAN;\n\n\tif (ctx->ehdr.e_ident[EI_VERSION] != EV_CURRENT)\n\t\treturn EL_NOTELF;\n\n\tif (ctx->ehdr.e_type != ET_EXEC && ctx->ehdr.e_type != ET_DYN)\n\t\treturn EL_NOTEXEC;\n\n\tif (ctx->ehdr.e_machine != EM_THIS)\n\t\treturn EL_WRONGARCH;\n\n\tif (ctx->ehdr.e_version != EV_CURRENT)\n\t\treturn EL_NOTELF;\n\n\t/* load phdrs */\n\tElf_Phdr ph;\n\n\t/* iterate through, calculate extents */\n\tctx->base_load_paddr = ctx->base_load_vaddr = 0;\n\tctx->align = 1;\n\tctx->memsz = 0;\n\n\tunsigned i = 0;\n\tfor (;;)\n\t{\n\t\tif ((rv = el_findphdr(ctx, &ph, PT_LOAD, &i)))\n\t\t\treturn rv;\n\n\t\tif (i == (unsigned)-1)\n\t\t\tbreak;\n\n\t\tElf_Addr phend = ph.p_vaddr + ph.p_memsz;\n\t\tif (phend > ctx->memsz)\n\t\t\tctx->memsz = phend;\n\n\t\tif (ph.p_align > ctx->align)\n\t\t\tctx->align = ph.p_align;\n\n\t\ti++;\n\t}\n\n\t// Program Header\n\tif (ctx->ehdr.e_type == ET_DYN)\n\t{\n\t\ti = 0;\n\n\t\tif ((rv = el_findphdr(ctx, &ph, PT_DYNAMIC, &i)))\n\t\t\treturn rv;\n\n\t\tif (i == (unsigned)-1)\n\t\t\treturn EL_NODYN;\n\n\t\tctx->dynoff = ph.p_offset;\n\t\tctx->dynsize = ph.p_filesz;\n\t}\n\telse\n\t{\n\t\tctx->dynoff = 0;\n\t\tctx->dynsize = 0;\n\t}\n\n\t// Section String Table\n\tif (ctx->ehdr.e_type == ET_DYN)\n\t{\n\t\ti = ctx->ehdr.e_shstrndx - 1;\n\n\t\tif ((rv = el_findshdr(ctx, &ctx->shstr, SHT_STRTAB, &i)))\n\t\t\treturn rv;\n\n\t\t// Reset\n\t\ti = 0;\n\n\t\tif ((rv = el_findshdr(ctx, &ctx->symtab, SHT_SYMTAB, &i)))\n\t\t\treturn rv;\n\n\t\tif (i == (unsigned)-1)\n\t\t\treturn EL_NODYN;\n\t}\n\n\treturn rv;\n}\n\n/*\ntypedef void* (*el_alloc_cb)(\n\tel_ctx *ctx,\n\tElf_Addr phys,\n\tElf_Addr virt,\n\tElf_Addr size);\n*/\n\nel_status el_load(el_ctx *ctx, el_alloc_cb alloc)\n{\n\tel_status rv = EL_OK;\n\n\t/* address deltas */\n\tElf_Addr pdelta = ctx->base_load_paddr;\n\tElf_Addr vdelta = ctx->base_load_vaddr;\n\n\t/* iterate paddrs */\n\tElf_Phdr ph;\n\tunsigned i = 0;\n\tfor (;;)\n\t{\n\t\tif ((rv = el_findphdr(ctx, &ph, PT_LOAD, &i)))\n\t\t\treturn rv;\n\n\t\tif (i == (unsigned)-1)\n\t\t\tbreak;\n\n\t\tElf_Addr pload = ph.p_paddr + pdelta;\n\t\tElf_Addr vload = ph.p_vaddr + vdelta;\n\n\t\t/* allocate mem */\n\t\tchar *dest = alloc(ctx, pload, vload, ph.p_memsz);\n\t\tif (!dest)\n\t\t\treturn EL_ENOMEM;\n\n\t\tEL_DEBUG(\"Loading seg fileoff %x, vaddr %x to %p\\n\",\n\t\t\t\tph.p_offset, ph.p_vaddr, dest);\n\n\t\t/* read loaded portion */\n\t\tif ((rv = el_pread(ctx, dest, ph.p_filesz, ph.p_offset)))\n\t\t\treturn rv;\n\n\t\t/* zero mem-only portion */\n\t\tmemset(dest + ph.p_filesz, 0, ph.p_memsz - ph.p_filesz);\n\n\t\ti++;\n\t}\n\n\treturn rv;\n}\n\nel_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, uint32_t tag)\n{\n\tel_status rv = EL_OK;\n\tsize_t ndyn = ctx->dynsize / sizeof(Elf_Dyn);\n\n\tfor (unsigned i = 0; i < ndyn; i++)\n\t{\n\t\tif ((rv = el_pread(ctx, dyn, sizeof *dyn, ctx->dynoff + i * sizeof *dyn)))\n\t\t\treturn rv;\n\n\t\tif (dyn->d_tag == tag)\n\t\t\treturn EL_OK;\n\t}\n\n\tdyn->d_tag = DT_NULL;\n\treturn EL_OK;\n}\n\nel_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, uint32_t type)\n{\n\tel_status rv = EL_OK;\n\n\tElf_Dyn rel, relsz, relent;\n\n\tif ((rv = el_finddyn(ctx, &rel, type)))\n\t\treturn rv;\n\n\tif ((rv = el_finddyn(ctx, &relsz, type + 1)))\n\t\treturn rv;\n\n\tif ((rv = el_finddyn(ctx, &relent, type + 2)))\n\t\treturn rv;\n\n\tif (rel.d_tag == DT_NULL || relsz.d_tag == DT_NULL || relent.d_tag == DT_NULL)\n\t{\n\t\tri->entrysize = 0;\n\t\tri->tablesize = 0;\n\t\tri->tableoff = 0;\n\t}\n\telse\n\t{\n\t\tri->tableoff = rel.d_un.d_ptr;\n\t\tri->tablesize = relsz.d_un.d_val;\n\t\tri->entrysize = relent.d_un.d_val;\n\t}\n\n\treturn rv;\n}\n\nextern el_status el_applyrel(el_ctx *ctx, Elf_Rel *rel);\nextern el_status el_applyrela(el_ctx *ctx, Elf_RelA *rela);\n\nel_status el_relocate(el_ctx *ctx)\n{\n\tel_status rv = EL_OK;\n\n\t// not dynamic\n\tif (ctx->ehdr.e_type != ET_DYN)\n\t\treturn EL_OK;\n\n\tchar *base = (char *)ctx->base_load_paddr;\n\n\tel_relocinfo ri;\n#ifdef EL_ARCH_USES_REL\n\tif ((rv = el_findrelocs(ctx, &ri, DT_REL)))\n\t\treturn rv;\n\n\tif (ri.entrysize != sizeof(Elf_Rel) && ri.tablesize)\n\t{\n\t\tEL_DEBUG(\"Relocation size %u doesn't match expected %u\\n\",\n\t\t\t\tri.entrysize, sizeof(Elf_Rel));\n\t\treturn EL_BADREL;\n\t}\n\n\tsize_t relcnt = ri.tablesize / sizeof(Elf_Rel);\n\tElf_Rel *reltab = (Elf_Rel *)(base + ri.tableoff);\n\tfor (size_t i = 0; i < relcnt; i++)\n\t{\n\t\tif ((rv = el_applyrel(ctx, &reltab[i])))\n\t\t\treturn rv;\n\t}\n#endif\n\n#ifdef EL_ARCH_USES_RELA\n\tif ((rv = el_findrelocs(ctx, &ri, DT_RELA)))\n\t\treturn rv;\n\n\tif (ri.entrysize != sizeof(Elf_RelA) && ri.tablesize)\n\t{\n\t\tEL_DEBUG(\"Relocation size %u doesn't match expected %u\\n\",\n\t\t\t\tri.entrysize, sizeof(Elf_RelA));\n\t\treturn EL_BADREL;\n\t}\n\n\tsize_t relacnt = ri.tablesize / sizeof(Elf_RelA);\n\tElf_RelA *relatab = (Elf_RelA *)(base + ri.tableoff);\n\tfor (size_t i = 0; i < relacnt; i++)\n\t{\n\t\tif ((rv = el_applyrela(ctx, &relatab[i])))\n\t\t\treturn rv;\n\t}\n#endif\n\n#if !defined(EL_ARCH_USES_REL) && !defined(EL_ARCH_USES_RELA)\n#error No relocation type defined!\n#endif\n\n\treturn rv;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/elfload/elfreloc_aarch64.c",
    "content": "\n/*\n * Copyright © 2014, Owen Shepherd\n *\n * Permission to use, copy, modify, and/or distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\n * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\n * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n * PERFORMANCE OF THIS SOFTWARE.\n */\n\n#include \"libs/elfload/elfload.h\"\n\n#if defined(__aarch64__)\n\n#define R_AARCH64_NONE 0\n#define R_AARCH64_RELATIVE 1027\n\nel_status el_applyrela(el_ctx *ctx, Elf_RelA *rel)\n{\n\tuintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr);\n\tuint32_t type = ELF_R_TYPE(rel->r_info);\n\tuint32_t sym = ELF_R_SYM(rel->r_info);\n\n\tswitch (type)\n\t{\n\tcase R_AARCH64_NONE:\n\t\tEL_DEBUG(\"R_AARCH64_NONE\\n\");\n\t\tbreak;\n\tcase R_AARCH64_RELATIVE:\n\t\tif (sym)\n\t\t{\n\t\t\tEL_DEBUG(\"R_AARCH64_RELATIVE with symbol ref!\\n\");\n\t\t\treturn EL_BADREL;\n\t\t}\n\n\t\tEL_DEBUG(\"Applying R_AARCH64_RELATIVE reloc @%p\\n\", p);\n\t\t*p = rel->r_addend + ctx->base_load_vaddr;\n\t\tbreak;\n\n\tdefault:\n\t\tEL_DEBUG(\"Bad relocation %u\\n\", type);\n\t\treturn EL_BADREL;\n\t}\n\n\treturn EL_OK;\n}\n\nel_status el_applyrel(el_ctx *ctx, Elf_Rel *rel)\n{\n\tuintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr);\n\tuint32_t type = ELF_R_TYPE(rel->r_info);\n\tuint32_t sym = ELF_R_SYM(rel->r_info);\n\n\tswitch (type)\n\t{\n\tcase R_AARCH64_NONE:\n\t\tEL_DEBUG(\"R_AARCH64_NONE\\n\");\n\t\tbreak;\n\tcase R_AARCH64_RELATIVE:\n\t\tif (sym)\n\t\t{\n\t\t\tEL_DEBUG(\"R_AARCH64_RELATIVE with symbol ref!\\n\");\n\t\t\treturn EL_BADREL;\n\t\t}\n\n\t\tEL_DEBUG(\"Applying R_AARCH64_RELATIVE reloc @%p\\n\", p);\n\t\t*p += ctx->base_load_vaddr;\n\t\tbreak;\n\n\tdefault:\n\t\tEL_DEBUG(\"Bad relocation %u\\n\", type);\n\t\treturn EL_BADREL;\n\t}\n\n\treturn EL_OK;\n}\n\n#endif"
  },
  {
    "path": "argon-nx-gui/src/libs/elfload/elfreloc_arm.c",
    "content": "\n/*\n * ----------------------------------------------------------------------------\n * \"THE BEER-WARE LICENSE\" (Revision 42):\n * <m4x@m4xw.net> wrote this file. As long as you retain this notice you can do\n * whatever you want with this stuff. If we meet some day, and you think this\n * stuff is worth it, you can buy me a beer in return.                     M4xw\n * ----------------------------------------------------------------------------\n */\n\n#include \"libs/elfload/elfload.h\"\n\n#if defined(__arm__)\n\n// Taken from http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044f/IHI0044F_aaelf.pdf\n#define R_ARM_NONE 0\n#define R_ARM_ABS32 2\n#define R_ARM_JUMP_SLOT 22\n#define R_ARM_GLOB_DAT 21\n#define R_ARM_RELATIVE 23\n\nel_status el_applyrel(el_ctx *ctx, Elf_Rel *rel)\n{\n\tuint32_t sym = ELF_R_SYM(rel->r_info);                              // Symbol offset\n\tuint32_t type = ELF_R_TYPE(rel->r_info);                            // Relocation Type\n\tuintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr); // Target Addr\n\n#if 0 // For later symbol usage\n\tElf32_Sym *elfSym;\n\tconst char *symbolName;\n\n\t// We resolve relocs from the originating elf-image\n\telfSym = (Elf32_Sym *)(ctx->symtab.sh_offset + (char *)buffteg) + sym;\n\tint strtab_offset = ctx->shstr.sh_offset;\n\tchar *strtab = (char *)buffteg + strtab_offset;\n\tsymbolName = strtab + elfSym->st_name;\n\t//EL_DEBUG(\"Str: %s sz: %x val: %x\\n\", symbolName, elfSym->st_size, elfSym->st_value);\n#endif\n\n\tswitch (type)\n\t{\n\tcase R_ARM_NONE:\n\t\tEL_DEBUG(\"R_ARM_NONE\\n\");\n\t\tbreak;\n\tcase R_ARM_JUMP_SLOT:\n\tcase R_ARM_ABS32:\n\tcase R_ARM_GLOB_DAT:\n\t\t// Stubbed for later purpose\n\t\t//*p += elfSym->st_value; // + vaddr from sec\n\t\t//*p |= 0; // 1 if Thumb && STT_FUNC, ignored for now\n\t\tbreak;\n\tcase R_ARM_RELATIVE: // Needed for PIE\n\t\tif (sym)\n\t\t{\n\t\t\treturn EL_BADREL;\n\t\t}\n\t\t*p += ctx->base_load_vaddr;\n\t\tbreak;\n\n\tdefault:\n\t\treturn EL_BADREL;\n\t}\n\n\treturn EL_OK;\n}\n\n#endif"
  },
  {
    "path": "argon-nx-gui/src/libs/fatfs/diskio.c",
    "content": "/*-----------------------------------------------------------------------*/\n/* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2016        */\n/*-----------------------------------------------------------------------*/\n/* If a working storage control module is available, it should be        */\n/* attached to the FatFs via a glue function rather than modifying it.   */\n/* This is an example of glue functions to attach various exsisting      */\n/* storage control modules to the FatFs module with a defined API.       */\n/*-----------------------------------------------------------------------*/\n\n#include <string.h>\n#include \"libs/fatfs/diskio.h\"\t\t/* FatFs lower layer API */\n#include \"storage/sdmmc.h\"\n\n#define SDMMC_UPPER_BUFFER 0xB8000000\n#define DRAM_START         0x80000000\n\nextern sdmmc_storage_t g_sd_storage;\n\n/*-----------------------------------------------------------------------*/\n/* Get Drive Status                                                      */\n/*-----------------------------------------------------------------------*/\nDSTATUS disk_status (\n\tBYTE pdrv\t\t/* Physical drive nmuber to identify the drive */\n)\n{\n\treturn 0;\n}\n\n/*-----------------------------------------------------------------------*/\n/* Inidialize a Drive                                                    */\n/*-----------------------------------------------------------------------*/\nDSTATUS disk_initialize (\n\tBYTE pdrv\t\t\t\t/* Physical drive nmuber to identify the drive */\n)\n{\n\treturn 0;\n}\n\n/*-----------------------------------------------------------------------*/\n/* Read Sector(s)                                                        */\n/*-----------------------------------------------------------------------*/\nDRESULT disk_read (\n\tBYTE pdrv,\t\t/* Physical drive nmuber to identify the drive */\n\tBYTE *buff,\t\t/* Data buffer to store read data */\n\tDWORD sector,\t/* Start sector in LBA */\n\tUINT count\t\t/* Number of sectors to read */\n)\n{\n\tif ((u32)buff >= DRAM_START)\n\t\treturn sdmmc_storage_read(&g_sd_storage, sector, count, buff) ? RES_OK : RES_ERROR;\n\tu8 *buf = (u8 *)SDMMC_UPPER_BUFFER;\n\tif (sdmmc_storage_read(&g_sd_storage, sector, count, buf))\n\t{\n\t\tmemcpy(buff, buf, 512 * count);\n\t\treturn RES_OK;\n\t}\n\treturn RES_ERROR;\n}\n\n/*-----------------------------------------------------------------------*/\n/* Write Sector(s)                                                       */\n/*-----------------------------------------------------------------------*/\nDRESULT disk_write (\n\tBYTE pdrv,\t\t\t/* Physical drive nmuber to identify the drive */\n\tconst BYTE *buff,\t/* Data to be written */\n\tDWORD sector,\t\t/* Start sector in LBA */\n\tUINT count\t\t\t/* Number of sectors to write */\n)\n{\n\tif ((u32)buff >= DRAM_START)\n\t\treturn sdmmc_storage_write(&g_sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;\n\tu8 *buf = (u8 *)SDMMC_UPPER_BUFFER; //TODO: define this somewhere.\n\tmemcpy(buf, buff, 512 * count);\n\tif (sdmmc_storage_write(&g_sd_storage, sector, count, buf))\n\t\treturn RES_OK;\n\treturn RES_ERROR;\n}\n\n/*-----------------------------------------------------------------------*/\n/* Miscellaneous Functions                                               */\n/*-----------------------------------------------------------------------*/\nDRESULT disk_ioctl (\n\tBYTE pdrv,\t\t/* Physical drive nmuber (0..) */\n\tBYTE cmd,\t\t/* Control code */\n\tvoid *buff\t\t/* Buffer to send/receive control data */\n)\n{\n\treturn RES_OK;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/fatfs/ff.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018-2019 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n/*----------------------------------------------------------------------------/\n/  FatFs - Generic FAT Filesystem Module  R0.13c (p3)                         /\n/-----------------------------------------------------------------------------/\n/\n/ Copyright (C) 2018, ChaN, all right reserved.\n/\n/ FatFs module is an open source software. Redistribution and use of FatFs in\n/ source and binary forms, with or without modification, are permitted provided\n/ that the following condition is met:\n/\n/ 1. Redistributions of source code must retain the above copyright notice,\n/    this condition and the following disclaimer.\n/\n/ This software is provided by the copyright holder and contributors \"AS IS\"\n/ and any warranties related to this software are DISCLAIMED.\n/ The copyright owner or contributors be NOT LIABLE for any damages caused\n/ by use of this software.\n/\n/----------------------------------------------------------------------------*/\n\n\n#include \"libs/fatfs/ff.h\"\t\t\t/* Declarations of FatFs API */\n#include \"libs/fatfs/diskio.h\"\t\t/* Declarations of device I/O functions */\n#include \"gfx/gfx.h\"\n\n#pragma GCC push_options\n#pragma GCC target (\"thumb\")\n\n#define EFSPRINTF(text, ...) print_error(); gfx_printf(\"%k\"text\"%k\\n\", 0xFFFFFF00, 0xFFFFFFFF);\n//#define EFSPRINTF(...)\n\n/*--------------------------------------------------------------------------\n\n   Module Private Definitions\n\n---------------------------------------------------------------------------*/\n\n#if FF_DEFINED != 86604\t/* Revision ID */\n#error Wrong include file (ff.h).\n#endif\n\n\n/* Limits and boundaries */\n#define MAX_DIR\t\t0x200000\t\t/* Max size of FAT directory */\n#define MAX_DIR_EX\t0x10000000\t\t/* Max size of exFAT directory */\n#define MAX_FAT12\t0xFF5\t\t\t/* Max FAT12 clusters (differs from specs, but right for real DOS/Windows behavior) */\n#define MAX_FAT16\t0xFFF5\t\t\t/* Max FAT16 clusters (differs from specs, but right for real DOS/Windows behavior) */\n#define MAX_FAT32\t0x0FFFFFF5\t\t/* Max FAT32 clusters (not specified, practical limit) */\n#define MAX_EXFAT\t0x7FFFFFFD\t\t/* Max exFAT clusters (differs from specs, implementation limit) */\n\n\n/* Character code support macros */\n#define IsUpper(c)\t\t((c) >= 'A' && (c) <= 'Z')\n#define IsLower(c)\t\t((c) >= 'a' && (c) <= 'z')\n#define IsDigit(c)\t\t((c) >= '0' && (c) <= '9')\n#define IsSurrogate(c)\t((c) >= 0xD800 && (c) <= 0xDFFF)\n#define IsSurrogateH(c)\t((c) >= 0xD800 && (c) <= 0xDBFF)\n#define IsSurrogateL(c)\t((c) >= 0xDC00 && (c) <= 0xDFFF)\n\n\n/* Additional file access control and file status flags for internal use */\n#define FA_SEEKEND\t0x20\t/* Seek to end of the file on file open */\n#define FA_MODIFIED\t0x40\t/* File has been modified */\n#define FA_DIRTY\t0x80\t/* FIL.buf[] needs to be written-back */\n\n\n/* Additional file attribute bits for internal use */\n#define AM_VOL\t\t0x08\t/* Volume label */\n#define AM_LFN\t\t0x0F\t/* LFN entry */\n#define AM_MASK\t\t0x3F\t/* Mask of defined bits */\n\n\n/* Name status flags in fn[11] */\n#define NSFLAG\t\t11\t\t/* Index of the name status byte */\n#define NS_LOSS\t\t0x01\t/* Out of 8.3 format */\n#define NS_LFN\t\t0x02\t/* Force to create LFN entry */\n#define NS_LAST\t\t0x04\t/* Last segment */\n#define NS_BODY\t\t0x08\t/* Lower case flag (body) */\n#define NS_EXT\t\t0x10\t/* Lower case flag (ext) */\n#define NS_DOT\t\t0x20\t/* Dot entry */\n#define NS_NOLFN\t0x40\t/* Do not find LFN */\n#define NS_NONAME\t0x80\t/* Not followed */\n\n\n/* exFAT directory entry types */\n#define\tET_BITMAP\t0x81\t/* Allocation bitmap */\n#define\tET_UPCASE\t0x82\t/* Up-case table */\n#define\tET_VLABEL\t0x83\t/* Volume label */\n#define\tET_FILEDIR\t0x85\t/* File and directory */\n#define\tET_STREAM\t0xC0\t/* Stream extension */\n#define\tET_FILENAME\t0xC1\t/* Name extension */\n\n\n/* FatFs refers the FAT structure as simple byte array instead of structure member\n/ because the C structure is not binary compatible between different platforms */\n\n#define BS_JmpBoot\t\t\t0\t\t/* x86 jump instruction (3-byte) */\n#define BS_OEMName\t\t\t3\t\t/* OEM name (8-byte) */\n#define BPB_BytsPerSec\t\t11\t\t/* Sector size [byte] (WORD) */\n#define BPB_SecPerClus\t\t13\t\t/* Cluster size [sector] (BYTE) */\n#define BPB_RsvdSecCnt\t\t14\t\t/* Size of reserved area [sector] (WORD) */\n#define BPB_NumFATs\t\t\t16\t\t/* Number of FATs (BYTE) */\n#define BPB_RootEntCnt\t\t17\t\t/* Size of root directory area for FAT [entry] (WORD) */\n#define BPB_TotSec16\t\t19\t\t/* Volume size (16-bit) [sector] (WORD) */\n#define BPB_Media\t\t\t21\t\t/* Media descriptor byte (BYTE) */\n#define BPB_FATSz16\t\t\t22\t\t/* FAT size (16-bit) [sector] (WORD) */\n#define BPB_SecPerTrk\t\t24\t\t/* Number of sectors per track for int13h [sector] (WORD) */\n#define BPB_NumHeads\t\t26\t\t/* Number of heads for int13h (WORD) */\n#define BPB_HiddSec\t\t\t28\t\t/* Volume offset from top of the drive (DWORD) */\n#define BPB_TotSec32\t\t32\t\t/* Volume size (32-bit) [sector] (DWORD) */\n#define BS_DrvNum\t\t\t36\t\t/* Physical drive number for int13h (BYTE) */\n#define BS_NTres\t\t\t37\t\t/* WindowsNT error flag (BYTE) */\n#define BS_BootSig\t\t\t38\t\t/* Extended boot signature (BYTE) */\n#define BS_VolID\t\t\t39\t\t/* Volume serial number (DWORD) */\n#define BS_VolLab\t\t\t43\t\t/* Volume label string (8-byte) */\n#define BS_FilSysType\t\t54\t\t/* Filesystem type string (8-byte) */\n#define BS_BootCode\t\t\t62\t\t/* Boot code (448-byte) */\n#define BS_55AA\t\t\t\t510\t\t/* Signature word (WORD) */\n\n#define BPB_FATSz32\t\t\t36\t\t/* FAT32: FAT size [sector] (DWORD) */\n#define BPB_ExtFlags32\t\t40\t\t/* FAT32: Extended flags (WORD) */\n#define BPB_FSVer32\t\t\t42\t\t/* FAT32: Filesystem version (WORD) */\n#define BPB_RootClus32\t\t44\t\t/* FAT32: Root directory cluster (DWORD) */\n#define BPB_FSInfo32\t\t48\t\t/* FAT32: Offset of FSINFO sector (WORD) */\n#define BPB_BkBootSec32\t\t50\t\t/* FAT32: Offset of backup boot sector (WORD) */\n#define BS_DrvNum32\t\t\t64\t\t/* FAT32: Physical drive number for int13h (BYTE) */\n#define BS_NTres32\t\t\t65\t\t/* FAT32: Error flag (BYTE) */\n#define BS_BootSig32\t\t66\t\t/* FAT32: Extended boot signature (BYTE) */\n#define BS_VolID32\t\t\t67\t\t/* FAT32: Volume serial number (DWORD) */\n#define BS_VolLab32\t\t\t71\t\t/* FAT32: Volume label string (8-byte) */\n#define BS_FilSysType32\t\t82\t\t/* FAT32: Filesystem type string (8-byte) */\n#define BS_BootCode32\t\t90\t\t/* FAT32: Boot code (420-byte) */\n\n#define BPB_ZeroedEx\t\t11\t\t/* exFAT: MBZ field (53-byte) */\n#define BPB_VolOfsEx\t\t64\t\t/* exFAT: Volume offset from top of the drive [sector] (QWORD) */\n#define BPB_TotSecEx\t\t72\t\t/* exFAT: Volume size [sector] (QWORD) */\n#define BPB_FatOfsEx\t\t80\t\t/* exFAT: FAT offset from top of the volume [sector] (DWORD) */\n#define BPB_FatSzEx\t\t\t84\t\t/* exFAT: FAT size [sector] (DWORD) */\n#define BPB_DataOfsEx\t\t88\t\t/* exFAT: Data offset from top of the volume [sector] (DWORD) */\n#define BPB_NumClusEx\t\t92\t\t/* exFAT: Number of clusters (DWORD) */\n#define BPB_RootClusEx\t\t96\t\t/* exFAT: Root directory start cluster (DWORD) */\n#define BPB_VolIDEx\t\t\t100\t\t/* exFAT: Volume serial number (DWORD) */\n#define BPB_FSVerEx\t\t\t104\t\t/* exFAT: Filesystem version (WORD) */\n#define BPB_VolFlagEx\t\t106\t\t/* exFAT: Volume flags (WORD) */\n#define BPB_BytsPerSecEx\t108\t\t/* exFAT: Log2 of sector size in unit of byte (BYTE) */\n#define BPB_SecPerClusEx\t109\t\t/* exFAT: Log2 of cluster size in unit of sector (BYTE) */\n#define BPB_NumFATsEx\t\t110\t\t/* exFAT: Number of FATs (BYTE) */\n#define BPB_DrvNumEx\t\t111\t\t/* exFAT: Physical drive number for int13h (BYTE) */\n#define BPB_PercInUseEx\t\t112\t\t/* exFAT: Percent in use (BYTE) */\n#define BPB_RsvdEx\t\t\t113\t\t/* exFAT: Reserved (7-byte) */\n#define BS_BootCodeEx\t\t120\t\t/* exFAT: Boot code (390-byte) */\n\n#define DIR_Name\t\t\t0\t\t/* Short file name (11-byte) */\n#define DIR_Attr\t\t\t11\t\t/* Attribute (BYTE) */\n#define DIR_NTres\t\t\t12\t\t/* Lower case flag (BYTE) */\n#define DIR_CrtTime10\t\t13\t\t/* Created time sub-second (BYTE) */\n#define DIR_CrtTime\t\t\t14\t\t/* Created time (DWORD) */\n#define DIR_LstAccDate\t\t18\t\t/* Last accessed date (WORD) */\n#define DIR_FstClusHI\t\t20\t\t/* Higher 16-bit of first cluster (WORD) */\n#define DIR_ModTime\t\t\t22\t\t/* Modified time (DWORD) */\n#define DIR_FstClusLO\t\t26\t\t/* Lower 16-bit of first cluster (WORD) */\n#define DIR_FileSize\t\t28\t\t/* File size (DWORD) */\n#define LDIR_Ord\t\t\t0\t\t/* LFN: LFN order and LLE flag (BYTE) */\n#define LDIR_Attr\t\t\t11\t\t/* LFN: LFN attribute (BYTE) */\n#define LDIR_Type\t\t\t12\t\t/* LFN: Entry type (BYTE) */\n#define LDIR_Chksum\t\t\t13\t\t/* LFN: Checksum of the SFN (BYTE) */\n#define LDIR_FstClusLO\t\t26\t\t/* LFN: MBZ field (WORD) */\n#define XDIR_Type\t\t\t0\t\t/* exFAT: Type of exFAT directory entry (BYTE) */\n#define XDIR_NumLabel\t\t1\t\t/* exFAT: Number of volume label characters (BYTE) */\n#define XDIR_Label\t\t\t2\t\t/* exFAT: Volume label (11-WORD) */\n#define XDIR_CaseSum\t\t4\t\t/* exFAT: Sum of case conversion table (DWORD) */\n#define XDIR_NumSec\t\t\t1\t\t/* exFAT: Number of secondary entries (BYTE) */\n#define XDIR_SetSum\t\t\t2\t\t/* exFAT: Sum of the set of directory entries (WORD) */\n#define XDIR_Attr\t\t\t4\t\t/* exFAT: File attribute (WORD) */\n#define XDIR_CrtTime\t\t8\t\t/* exFAT: Created time (DWORD) */\n#define XDIR_ModTime\t\t12\t\t/* exFAT: Modified time (DWORD) */\n#define XDIR_AccTime\t\t16\t\t/* exFAT: Last accessed time (DWORD) */\n#define XDIR_CrtTime10\t\t20\t\t/* exFAT: Created time subsecond (BYTE) */\n#define XDIR_ModTime10\t\t21\t\t/* exFAT: Modified time subsecond (BYTE) */\n#define XDIR_CrtTZ\t\t\t22\t\t/* exFAT: Created timezone (BYTE) */\n#define XDIR_ModTZ\t\t\t23\t\t/* exFAT: Modified timezone (BYTE) */\n#define XDIR_AccTZ\t\t\t24\t\t/* exFAT: Last accessed timezone (BYTE) */\n#define XDIR_GenFlags\t\t33\t\t/* exFAT: General secondary flags (BYTE) */\n#define XDIR_NumName\t\t35\t\t/* exFAT: Number of file name characters (BYTE) */\n#define XDIR_NameHash\t\t36\t\t/* exFAT: Hash of file name (WORD) */\n#define XDIR_ValidFileSize\t40\t\t/* exFAT: Valid file size (QWORD) */\n#define XDIR_FstClus\t\t52\t\t/* exFAT: First cluster of the file data (DWORD) */\n#define XDIR_FileSize\t\t56\t\t/* exFAT: File/Directory size (QWORD) */\n\n#define SZDIRE\t\t\t\t32\t\t/* Size of a directory entry */\n#define DDEM\t\t\t\t0xE5\t/* Deleted directory entry mark set to DIR_Name[0] */\n#define RDDEM\t\t\t\t0x05\t/* Replacement of the character collides with DDEM */\n#define LLEF\t\t\t\t0x40\t/* Last long entry flag in LDIR_Ord */\n\n#define FSI_LeadSig\t\t\t0\t\t/* FAT32 FSI: Leading signature (DWORD) */\n#define FSI_StrucSig\t\t484\t\t/* FAT32 FSI: Structure signature (DWORD) */\n#define FSI_Free_Count\t\t488\t\t/* FAT32 FSI: Number of free clusters (DWORD) */\n#define FSI_Nxt_Free\t\t492\t\t/* FAT32 FSI: Last allocated cluster (DWORD) */\n\n#define MBR_Table\t\t\t446\t\t/* MBR: Offset of partition table in the MBR */\n#define SZ_PTE\t\t\t\t16\t\t/* MBR: Size of a partition table entry */\n#define PTE_Boot\t\t\t0\t\t/* MBR PTE: Boot indicator */\n#define PTE_StHead\t\t\t1\t\t/* MBR PTE: Start head */\n#define PTE_StSec\t\t\t2\t\t/* MBR PTE: Start sector */\n#define PTE_StCyl\t\t\t3\t\t/* MBR PTE: Start cylinder */\n#define PTE_System\t\t\t4\t\t/* MBR PTE: System ID */\n#define PTE_EdHead\t\t\t5\t\t/* MBR PTE: End head */\n#define PTE_EdSec\t\t\t6\t\t/* MBR PTE: End sector */\n#define PTE_EdCyl\t\t\t7\t\t/* MBR PTE: End cylinder */\n#define PTE_StLba\t\t\t8\t\t/* MBR PTE: Start in LBA */\n#define PTE_SizLba\t\t\t12\t\t/* MBR PTE: Size in LBA */\n\n\n/* Post process on fatal error in the file operations */\n#define ABORT(fs, res)\t\t{ fp->err = (BYTE)(res); LEAVE_FF(fs, res); }\n\n\n/* Re-entrancy related */\n#if FF_FS_REENTRANT\n#if FF_USE_LFN == 1\n#error Static LFN work area cannot be used at thread-safe configuration\n#endif\n#define LEAVE_FF(fs, res)\t{ unlock_fs(fs, res); return res; }\n#else\n#define LEAVE_FF(fs, res)\treturn res\n#endif\n\n\n/* Definitions of volume - physical location conversion */\n#if FF_MULTI_PARTITION\n#define LD2PD(vol) VolToPart[vol].pd\t/* Get physical drive number */\n#define LD2PT(vol) VolToPart[vol].pt\t/* Get partition index */\n#else\n#define LD2PD(vol) (BYTE)(vol)\t/* Each logical drive is bound to the same physical drive number */\n#define LD2PT(vol) 0\t\t\t/* Find first valid partition or in SFD */\n#endif\n\n\n/* Definitions of sector size */\n#if (FF_MAX_SS < FF_MIN_SS) || (FF_MAX_SS != 512 && FF_MAX_SS != 1024 && FF_MAX_SS != 2048 && FF_MAX_SS != 4096) || (FF_MIN_SS != 512 && FF_MIN_SS != 1024 && FF_MIN_SS != 2048 && FF_MIN_SS != 4096)\n#error Wrong sector size configuration\n#endif\n#if FF_MAX_SS == FF_MIN_SS\n#define SS(fs)\t((UINT)FF_MAX_SS)\t/* Fixed sector size */\n#else\n#define SS(fs)\t((fs)->ssize)\t/* Variable sector size */\n#endif\n\n\n/* Timestamp */\n#if FF_FS_NORTC == 1\n#if FF_NORTC_YEAR < 1980 || FF_NORTC_YEAR > 2107 || FF_NORTC_MON < 1 || FF_NORTC_MON > 12 || FF_NORTC_MDAY < 1 || FF_NORTC_MDAY > 31\n#error Invalid FF_FS_NORTC settings\n#endif\n#define GET_FATTIME()\t((DWORD)(FF_NORTC_YEAR - 1980) << 25 | (DWORD)FF_NORTC_MON << 21 | (DWORD)FF_NORTC_MDAY << 16)\n#else\n#define GET_FATTIME()\tget_fattime()\n#endif\n\n\n/* File lock controls */\n#if FF_FS_LOCK != 0\n#if FF_FS_READONLY\n#error FF_FS_LOCK must be 0 at read-only configuration\n#endif\ntypedef struct {\n\tFATFS *fs;\t\t/* Object ID 1, volume (NULL:blank entry) */\n\tDWORD clu;\t\t/* Object ID 2, containing directory (0:root) */\n\tDWORD ofs;\t\t/* Object ID 3, offset in the directory */\n\tWORD ctr;\t\t/* Object open counter, 0:none, 0x01..0xFF:read mode open count, 0x100:write mode */\n} FILESEM;\n#endif\n\n\n/* SBCS up-case tables (\\x80-\\xFF) */\n#define TBL_CT437  {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT720  {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT737  {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \\\n\t\t\t\t\t0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xEF,0xF5,0xF0,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT771  {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDC,0xDE,0xDE, \\\n\t\t\t\t\t0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFE,0xFF}\n#define TBL_CT775  {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT850  {0x43,0x55,0x45,0x41,0x41,0x41,0x41,0x43,0x45,0x45,0x45,0x49,0x49,0x49,0x41,0x41, \\\n\t\t\t\t\t0x45,0x92,0x92,0x4F,0x4F,0x4F,0x55,0x55,0x59,0x4F,0x55,0x4F,0x9C,0x4F,0x9E,0x9F, \\\n\t\t\t\t\t0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0x41,0x41,0x41,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0x41,0x41,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD1,0xD1,0x45,0x45,0x45,0x49,0x49,0x49,0x49,0xD9,0xDA,0xDB,0xDC,0xDD,0x49,0xDF, \\\n\t\t\t\t\t0x4F,0xE1,0x4F,0x4F,0x4F,0x4F,0xE6,0xE8,0xE8,0x55,0x55,0x55,0x59,0x59,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT852  {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0xAC, \\\n\t\t\t\t\t0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}\n#define TBL_CT855  {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F, \\\n\t\t\t\t\t0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \\\n\t\t\t\t\t0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \\\n\t\t\t\t\t0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT857  {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x49,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \\\n\t\t\t\t\t0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0x49,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT860  {0x80,0x9A,0x90,0x8F,0x8E,0x91,0x86,0x80,0x89,0x89,0x92,0x8B,0x8C,0x98,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x91,0x92,0x8C,0x99,0xA9,0x96,0x9D,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0x86,0x8B,0x9F,0x96,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT861  {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x8B,0x8B,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x92,0x92,0x4F,0x99,0x8D,0x55,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0xA4,0xA5,0xA6,0xA7,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT862  {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT863  {0x43,0x55,0x45,0x41,0x41,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x41,0x8F, \\\n\t\t\t\t\t0x45,0x45,0x45,0x4F,0x45,0x49,0x55,0x55,0x98,0x4F,0x55,0x9B,0x9C,0x55,0x55,0x9F, \\\n\t\t\t\t\t0xA0,0xA1,0x4F,0x55,0xA4,0xA5,0xA6,0xA7,0x49,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT864  {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT865  {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT866  {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\\n\t\t\t\t\t0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\\n\t\t\t\t\t0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\n#define TBL_CT869  {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \\\n\t\t\t\t\t0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x86,0x9C,0x8D,0x8F,0x90, \\\n\t\t\t\t\t0x91,0x90,0x92,0x95,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \\\n\t\t\t\t\t0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\\n\t\t\t\t\t0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \\\n\t\t\t\t\t0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xA4,0xA5,0xA6,0xD9,0xDA,0xDB,0xDC,0xA7,0xA8,0xDF, \\\n\t\t\t\t\t0xA9,0xAA,0xAC,0xAD,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xCF,0xCF,0xD0,0xEF, \\\n\t\t\t\t\t0xF0,0xF1,0xD1,0xD2,0xD3,0xF5,0xD4,0xF7,0xF8,0xF9,0xD5,0x96,0x95,0x98,0xFE,0xFF}\n\n\n/* DBCS code range |----- 1st byte -----|  |----------- 2nd byte -----------| */\n#define TBL_DC932 {0x81, 0x9F, 0xE0, 0xFC, 0x40, 0x7E, 0x80, 0xFC, 0x00, 0x00}\n#define TBL_DC936 {0x81, 0xFE, 0x00, 0x00, 0x40, 0x7E, 0x80, 0xFE, 0x00, 0x00}\n#define TBL_DC949 {0x81, 0xFE, 0x00, 0x00, 0x41, 0x5A, 0x61, 0x7A, 0x81, 0xFE}\n#define TBL_DC950 {0x81, 0xFE, 0x00, 0x00, 0x40, 0x7E, 0xA1, 0xFE, 0x00, 0x00}\n\n\n/* Macros for table definitions */\n#define MERGE_2STR(a, b) a ## b\n#define MKCVTBL(hd, cp) MERGE_2STR(hd, cp)\n\n\n\n\n/*--------------------------------------------------------------------------\n\n   Module Private Work Area\n\n---------------------------------------------------------------------------*/\n/* Remark: Variables defined here without initial value shall be guaranteed\n/  zero/null at start-up. If not, the linker option or start-up routine is\n/  not compliance with C standard. */\n\n/*--------------------------------*/\n/* File/Volume controls           */\n/*--------------------------------*/\n\n#if FF_VOLUMES < 1 || FF_VOLUMES > 10\n#error Wrong FF_VOLUMES setting\n#endif\nstatic FATFS* FatFs[FF_VOLUMES];\t/* Pointer to the filesystem objects (logical drives) */\nstatic WORD Fsid;\t\t\t\t\t/* Filesystem mount ID */\n\n#if FF_FS_RPATH != 0\nstatic BYTE CurrVol;\t\t\t\t/* Current drive */\n#endif\n\n#if FF_FS_LOCK != 0\nstatic FILESEM Files[FF_FS_LOCK];\t/* Open object lock semaphores */\n#endif\n\n#if FF_STR_VOLUME_ID\n#ifdef FF_VOLUME_STRS\nstatic const char* const VolumeStr[FF_VOLUMES] = {FF_VOLUME_STRS};\t/* Pre-defined volume ID */\n#endif\n#endif\n\n\n/*--------------------------------*/\n/* LFN/Directory working buffer   */\n/*--------------------------------*/\n\n#if FF_USE_LFN == 0\t\t/* Non-LFN configuration */\n#if FF_FS_EXFAT\n#error LFN must be enabled when enable exFAT\n#endif\n#define DEF_NAMBUF\n#define INIT_NAMBUF(fs)\n#define FREE_NAMBUF()\n#define LEAVE_MKFS(res)\treturn res\n\n#else\t\t\t\t\t/* LFN configurations */\n#if FF_MAX_LFN < 12 || FF_MAX_LFN > 255\n#error Wrong setting of FF_MAX_LFN\n#endif\n#if FF_LFN_BUF < FF_SFN_BUF || FF_SFN_BUF < 12\n#error Wrong setting of FF_LFN_BUF or FF_SFN_BUF\n#endif\n#if FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3\n#error Wrong setting of FF_LFN_UNICODE\n#endif\nstatic const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30};\t/* FAT: Offset of LFN characters in the directory entry */\n#define MAXDIRB(nc)\t((nc + 44U) / 15 * SZDIRE)\t/* exFAT: Size of directory entry block scratchpad buffer needed for the name length */\n\n#if FF_USE_LFN == 1\t\t/* LFN enabled with static working buffer */\n#if FF_FS_EXFAT\nstatic BYTE\tDirBuf[MAXDIRB(FF_MAX_LFN)];\t/* Directory entry block scratchpad buffer */\n#endif\nstatic WCHAR LfnBuf[FF_MAX_LFN + 1];\t\t/* LFN working buffer */\n#define DEF_NAMBUF\n#define INIT_NAMBUF(fs)\n#define FREE_NAMBUF()\n#define LEAVE_MKFS(res)\treturn res\n\n#elif FF_USE_LFN == 2 \t/* LFN enabled with dynamic working buffer on the stack */\n#if FF_FS_EXFAT\n#define DEF_NAMBUF\t\tWCHAR lbuf[FF_MAX_LFN+1]; BYTE dbuf[MAXDIRB(FF_MAX_LFN)];\t/* LFN working buffer and directory entry block scratchpad buffer */\n#define INIT_NAMBUF(fs)\t{ (fs)->lfnbuf = lbuf; (fs)->dirbuf = dbuf; }\n#define FREE_NAMBUF()\n#else\n#define DEF_NAMBUF\t\tWCHAR lbuf[FF_MAX_LFN+1];\t/* LFN working buffer */\n#define INIT_NAMBUF(fs)\t{ (fs)->lfnbuf = lbuf; }\n#define FREE_NAMBUF()\n#endif\n#define LEAVE_MKFS(res)\treturn res\n\n#elif FF_USE_LFN == 3 \t/* LFN enabled with dynamic working buffer on the heap */\n#if FF_FS_EXFAT\n#define DEF_NAMBUF\t\tWCHAR *lfn;\t/* Pointer to LFN working buffer and directory entry block scratchpad buffer */\n#define INIT_NAMBUF(fs)\t{ lfn = ff_memalloc((FF_MAX_LFN+1)*2 + MAXDIRB(FF_MAX_LFN)); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; (fs)->dirbuf = (BYTE*)(lfn+FF_MAX_LFN+1); }\n#define FREE_NAMBUF()\tff_memfree(lfn)\n#else\n#define DEF_NAMBUF\t\tWCHAR *lfn;\t/* Pointer to LFN working buffer */\n#define INIT_NAMBUF(fs)\t{ lfn = ff_memalloc((FF_MAX_LFN+1)*2); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; }\n#define FREE_NAMBUF()\tff_memfree(lfn)\n#endif\n#define LEAVE_MKFS(res)\t{ if (!work) ff_memfree(buf); return res; }\n#define MAX_MALLOC\t0x8000\t/* Must be >=FF_MAX_SS */\n\n#else\n#error Wrong setting of FF_USE_LFN\n\n#endif\t/* FF_USE_LFN == 1 */\n#endif\t/* FF_USE_LFN == 0 */\n\n\n\n/*--------------------------------*/\n/* Code conversion tables         */\n/*--------------------------------*/\n\n#if FF_CODE_PAGE == 0\t\t/* Run-time code page configuration */\n#define CODEPAGE CodePage\nstatic WORD CodePage;\t/* Current code page */\nstatic const BYTE *ExCvt, *DbcTbl;\t/* Pointer to current SBCS up-case table and DBCS code range table below */\n\nstatic const BYTE Ct437[] = TBL_CT437;\nstatic const BYTE Ct720[] = TBL_CT720;\nstatic const BYTE Ct737[] = TBL_CT737;\nstatic const BYTE Ct771[] = TBL_CT771;\nstatic const BYTE Ct775[] = TBL_CT775;\nstatic const BYTE Ct850[] = TBL_CT850;\nstatic const BYTE Ct852[] = TBL_CT852;\nstatic const BYTE Ct855[] = TBL_CT855;\nstatic const BYTE Ct857[] = TBL_CT857;\nstatic const BYTE Ct860[] = TBL_CT860;\nstatic const BYTE Ct861[] = TBL_CT861;\nstatic const BYTE Ct862[] = TBL_CT862;\nstatic const BYTE Ct863[] = TBL_CT863;\nstatic const BYTE Ct864[] = TBL_CT864;\nstatic const BYTE Ct865[] = TBL_CT865;\nstatic const BYTE Ct866[] = TBL_CT866;\nstatic const BYTE Ct869[] = TBL_CT869;\nstatic const BYTE Dc932[] = TBL_DC932;\nstatic const BYTE Dc936[] = TBL_DC936;\nstatic const BYTE Dc949[] = TBL_DC949;\nstatic const BYTE Dc950[] = TBL_DC950;\n\n#elif FF_CODE_PAGE < 900\t/* Static code page configuration (SBCS) */\n#define CODEPAGE FF_CODE_PAGE\nstatic const BYTE ExCvt[] = MKCVTBL(TBL_CT, FF_CODE_PAGE);\n\n#else\t\t\t\t\t/* Static code page configuration (DBCS) */\n#define CODEPAGE FF_CODE_PAGE\nstatic const BYTE DbcTbl[] = MKCVTBL(TBL_DC, FF_CODE_PAGE);\n\n#endif\n\n\n\n\n/*--------------------------------------------------------------------------\n\n   Module Private Functions\n\n---------------------------------------------------------------------------*/\n\n/*-----------------------------------------------------------------------*/\n/* Print error header                                                    */\n/*-----------------------------------------------------------------------*/\n\nvoid print_error()\n{\n\tgfx_printf(\"\\n\\n\\n%k[FatFS] Error: %k\", 0xFFFFFF00, 0xFFFFFFFF);\n}\n\n\n/*-----------------------------------------------------------------------*/\n/* Load/Store multi-byte word in the FAT structure                       */\n/*-----------------------------------------------------------------------*/\n\nstatic WORD ld_word (const BYTE* ptr)\t/*\t Load a 2-byte little-endian word */\n{\n\tWORD rv;\n\n\trv = ptr[1];\n\trv = rv << 8 | ptr[0];\n\treturn rv;\n}\n\nstatic DWORD ld_dword (const BYTE* ptr)\t/* Load a 4-byte little-endian word */\n{\n\tDWORD rv;\n\n\trv = ptr[3];\n\trv = rv << 8 | ptr[2];\n\trv = rv << 8 | ptr[1];\n\trv = rv << 8 | ptr[0];\n\treturn rv;\n}\n\n#if FF_FS_EXFAT\nstatic QWORD ld_qword (const BYTE* ptr)\t/* Load an 8-byte little-endian word */\n{\n\tQWORD rv;\n\n\trv = ptr[7];\n\trv = rv << 8 | ptr[6];\n\trv = rv << 8 | ptr[5];\n\trv = rv << 8 | ptr[4];\n\trv = rv << 8 | ptr[3];\n\trv = rv << 8 | ptr[2];\n\trv = rv << 8 | ptr[1];\n\trv = rv << 8 | ptr[0];\n\treturn rv;\n}\n#endif\n\n#if !FF_FS_READONLY\nstatic void st_word (BYTE* ptr, WORD val)\t/* Store a 2-byte word in little-endian */\n{\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val;\n}\n\nstatic void st_dword (BYTE* ptr, DWORD val)\t/* Store a 4-byte word in little-endian */\n{\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val;\n}\n\n#if FF_FS_EXFAT\nstatic void st_qword (BYTE* ptr, QWORD val)\t/* Store an 8-byte word in little-endian */\n{\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val; val >>= 8;\n\t*ptr++ = (BYTE)val;\n}\n#endif\n#endif\t/* !FF_FS_READONLY */\n\n\n\n/*-----------------------------------------------------------------------*/\n/* String functions                                                      */\n/*-----------------------------------------------------------------------*/\n\n/* Copy memory to memory */\nstatic void mem_cpy (void* dst, const void* src, UINT cnt)\n{\n\tBYTE *d = (BYTE*)dst;\n\tconst BYTE *s = (const BYTE*)src;\n\n\tif (cnt != 0) {\n\t\tdo {\n\t\t\t*d++ = *s++;\n\t\t} while (--cnt);\n\t}\n}\n\n\n/* Fill memory block */\nstatic void mem_set (void* dst, int val, UINT cnt)\n{\n\tBYTE *d = (BYTE*)dst;\n\n\tdo {\n\t\t*d++ = (BYTE)val;\n\t} while (--cnt);\n}\n\n\n/* Compare memory block */\nstatic int mem_cmp (const void* dst, const void* src, UINT cnt)\t/* ZR:same, NZ:different */\n{\n\tconst BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src;\n\tint r = 0;\n\n\tdo {\n\t\tr = *d++ - *s++;\n\t} while (--cnt && r == 0);\n\n\treturn r;\n}\n\n\n/* Check if chr is contained in the string */\nstatic int chk_chr (const char* str, int chr)\t/* NZ:contained, ZR:not contained */\n{\n\twhile (*str && *str != chr) str++;\n\treturn *str;\n}\n\n\n/* Test if the character is DBC 1st byte */\nstatic int dbc_1st (BYTE c)\n{\n#if FF_CODE_PAGE == 0\t\t/* Variable code page */\n\tif (DbcTbl && c >= DbcTbl[0]) {\n\t\tif (c <= DbcTbl[1]) return 1;\t\t\t\t\t/* 1st byte range 1 */\n\t\tif (c >= DbcTbl[2] && c <= DbcTbl[3]) return 1;\t/* 1st byte range 2 */\n\t}\n#elif FF_CODE_PAGE >= 900\t/* DBCS fixed code page */\n\tif (c >= DbcTbl[0]) {\n\t\tif (c <= DbcTbl[1]) return 1;\n\t\tif (c >= DbcTbl[2] && c <= DbcTbl[3]) return 1;\n\t}\n#else\t\t\t\t\t\t/* SBCS fixed code page */\n\tif (c != 0) return 0;\t/* Always false */\n#endif\n\treturn 0;\n}\n\n\n/* Test if the character is DBC 2nd byte */\nstatic int dbc_2nd (BYTE c)\n{\n#if FF_CODE_PAGE == 0\t\t/* Variable code page */\n\tif (DbcTbl && c >= DbcTbl[4]) {\n\t\tif (c <= DbcTbl[5]) return 1;\t\t\t\t\t/* 2nd byte range 1 */\n\t\tif (c >= DbcTbl[6] && c <= DbcTbl[7]) return 1;\t/* 2nd byte range 2 */\n\t\tif (c >= DbcTbl[8] && c <= DbcTbl[9]) return 1;\t/* 2nd byte range 3 */\n\t}\n#elif FF_CODE_PAGE >= 900\t/* DBCS fixed code page */\n\tif (c >= DbcTbl[4]) {\n\t\tif (c <= DbcTbl[5]) return 1;\n\t\tif (c >= DbcTbl[6] && c <= DbcTbl[7]) return 1;\n\t\tif (c >= DbcTbl[8] && c <= DbcTbl[9]) return 1;\n\t}\n#else\t\t\t\t\t\t/* SBCS fixed code page */\n\tif (c != 0) return 0;\t/* Always false */\n#endif\n\treturn 0;\n}\n\n\n#if FF_USE_LFN\n\n/* Get a character from TCHAR string in defined API encodeing */\nstatic DWORD tchar2uni (\t/* Returns character in UTF-16 encoding (>=0x10000 on double encoding unit, 0xFFFFFFFF on decode error) */\n\tconst TCHAR** str\t\t/* Pointer to pointer to TCHAR string in configured encoding */\n)\n{\n\tDWORD uc;\n\tconst TCHAR *p = *str;\n\n#if FF_LFN_UNICODE == 1\t\t/* UTF-16 input */\n\tWCHAR wc;\n\n\tuc = *p++;\t/* Get a unit */\n\tif (IsSurrogate(uc)) {\t/* Surrogate? */\n\t\twc = *p++;\t\t/* Get low surrogate */\n\t\tif (!IsSurrogateH(uc) || !IsSurrogateL(wc)) return 0xFFFFFFFF;\t/* Wrong surrogate? */\n\t\tuc = uc << 16 | wc;\n\t}\n\n#elif FF_LFN_UNICODE == 2\t/* UTF-8 input */\n\tBYTE b;\n\tint nf;\n\n\tuc = (BYTE)*p++;\t/* Get a unit */\n\tif (uc & 0x80) {\t/* Multiple byte code? */\n\t\tif ((uc & 0xE0) == 0xC0) {\t/* 2-byte sequence? */\n\t\t\tuc &= 0x1F; nf = 1;\n\t\t} else {\n\t\t\tif ((uc & 0xF0) == 0xE0) {\t/* 3-byte sequence? */\n\t\t\t\tuc &= 0x0F; nf = 2;\n\t\t\t} else {\n\t\t\t\tif ((uc & 0xF8) == 0xF0) {\t/* 4-byte sequence? */\n\t\t\t\t\tuc &= 0x07; nf = 3;\n\t\t\t\t} else {\t\t\t\t\t/* Wrong sequence */\n\t\t\t\t\treturn 0xFFFFFFFF;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdo {\t/* Get trailing bytes */\n\t\t\tb = (BYTE)*p++;\n\t\t\tif ((b & 0xC0) != 0x80) return 0xFFFFFFFF;\t/* Wrong sequence? */\n\t\t\tuc = uc << 6 | (b & 0x3F);\n\t\t} while (--nf != 0);\n\t\tif (uc < 0x80 || IsSurrogate(uc) || uc >= 0x110000) return 0xFFFFFFFF;\t/* Wrong code? */\n\t\tif (uc >= 0x010000) uc = 0xD800DC00 | ((uc - 0x10000) << 6 & 0x3FF0000) | (uc & 0x3FF);\t/* Make a surrogate pair if needed */\n\t}\n\n#elif FF_LFN_UNICODE == 3\t/* UTF-32 input */\n\tuc = (TCHAR)*p++;\t/* Get a unit */\n\tif (uc >= 0x110000) return 0xFFFFFFFF;\t/* Wrong code? */\n\tif (uc >= 0x010000) uc = 0xD800DC00 | ((uc - 0x10000) << 6 & 0x3FF0000) | (uc & 0x3FF);\t/* Make a surrogate pair if needed */\n\n#else\t\t/* ANSI/OEM input */\n\tBYTE b;\n\tWCHAR wc;\n\n\twc = (BYTE)*p++;\t\t\t/* Get a byte */\n\tif (dbc_1st((BYTE)wc)) {\t/* Is it a DBC 1st byte? */\n\t\tb = (BYTE)*p++;\t\t\t/* Get 2nd byte */\n\t\tif (!dbc_2nd(b)) return 0xFFFFFFFF;\t/* Invalid code? */\n\t\twc = (wc << 8) + b;\t\t/* Make a DBC */\n\t}\n\tif (wc != 0) {\n\t\twc = ff_oem2uni(wc, CODEPAGE);\t/* ANSI/OEM ==> Unicode */\n\t\tif (wc == 0) return 0xFFFFFFFF;\t/* Invalid code? */\n\t}\n\tuc = wc;\n\n#endif\n\t*str = p;\t/* Next read pointer */\n\treturn uc;\n}\n\n\n/* Output a TCHAR string in defined API encoding */\nstatic BYTE put_utf (\t/* Returns number of encoding units written (0:buffer overflow or wrong encoding) */\n\tDWORD chr,\t/* UTF-16 encoded character (Double encoding unit char if >=0x10000) */\n\tTCHAR* buf,\t/* Output buffer */\n\tUINT szb\t/* Size of the buffer */\n)\n{\n#if FF_LFN_UNICODE == 1\t/* UTF-16 output */\n\tWCHAR hs, wc;\n\n\ths = (WCHAR)(chr >> 16);\n\twc = (WCHAR)chr;\n\tif (hs == 0) {\t/* Single encoding unit? */\n\t\tif (szb < 1 || IsSurrogate(wc)) return 0;\t/* Buffer overflow or wrong code? */\n\t\t*buf = wc;\n\t\treturn 1;\n\t}\n\tif (szb < 2 || !IsSurrogateH(hs) || !IsSurrogateL(wc)) return 0;\t/* Buffer overflow or wrong surrogate? */\n\t*buf++ = hs;\n\t*buf++ = wc;\n\treturn 2;\n\n#elif FF_LFN_UNICODE == 2\t/* UTF-8 output */\n\tDWORD hc;\n\n\tif (chr < 0x80) {\t/* Single byte code? */\n\t\tif (szb < 1) return 0;\t/* Buffer overflow? */\n\t\t*buf = (TCHAR)chr;\n\t\treturn 1;\n\t}\n\tif (chr < 0x800) {\t/* 2-byte sequence? */\n\t\tif (szb < 2) return 0;\t/* Buffer overflow? */\n\t\t*buf++ = (TCHAR)(0xC0 | (chr >> 6 & 0x1F));\n\t\t*buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F));\n\t\treturn 2;\n\t}\n\tif (chr < 0x10000) {\t/* 3-byte sequence? */\n\t\tif (szb < 3 || IsSurrogate(chr)) return 0;\t/* Buffer overflow or wrong code? */\n\t\t*buf++ = (TCHAR)(0xE0 | (chr >> 12 & 0x0F));\n\t\t*buf++ = (TCHAR)(0x80 | (chr >> 6 & 0x3F));\n\t\t*buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F));\n\t\treturn 3;\n\t}\n\t/* 4-byte sequence */\n\tif (szb < 4) return 0;\t/* Buffer overflow? */\n\thc = ((chr & 0xFFFF0000) - 0xD8000000) >> 6;\t/* Get high 10 bits */\n\tchr = (chr & 0xFFFF) - 0xDC00;\t\t\t\t\t/* Get low 10 bits */\n\tif (hc >= 0x100000 || chr >= 0x400) return 0;\t/* Wrong surrogate? */\n\tchr = (hc | chr) + 0x10000;\n\t*buf++ = (TCHAR)(0xF0 | (chr >> 18 & 0x07));\n\t*buf++ = (TCHAR)(0x80 | (chr >> 12 & 0x3F));\n\t*buf++ = (TCHAR)(0x80 | (chr >> 6 & 0x3F));\n\t*buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F));\n\treturn 4;\n\n#elif FF_LFN_UNICODE == 3\t/* UTF-32 output */\n\tDWORD hc;\n\n\tif (szb < 1) return 0;\t/* Buffer overflow? */\n\tif (chr >= 0x10000) {\t/* Out of BMP? */\n\t\thc = ((chr & 0xFFFF0000) - 0xD8000000) >> 6;\t/* Get high 10 bits */\n\t\tchr = (chr & 0xFFFF) - 0xDC00;\t\t\t\t\t/* Get low 10 bits */\n\t\tif (hc >= 0x100000 || chr >= 0x400) return 0;\t/* Wrong surrogate? */\n\t\tchr = (hc | chr) + 0x10000;\n\t}\n\t*buf++ = (TCHAR)chr;\n\treturn 1;\n\n#else\t\t\t\t\t\t/* ANSI/OEM output */\n\tWCHAR wc;\n\n\twc = ff_uni2oem(chr, CODEPAGE);\n\tif (wc >= 0x100) {\t/* Is this a DBC? */\n\t\tif (szb < 2) return 0;\n\t\t*buf++ = (char)(wc >> 8);\t/* Store DBC 1st byte */\n\t\t*buf++ = (TCHAR)wc;\t\t\t/* Store DBC 2nd byte */\n\t\treturn 2;\n\t}\n\tif (wc == 0 || szb < 1) return 0;\t/* Invalid char or buffer overflow? */\n\t*buf++ = (TCHAR)wc;\t\t\t\t\t/* Store the character */\n\treturn 1;\n#endif\n}\n#endif\t/* FF_USE_LFN */\n\n\n#if FF_FS_REENTRANT\n/*-----------------------------------------------------------------------*/\n/* Request/Release grant to access the volume                            */\n/*-----------------------------------------------------------------------*/\nstatic int lock_fs (\t\t/* 1:Ok, 0:timeout */\n\tFATFS* fs\t\t/* Filesystem object */\n)\n{\n\treturn ff_req_grant(fs->sobj);\n}\n\n\nstatic void unlock_fs (\n\tFATFS* fs,\t\t/* Filesystem object */\n\tFRESULT res\t\t/* Result code to be returned */\n)\n{\n\tif (fs && res != FR_NOT_ENABLED && res != FR_INVALID_DRIVE && res != FR_TIMEOUT) {\n\t\tff_rel_grant(fs->sobj);\n\t}\n}\n\n#endif\n\n\n\n#if FF_FS_LOCK != 0\n/*-----------------------------------------------------------------------*/\n/* File lock control functions                                           */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT chk_lock (\t/* Check if the file can be accessed */\n\tDIR* dp,\t\t/* Directory object pointing the file to be checked */\n\tint acc\t\t\t/* Desired access type (0:Read mode open, 1:Write mode open, 2:Delete or rename) */\n)\n{\n\tUINT i, be;\n\n\t/* Search open object table for the object */\n\tbe = 0;\n\tfor (i = 0; i < FF_FS_LOCK; i++) {\n\t\tif (Files[i].fs) {\t/* Existing entry */\n\t\t\tif (Files[i].fs == dp->obj.fs &&\t \t/* Check if the object matches with an open object */\n\t\t\t\tFiles[i].clu == dp->obj.sclust &&\n\t\t\t\tFiles[i].ofs == dp->dptr) break;\n\t\t} else {\t\t\t/* Blank entry */\n\t\t\tbe = 1;\n\t\t}\n\t}\n\tif (i == FF_FS_LOCK) {\t/* The object has not been opened */\n\t\treturn (!be && acc != 2) ? FR_TOO_MANY_OPEN_FILES : FR_OK;\t/* Is there a blank entry for new object? */\n\t}\n\n\t/* The object was opened. Reject any open against writing file and all write mode open */\n\treturn (acc != 0 || Files[i].ctr == 0x100) ? FR_LOCKED : FR_OK;\n}\n\n\nstatic int enq_lock (void)\t/* Check if an entry is available for a new object */\n{\n\tUINT i;\n\n\tfor (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ;\n\treturn (i == FF_FS_LOCK) ? 0 : 1;\n}\n\n\nstatic UINT inc_lock (\t/* Increment object open counter and returns its index (0:Internal error) */\n\tDIR* dp,\t/* Directory object pointing the file to register or increment */\n\tint acc\t\t/* Desired access (0:Read, 1:Write, 2:Delete/Rename) */\n)\n{\n\tUINT i;\n\n\n\tfor (i = 0; i < FF_FS_LOCK; i++) {\t/* Find the object */\n\t\tif (Files[i].fs == dp->obj.fs &&\n\t\t\tFiles[i].clu == dp->obj.sclust &&\n\t\t\tFiles[i].ofs == dp->dptr) break;\n\t}\n\n\tif (i == FF_FS_LOCK) {\t\t\t\t/* Not opened. Register it as new. */\n\t\tfor (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ;\n\t\tif (i == FF_FS_LOCK) return 0;\t/* No free entry to register (int err) */\n\t\tFiles[i].fs = dp->obj.fs;\n\t\tFiles[i].clu = dp->obj.sclust;\n\t\tFiles[i].ofs = dp->dptr;\n\t\tFiles[i].ctr = 0;\n\t}\n\n\tif (acc >= 1 && Files[i].ctr) return 0;\t/* Access violation (int err) */\n\n\tFiles[i].ctr = acc ? 0x100 : Files[i].ctr + 1;\t/* Set semaphore value */\n\n\treturn i + 1;\t/* Index number origin from 1 */\n}\n\n\nstatic FRESULT dec_lock (\t/* Decrement object open counter */\n\tUINT i\t\t\t/* Semaphore index (1..) */\n)\n{\n\tWORD n;\n\tFRESULT res;\n\n\n\tif (--i < FF_FS_LOCK) {\t/* Index number origin from 0 */\n\t\tn = Files[i].ctr;\n\t\tif (n == 0x100) n = 0;\t\t/* If write mode open, delete the entry */\n\t\tif (n > 0) n--;\t\t\t\t/* Decrement read mode open count */\n\t\tFiles[i].ctr = n;\n\t\tif (n == 0) Files[i].fs = 0;\t/* Delete the entry if open count gets zero */\n\t\tres = FR_OK;\n\t} else {\n\t\tres = FR_INT_ERR;\t\t\t/* Invalid index nunber */\n\t}\n\treturn res;\n}\n\n\nstatic void clear_lock (\t/* Clear lock entries of the volume */\n\tFATFS *fs\n)\n{\n\tUINT i;\n\n\tfor (i = 0; i < FF_FS_LOCK; i++) {\n\t\tif (Files[i].fs == fs) Files[i].fs = 0;\n\t}\n}\n\n#endif\t/* FF_FS_LOCK != 0 */\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Move/Flush disk access window in the filesystem object                */\n/*-----------------------------------------------------------------------*/\n#if !FF_FS_READONLY\nstatic FRESULT sync_window (\t/* Returns FR_OK or FR_DISK_ERR */\n\tFATFS* fs\t\t\t/* Filesystem object */\n)\n{\n\tFRESULT res = FR_OK;\n\n\n\tif (fs->wflag) {\t/* Is the disk access window dirty */\n\t\tif (disk_write(fs->pdrv, fs->win, fs->winsect, 1) == RES_OK) {\t/* Write back the window */\n\t\t\tfs->wflag = 0;\t/* Clear window dirty flag */\n\t\t\tif (fs->winsect - fs->fatbase < fs->fsize) {\t/* Is it in the 1st FAT? */\n\t\t\t\tif (fs->n_fats == 2) disk_write(fs->pdrv, fs->win, fs->winsect + fs->fsize, 1);\t/* Reflect it to 2nd FAT if needed */\n\t\t\t}\n\t\t} else {\n\t\t\tres = FR_DISK_ERR;\n\t\t}\n\t}\n\treturn res;\n}\n#endif\n\n\nstatic FRESULT move_window (\t/* Returns FR_OK or FR_DISK_ERR */\n\tFATFS* fs,\t\t\t/* Filesystem object */\n\tDWORD sector\t\t/* Sector number to make appearance in the fs->win[] */\n)\n{\n\tFRESULT res = FR_OK;\n\n\n\tif (sector != fs->winsect) {\t/* Window offset changed? */\n#if !FF_FS_READONLY\n\t\tres = sync_window(fs);\t\t/* Write-back changes */\n#endif\n\t\tif (res == FR_OK) {\t\t\t/* Fill sector window with new data */\n\t\t\tif (disk_read(fs->pdrv, fs->win, sector, 1) != RES_OK) {\n\t\t\t\tsector = 0xFFFFFFFF;\t/* Invalidate window if read data is not valid */\n\t\t\t\tres = FR_DISK_ERR;\n\t\t\t}\n\t\t\tfs->winsect = sector;\n\t\t}\n\t}\n\treturn res;\n}\n\n\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Synchronize filesystem and data on the storage                        */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT sync_fs (\t/* Returns FR_OK or FR_DISK_ERR */\n\tFATFS* fs\t\t/* Filesystem object */\n)\n{\n\tFRESULT res;\n\n\n\tres = sync_window(fs);\n\tif (res == FR_OK) {\n\t\tif (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) {\t/* FAT32: Update FSInfo sector if needed */\n\t\t\t/* Create FSInfo structure */\n\t\t\tmem_set(fs->win, 0, sizeof fs->win);\n\t\t\tst_word(fs->win + BS_55AA, 0xAA55);\n\t\t\tst_dword(fs->win + FSI_LeadSig, 0x41615252);\n\t\t\tst_dword(fs->win + FSI_StrucSig, 0x61417272);\n\t\t\tst_dword(fs->win + FSI_Free_Count, fs->free_clst);\n\t\t\tst_dword(fs->win + FSI_Nxt_Free, fs->last_clst);\n\t\t\t/* Write it into the FSInfo sector */\n\t\t\tfs->winsect = fs->volbase + 1;\n\t\t\tdisk_write(fs->pdrv, fs->win, fs->winsect, 1);\n\t\t\tfs->fsi_flag = 0;\n\t\t}\n\t\t/* Make sure that no pending write process in the lower layer */\n\t\tif (disk_ioctl(fs->pdrv, CTRL_SYNC, 0) != RES_OK) res = FR_DISK_ERR;\n\t}\n\n\treturn res;\n}\n\n#endif\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Get physical sector number from cluster number                        */\n/*-----------------------------------------------------------------------*/\n\nstatic DWORD clst2sect (\t/* !=0:Sector number, 0:Failed (invalid cluster#) */\n\tFATFS* fs,\t\t/* Filesystem object */\n\tDWORD clst\t\t/* Cluster# to be converted */\n)\n{\n\tclst -= 2;\t\t/* Cluster number is origin from 2 */\n\tif (clst >= fs->n_fatent - 2) return 0;\t\t/* Is it invalid cluster number? */\n\treturn fs->database + fs->csize * clst;\t\t/* Start sector number of the cluster */\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* FAT access - Read value of a FAT entry                                */\n/*-----------------------------------------------------------------------*/\n\nstatic DWORD get_fat (\t\t/* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x7FFFFFFF:Cluster status */\n\tFFOBJID* obj,\t/* Corresponding object */\n\tDWORD clst\t\t/* Cluster number to get the value */\n)\n{\n\tUINT wc, bc;\n\tDWORD val;\n\tFATFS *fs = obj->fs;\n\n\n\tif (clst < 2 || clst >= fs->n_fatent) {\t/* Check if in valid range */\n\t\tval = 1;\t/* Internal error */\n\n\t} else {\n\t\tval = 0xFFFFFFFF;\t/* Default value falls on disk error */\n\n\t\tswitch (fs->fs_type) {\n\t\tcase FS_FAT12 :\n\t\t\tbc = (UINT)clst; bc += bc / 2;\n\t\t\tif (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break;\n\t\t\twc = fs->win[bc++ % SS(fs)];\t\t/* Get 1st byte of the entry */\n\t\t\tif (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break;\n\t\t\twc |= fs->win[bc % SS(fs)] << 8;\t/* Merge 2nd byte of the entry */\n\t\t\tval = (clst & 1) ? (wc >> 4) : (wc & 0xFFF);\t/* Adjust bit position */\n\t\t\tbreak;\n\n\t\tcase FS_FAT16 :\n\t\t\tif (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))) != FR_OK) break;\n\t\t\tval = ld_word(fs->win + clst * 2 % SS(fs));\t\t/* Simple WORD array */\n\t\t\tbreak;\n\n\t\tcase FS_FAT32 :\n\t\t\tif (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break;\n\t\t\tval = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x0FFFFFFF;\t/* Simple DWORD array but mask out upper 4 bits */\n\t\t\tbreak;\n#if FF_FS_EXFAT\n\t\tcase FS_EXFAT :\n\t\t\tif ((obj->objsize != 0 && obj->sclust != 0) || obj->stat == 0) {\t/* Object except root dir must have valid data length */\n\t\t\t\tDWORD cofs = clst - obj->sclust;\t/* Offset from start cluster */\n\t\t\t\tDWORD clen = (DWORD)((obj->objsize - 1) / SS(fs)) / fs->csize;\t/* Number of clusters - 1 */\n\n\t\t\t\tif (obj->stat == 2 && cofs <= clen) {\t/* Is it a contiguous chain? */\n\t\t\t\t\tval = (cofs == clen) ? 0x7FFFFFFF : clst + 1;\t/* No data on the FAT, generate the value */\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (obj->stat == 3 && cofs < obj->n_cont) {\t/* Is it in the 1st fragment? */\n\t\t\t\t\tval = clst + 1; \t/* Generate the value */\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (obj->stat != 2) {\t/* Get value from FAT if FAT chain is valid */\n\t\t\t\t\tif (obj->n_frag != 0) {\t/* Is it on the growing edge? */\n\t\t\t\t\t\tval = 0x7FFFFFFF;\t/* Generate EOC */\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break;\n\t\t\t\t\t\tval = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x7FFFFFFF;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* go to default */\n#endif\n\t\tdefault:\n\t\t\tval = 1;\t/* Internal error */\n\t\t}\n\t}\n\n\treturn val;\n}\n\n\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* FAT access - Change value of a FAT entry                              */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT put_fat (\t/* FR_OK(0):succeeded, !=0:error */\n\tFATFS* fs,\t\t/* Corresponding filesystem object */\n\tDWORD clst,\t\t/* FAT index number (cluster number) to be changed */\n\tDWORD val\t\t/* New value to be set to the entry */\n)\n{\n\tUINT bc;\n\tBYTE *p;\n\tFRESULT res = FR_INT_ERR;\n\n\n\tif (clst >= 2 && clst < fs->n_fatent) {\t/* Check if in valid range */\n\t\tswitch (fs->fs_type) {\n\t\tcase FS_FAT12 :\n\t\t\tbc = (UINT)clst; bc += bc / 2;\t/* bc: byte offset of the entry */\n\t\t\tres = move_window(fs, fs->fatbase + (bc / SS(fs)));\n\t\t\tif (res != FR_OK) break;\n\t\t\tp = fs->win + bc++ % SS(fs);\n\t\t\t*p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;\t\t/* Put 1st byte */\n\t\t\tfs->wflag = 1;\n\t\t\tres = move_window(fs, fs->fatbase + (bc / SS(fs)));\n\t\t\tif (res != FR_OK) break;\n\t\t\tp = fs->win + bc % SS(fs);\n\t\t\t*p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));\t/* Put 2nd byte */\n\t\t\tfs->wflag = 1;\n\t\t\tbreak;\n\n\t\tcase FS_FAT16 :\n\t\t\tres = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)));\n\t\t\tif (res != FR_OK) break;\n\t\t\tst_word(fs->win + clst * 2 % SS(fs), (WORD)val);\t/* Simple WORD array */\n\t\t\tfs->wflag = 1;\n\t\t\tbreak;\n\n\t\tcase FS_FAT32 :\n#if FF_FS_EXFAT\n\t\tcase FS_EXFAT :\n#endif\n\t\t\tres = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)));\n\t\t\tif (res != FR_OK) break;\n\t\t\tif (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) {\n\t\t\t\tval = (val & 0x0FFFFFFF) | (ld_dword(fs->win + clst * 4 % SS(fs)) & 0xF0000000);\n\t\t\t}\n\t\t\tst_dword(fs->win + clst * 4 % SS(fs), val);\n\t\t\tfs->wflag = 1;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn res;\n}\n\n#endif /* !FF_FS_READONLY */\n\n\n\n\n#if FF_FS_EXFAT && !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* exFAT: Accessing FAT and Allocation Bitmap                            */\n/*-----------------------------------------------------------------------*/\n\n/*--------------------------------------*/\n/* Find a contiguous free cluster block */\n/*--------------------------------------*/\n\nstatic DWORD find_bitmap (\t/* 0:Not found, 2..:Cluster block found, 0xFFFFFFFF:Disk error */\n\tFATFS* fs,\t/* Filesystem object */\n\tDWORD clst,\t/* Cluster number to scan from */\n\tDWORD ncl\t/* Number of contiguous clusters to find (1..) */\n)\n{\n\tBYTE bm, bv;\n\tUINT i;\n\tDWORD val, scl, ctr;\n\n\n\tclst -= 2;\t/* The first bit in the bitmap corresponds to cluster #2 */\n\tif (clst >= fs->n_fatent - 2) clst = 0;\n\tscl = val = clst; ctr = 0;\n\tfor (;;) {\n\t\tif (move_window(fs, fs->bitbase + val / 8 / SS(fs)) != FR_OK) return 0xFFFFFFFF;\n\t\ti = val / 8 % SS(fs); bm = 1 << (val % 8);\n\t\tdo {\n\t\t\tdo {\n\t\t\t\tbv = fs->win[i] & bm; bm <<= 1;\t\t/* Get bit value */\n\t\t\t\tif (++val >= fs->n_fatent - 2) {\t/* Next cluster (with wrap-around) */\n\t\t\t\t\tval = 0; bm = 0; i = SS(fs);\n\t\t\t\t}\n\t\t\t\tif (bv == 0) {\t/* Is it a free cluster? */\n\t\t\t\t\tif (++ctr == ncl) return scl + 2;\t/* Check if run length is sufficient for required */\n\t\t\t\t} else {\n\t\t\t\t\tscl = val; ctr = 0;\t\t/* Encountered a cluster in-use, restart to scan */\n\t\t\t\t}\n\t\t\t\tif (val == clst) return 0;\t/* All cluster scanned? */\n\t\t\t} while (bm != 0);\n\t\t\tbm = 1;\n\t\t} while (++i < SS(fs));\n\t}\n}\n\n\n/*----------------------------------------*/\n/* Set/Clear a block of allocation bitmap */\n/*----------------------------------------*/\n\nstatic FRESULT change_bitmap (\n\tFATFS* fs,\t/* Filesystem object */\n\tDWORD clst,\t/* Cluster number to change from */\n\tDWORD ncl,\t/* Number of clusters to be changed */\n\tint bv\t\t/* bit value to be set (0 or 1) */\n)\n{\n\tBYTE bm;\n\tUINT i;\n\tDWORD sect;\n\n\n\tclst -= 2;\t/* The first bit corresponds to cluster #2 */\n\tsect = fs->bitbase + clst / 8 / SS(fs);\t/* Sector address */\n\ti = clst / 8 % SS(fs);\t\t\t\t\t/* Byte offset in the sector */\n\tbm = 1 << (clst % 8);\t\t\t\t\t/* Bit mask in the byte */\n\tfor (;;) {\n\t\tif (move_window(fs, sect++) != FR_OK) return FR_DISK_ERR;\n\t\tdo {\n\t\t\tdo {\n\t\t\t\tif (bv == (int)((fs->win[i] & bm) != 0)) return FR_INT_ERR;\t/* Is the bit expected value? */\n\t\t\t\tfs->win[i] ^= bm;\t/* Flip the bit */\n\t\t\t\tfs->wflag = 1;\n\t\t\t\tif (--ncl == 0) return FR_OK;\t/* All bits processed? */\n\t\t\t} while (bm <<= 1);\t\t/* Next bit */\n\t\t\tbm = 1;\n\t\t} while (++i < SS(fs));\t\t/* Next byte */\n\t\ti = 0;\n\t}\n}\n\n\n/*---------------------------------------------*/\n/* Fill the first fragment of the FAT chain    */\n/*---------------------------------------------*/\n\nstatic FRESULT fill_first_frag (\n\tFFOBJID* obj\t/* Pointer to the corresponding object */\n)\n{\n\tFRESULT res;\n\tDWORD cl, n;\n\n\n\tif (obj->stat == 3) {\t/* Has the object been changed 'fragmented' in this session? */\n\t\tfor (cl = obj->sclust, n = obj->n_cont; n; cl++, n--) {\t/* Create cluster chain on the FAT */\n\t\t\tres = put_fat(obj->fs, cl, cl + 1);\n\t\t\tif (res != FR_OK) return res;\n\t\t}\n\t\tobj->stat = 0;\t/* Change status 'FAT chain is valid' */\n\t}\n\treturn FR_OK;\n}\n\n\n/*---------------------------------------------*/\n/* Fill the last fragment of the FAT chain     */\n/*---------------------------------------------*/\n\nstatic FRESULT fill_last_frag (\n\tFFOBJID* obj,\t/* Pointer to the corresponding object */\n\tDWORD lcl,\t\t/* Last cluster of the fragment */\n\tDWORD term\t\t/* Value to set the last FAT entry */\n)\n{\n\tFRESULT res;\n\n\n\twhile (obj->n_frag > 0) {\t/* Create the chain of last fragment */\n\t\tres = put_fat(obj->fs, lcl - obj->n_frag + 1, (obj->n_frag > 1) ? lcl - obj->n_frag + 2 : term);\n\t\tif (res != FR_OK) return res;\n\t\tobj->n_frag--;\n\t}\n\treturn FR_OK;\n}\n\n#endif\t/* FF_FS_EXFAT && !FF_FS_READONLY */\n\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* FAT handling - Remove a cluster chain                                 */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT remove_chain (\t/* FR_OK(0):succeeded, !=0:error */\n\tFFOBJID* obj,\t\t/* Corresponding object */\n\tDWORD clst,\t\t\t/* Cluster to remove a chain from */\n\tDWORD pclst\t\t\t/* Previous cluster of clst (0 if entire chain) */\n)\n{\n\tFRESULT res = FR_OK;\n\tDWORD nxt;\n\tFATFS *fs = obj->fs;\n#if FF_FS_EXFAT || FF_USE_TRIM\n\tDWORD scl = clst, ecl = clst;\n#endif\n#if FF_USE_TRIM\n\tDWORD rt[2];\n#endif\n\n\tif (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR;\t/* Check if in valid range */\n\n\t/* Mark the previous cluster 'EOC' on the FAT if it exists */\n\tif (pclst != 0 && (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT || obj->stat != 2)) {\n\t\tres = put_fat(fs, pclst, 0xFFFFFFFF);\n\t\tif (res != FR_OK) return res;\n\t}\n\n\t/* Remove the chain */\n\tdo {\n\t\tnxt = get_fat(obj, clst);\t\t\t/* Get cluster status */\n\t\tif (nxt == 0) break;\t\t\t\t/* Empty cluster? */\n\t\tif (nxt == 1) return FR_INT_ERR;\t/* Internal error? */\n\t\tif (nxt == 0xFFFFFFFF) return FR_DISK_ERR;\t/* Disk error? */\n\t\tif (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) {\n\t\t\tres = put_fat(fs, clst, 0);\t\t/* Mark the cluster 'free' on the FAT */\n\t\t\tif (res != FR_OK) return res;\n\t\t}\n\t\tif (fs->free_clst < fs->n_fatent - 2) {\t/* Update FSINFO */\n\t\t\tfs->free_clst++;\n\t\t\tfs->fsi_flag |= 1;\n\t\t}\n#if FF_FS_EXFAT || FF_USE_TRIM\n\t\tif (ecl + 1 == nxt) {\t/* Is next cluster contiguous? */\n\t\t\tecl = nxt;\n\t\t} else {\t\t\t\t/* End of contiguous cluster block */\n#if FF_FS_EXFAT\n\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\tres = change_bitmap(fs, scl, ecl - scl + 1, 0);\t/* Mark the cluster block 'free' on the bitmap */\n\t\t\t\tif (res != FR_OK) return res;\n\t\t\t}\n#endif\n#if FF_USE_TRIM\n\t\t\trt[0] = clst2sect(fs, scl);\t\t\t\t\t/* Start of data area freed */\n\t\t\trt[1] = clst2sect(fs, ecl) + fs->csize - 1;\t/* End of data area freed */\n\t\t\tdisk_ioctl(fs->pdrv, CTRL_TRIM, rt);\t\t/* Inform device the data in the block is no longer needed */\n#endif\n\t\t\tscl = ecl = nxt;\n\t\t}\n#endif\n\t\tclst = nxt;\t\t\t\t\t/* Next cluster */\n\t} while (clst < fs->n_fatent);\t/* Repeat while not the last link */\n\n#if FF_FS_EXFAT\n\t/* Some post processes for chain status */\n\tif (fs->fs_type == FS_EXFAT) {\n\t\tif (pclst == 0) {\t/* Has the entire chain been removed? */\n\t\t\tobj->stat = 0;\t\t/* Change the chain status 'initial' */\n\t\t} else {\n\t\t\tif (obj->stat == 0) {\t/* Is it a fragmented chain from the beginning of this session? */\n\t\t\t\tclst = obj->sclust;\t\t/* Follow the chain to check if it gets contiguous */\n\t\t\t\twhile (clst != pclst) {\n\t\t\t\t\tnxt = get_fat(obj, clst);\n\t\t\t\t\tif (nxt < 2) return FR_INT_ERR;\n\t\t\t\t\tif (nxt == 0xFFFFFFFF) return FR_DISK_ERR;\n\t\t\t\t\tif (nxt != clst + 1) break;\t/* Not contiguous? */\n\t\t\t\t\tclst++;\n\t\t\t\t}\n\t\t\t\tif (clst == pclst) {\t/* Has the chain got contiguous again? */\n\t\t\t\t\tobj->stat = 2;\t\t/* Change the chain status 'contiguous' */\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (obj->stat == 3 && pclst >= obj->sclust && pclst <= obj->sclust + obj->n_cont) {\t/* Was the chain fragmented in this session and got contiguous again? */\n\t\t\t\t\tobj->stat = 2;\t/* Change the chain status 'contiguous' */\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n#endif\n\treturn FR_OK;\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* FAT handling - Stretch a chain or Create a new chain                  */\n/*-----------------------------------------------------------------------*/\n\nstatic DWORD create_chain (\t/* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */\n\tFFOBJID* obj,\t\t/* Corresponding object */\n\tDWORD clst\t\t\t/* Cluster# to stretch, 0:Create a new chain */\n)\n{\n\tDWORD cs, ncl, scl;\n\tFRESULT res;\n\tFATFS *fs = obj->fs;\n\n\n\tif (clst == 0) {\t/* Create a new chain */\n\t\tscl = fs->last_clst;\t\t\t\t/* Suggested cluster to start to find */\n\t\tif (scl == 0 || scl >= fs->n_fatent) scl = 1;\n\t}\n\telse {\t\t\t\t/* Stretch a chain */\n\t\tcs = get_fat(obj, clst);\t\t\t/* Check the cluster status */\n\t\tif (cs < 2) return 1;\t\t\t\t/* Test for insanity */\n\t\tif (cs == 0xFFFFFFFF) return cs;\t/* Test for disk error */\n\t\tif (cs < fs->n_fatent) return cs;\t/* It is already followed by next cluster */\n\t\tscl = clst;\t\t\t\t\t\t\t/* Cluster to start to find */\n\t}\n\tif (fs->free_clst == 0) return 0;\t\t/* No free cluster */\n\n#if FF_FS_EXFAT\n\tif (fs->fs_type == FS_EXFAT) {\t/* On the exFAT volume */\n\t\tncl = find_bitmap(fs, scl, 1);\t\t\t\t/* Find a free cluster */\n\t\tif (ncl == 0 || ncl == 0xFFFFFFFF) return ncl;\t/* No free cluster or hard error? */\n\t\tres = change_bitmap(fs, ncl, 1, 1);\t\t\t/* Mark the cluster 'in use' */\n\t\tif (res == FR_INT_ERR) return 1;\n\t\tif (res == FR_DISK_ERR) return 0xFFFFFFFF;\n\t\tif (clst == 0) {\t\t\t\t\t\t\t/* Is it a new chain? */\n\t\t\tobj->stat = 2;\t\t\t\t\t\t\t/* Set status 'contiguous' */\n\t\t} else {\t\t\t\t\t\t\t\t\t/* It is a stretched chain */\n\t\t\tif (obj->stat == 2 && ncl != scl + 1) {\t/* Is the chain got fragmented? */\n\t\t\t\tobj->n_cont = scl - obj->sclust;\t/* Set size of the contiguous part */\n\t\t\t\tobj->stat = 3;\t\t\t\t\t\t/* Change status 'just fragmented' */\n\t\t\t}\n\t\t}\n\t\tif (obj->stat != 2) {\t/* Is the file non-contiguous? */\n\t\t\tif (ncl == clst + 1) {\t/* Is the cluster next to previous one? */\n\t\t\t\tobj->n_frag = obj->n_frag ? obj->n_frag + 1 : 2;\t/* Increment size of last framgent */\n\t\t\t} else {\t\t\t\t/* New fragment */\n\t\t\t\tif (obj->n_frag == 0) obj->n_frag = 1;\n\t\t\t\tres = fill_last_frag(obj, clst, ncl);\t/* Fill last fragment on the FAT and link it to new one */\n\t\t\t\tif (res == FR_OK) obj->n_frag = 1;\n\t\t\t}\n\t\t}\n\t} else\n#endif\n\t{\t/* On the FAT/FAT32 volume */\n\t\tncl = 0;\n\t\tif (scl == clst) {\t\t\t\t\t\t/* Stretching an existing chain? */\n\t\t\tncl = scl + 1;\t\t\t\t\t\t/* Test if next cluster is free */\n\t\t\tif (ncl >= fs->n_fatent) ncl = 2;\n\t\t\tcs = get_fat(obj, ncl);\t\t\t\t/* Get next cluster status */\n\t\t\tif (cs == 1 || cs == 0xFFFFFFFF) return cs;\t/* Test for error */\n\t\t\tif (cs != 0) {\t\t\t\t\t\t/* Not free? */\n\t\t\t\tcs = fs->last_clst;\t\t\t\t/* Start at suggested cluster if it is valid */\n\t\t\t\tif (cs >= 2 && cs < fs->n_fatent) scl = cs;\n\t\t\t\tncl = 0;\n\t\t\t}\n\t\t}\n\t\tif (ncl == 0) {\t/* The new cluster cannot be contiguous and find another fragment */\n\t\t\tncl = scl;\t/* Start cluster */\n\t\t\tfor (;;) {\n\t\t\t\tncl++;\t\t\t\t\t\t\t/* Next cluster */\n\t\t\t\tif (ncl >= fs->n_fatent) {\t\t/* Check wrap-around */\n\t\t\t\t\tncl = 2;\n\t\t\t\t\tif (ncl > scl) return 0;\t/* No free cluster found? */\n\t\t\t\t}\n\t\t\t\tcs = get_fat(obj, ncl);\t\t\t/* Get the cluster status */\n\t\t\t\tif (cs == 0) break;\t\t\t\t/* Found a free cluster? */\n\t\t\t\tif (cs == 1 || cs == 0xFFFFFFFF) return cs;\t/* Test for error */\n\t\t\t\tif (ncl == scl) return 0;\t\t/* No free cluster found? */\n\t\t\t}\n\t\t}\n\t\tres = put_fat(fs, ncl, 0xFFFFFFFF);\t\t/* Mark the new cluster 'EOC' */\n\t\tif (res == FR_OK && clst != 0) {\n\t\t\tres = put_fat(fs, clst, ncl);\t\t/* Link it from the previous one if needed */\n\t\t}\n\t}\n\n\tif (res == FR_OK) {\t\t\t/* Update FSINFO if function succeeded. */\n\t\tfs->last_clst = ncl;\n\t\tif (fs->free_clst <= fs->n_fatent - 2) fs->free_clst--;\n\t\tfs->fsi_flag |= 1;\n\t} else {\n\t\tncl = (res == FR_DISK_ERR) ? 0xFFFFFFFF : 1;\t/* Failed. Generate error status */\n\t}\n\n\treturn ncl;\t\t/* Return new cluster number or error status */\n}\n\n#endif /* !FF_FS_READONLY */\n\n\n\n\n#if FF_USE_FASTSEEK\n/*-----------------------------------------------------------------------*/\n/* FAT handling - Convert offset into cluster with link map table        */\n/*-----------------------------------------------------------------------*/\n\nstatic DWORD clmt_clust (\t/* <2:Error, >=2:Cluster number */\n\tFIL* fp,\t\t/* Pointer to the file object */\n\tFSIZE_t ofs\t\t/* File offset to be converted to cluster# */\n)\n{\n\tDWORD cl, ncl, *tbl;\n\tFATFS *fs = fp->obj.fs;\n\n\n\ttbl = fp->cltbl + 1;\t/* Top of CLMT */\n\tcl = (DWORD)(ofs / SS(fs) / fs->csize);\t/* Cluster order from top of the file */\n\tfor (;;) {\n\t\tncl = *tbl++;\t\t\t/* Number of cluters in the fragment */\n\t\tif (ncl == 0) return 0;\t/* End of table? (error) */\n\t\tif (cl < ncl) break;\t/* In this fragment? */\n\t\tcl -= ncl; tbl++;\t\t/* Next fragment */\n\t}\n\treturn cl + *tbl;\t/* Return the cluster number */\n}\n\n#endif\t/* FF_USE_FASTSEEK */\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Directory handling - Fill a cluster with zeros                        */\n/*-----------------------------------------------------------------------*/\n\n#if !FF_FS_READONLY\nstatic FRESULT dir_clear (\t/* Returns FR_OK or FR_DISK_ERR */\n\tFATFS *fs,\t\t/* Filesystem object */\n\tDWORD clst\t\t/* Directory table to clear */\n)\n{\n\tDWORD sect;\n\tUINT n, szb;\n\tBYTE *ibuf;\n\n\n\tif (sync_window(fs) != FR_OK) return FR_DISK_ERR;\t/* Flush disk access window */\n\tsect = clst2sect(fs, clst);\t\t/* Top of the cluster */\n\tfs->winsect = sect;\t\t\t\t/* Set window to top of the cluster */\n\tmem_set(fs->win, 0, sizeof fs->win);\t/* Clear window buffer */\n#if FF_USE_LFN == 3\t\t/* Quick table clear by using multi-secter write */\n\t/* Allocate a temporary buffer */\n\tfor (szb = ((DWORD)fs->csize * SS(fs) >= MAX_MALLOC) ? MAX_MALLOC : fs->csize * SS(fs), ibuf = 0; szb > SS(fs) && (ibuf = ff_memalloc(szb)) == 0; szb /= 2) ;\n\tif (szb > SS(fs)) {\t\t/* Buffer allocated? */\n\t\tmem_set(ibuf, 0, szb);\n\t\tszb /= SS(fs);\t\t/* Bytes -> Sectors */\n\t\tfor (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ;\t/* Fill the cluster with 0 */\n\t\tff_memfree(ibuf);\n\t} else\n#endif\n\t{\n\t\tibuf = fs->win; szb = 1;\t/* Use window buffer (many single-sector writes may take a time) */\n\t\tfor (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ;\t/* Fill the cluster with 0 */\n\t}\n\treturn (n == fs->csize) ? FR_OK : FR_DISK_ERR;\n}\n#endif\t/* !FF_FS_READONLY */\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Directory handling - Set directory index                              */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT dir_sdi (\t/* FR_OK(0):succeeded, !=0:error */\n\tDIR* dp,\t\t/* Pointer to directory object */\n\tDWORD ofs\t\t/* Offset of directory table */\n)\n{\n\tDWORD csz, clst;\n\tFATFS *fs = dp->obj.fs;\n\n\n\tif (ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR) || ofs % SZDIRE) {\t/* Check range of offset and alignment */\n\t\treturn FR_INT_ERR;\n\t}\n\tdp->dptr = ofs;\t\t\t\t/* Set current offset */\n\tclst = dp->obj.sclust;\t\t/* Table start cluster (0:root) */\n\tif (clst == 0 && fs->fs_type >= FS_FAT32) {\t/* Replace cluster# 0 with root cluster# */\n\t\tclst = fs->dirbase;\n\t\tif (FF_FS_EXFAT) dp->obj.stat = 0;\t/* exFAT: Root dir has an FAT chain */\n\t}\n\n\tif (clst == 0) {\t/* Static table (root-directory on the FAT volume) */\n\t\tif (ofs / SZDIRE >= fs->n_rootdir) return FR_INT_ERR;\t/* Is index out of range? */\n\t\tdp->sect = fs->dirbase;\n\n\t} else {\t\t\t/* Dynamic table (sub-directory or root-directory on the FAT32/exFAT volume) */\n\t\tcsz = (DWORD)fs->csize * SS(fs);\t/* Bytes per cluster */\n\t\twhile (ofs >= csz) {\t\t\t\t/* Follow cluster chain */\n\t\t\tclst = get_fat(&dp->obj, clst);\t\t\t\t/* Get next cluster */\n\t\t\tif (clst == 0xFFFFFFFF) return FR_DISK_ERR;\t/* Disk error */\n\t\t\tif (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR;\t/* Reached to end of table or internal error */\n\t\t\tofs -= csz;\n\t\t}\n\t\tdp->sect = clst2sect(fs, clst);\n\t}\n\tdp->clust = clst;\t\t\t\t\t/* Current cluster# */\n\tif (dp->sect == 0) return FR_INT_ERR;\n\tdp->sect += ofs / SS(fs);\t\t\t/* Sector# of the directory entry */\n\tdp->dir = fs->win + (ofs % SS(fs));\t/* Pointer to the entry in the win[] */\n\n\treturn FR_OK;\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Directory handling - Move directory table index next                  */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT dir_next (\t/* FR_OK(0):succeeded, FR_NO_FILE:End of table, FR_DENIED:Could not stretch */\n\tDIR* dp,\t\t\t\t/* Pointer to the directory object */\n\tint stretch\t\t\t\t/* 0: Do not stretch table, 1: Stretch table if needed */\n)\n{\n\tDWORD ofs, clst;\n\tFATFS *fs = dp->obj.fs;\n\n\n\tofs = dp->dptr + SZDIRE;\t/* Next entry */\n\tif (ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR)) dp->sect = 0;\t/* Disable it if the offset reached the max value */\n\tif (dp->sect == 0) return FR_NO_FILE;\t/* Report EOT if it has been disabled */\n\n\tif (ofs % SS(fs) == 0) {\t/* Sector changed? */\n\t\tdp->sect++;\t\t\t\t/* Next sector */\n\n\t\tif (dp->clust == 0) {\t/* Static table */\n\t\t\tif (ofs / SZDIRE >= fs->n_rootdir) {\t/* Report EOT if it reached end of static table */\n\t\t\t\tdp->sect = 0; return FR_NO_FILE;\n\t\t\t}\n\t\t}\n\t\telse {\t\t\t\t\t/* Dynamic table */\n\t\t\tif ((ofs / SS(fs) & (fs->csize - 1)) == 0) {\t/* Cluster changed? */\n\t\t\t\tclst = get_fat(&dp->obj, dp->clust);\t\t/* Get next cluster */\n\t\t\t\tif (clst <= 1) return FR_INT_ERR;\t\t\t/* Internal error */\n\t\t\t\tif (clst == 0xFFFFFFFF) return FR_DISK_ERR;\t/* Disk error */\n\t\t\t\tif (clst >= fs->n_fatent) {\t\t\t\t\t/* It reached end of dynamic table */\n#if !FF_FS_READONLY\n\t\t\t\t\tif (!stretch) {\t\t\t\t\t\t\t\t/* If no stretch, report EOT */\n\t\t\t\t\t\tdp->sect = 0; return FR_NO_FILE;\n\t\t\t\t\t}\n\t\t\t\t\tclst = create_chain(&dp->obj, dp->clust);\t/* Allocate a cluster */\n\t\t\t\t\tif (clst == 0) return FR_DENIED;\t\t\t/* No free cluster */\n\t\t\t\t\tif (clst == 1) return FR_INT_ERR;\t\t\t/* Internal error */\n\t\t\t\t\tif (clst == 0xFFFFFFFF) return FR_DISK_ERR;\t/* Disk error */\n\t\t\t\t\tif (dir_clear(fs, clst) != FR_OK) return FR_DISK_ERR;\t/* Clean up the stretched table */\n\t\t\t\t\tif (FF_FS_EXFAT) dp->obj.stat |= 4;\t\t\t/* exFAT: The directory has been stretched */\n#else\n\t\t\t\t\tif (!stretch) dp->sect = 0;\t\t\t\t\t/* (this line is to suppress compiler warning) */\n\t\t\t\t\tdp->sect = 0; return FR_NO_FILE;\t\t\t/* Report EOT */\n#endif\n\t\t\t\t}\n\t\t\t\tdp->clust = clst;\t\t/* Initialize data for new cluster */\n\t\t\t\tdp->sect = clst2sect(fs, clst);\n\t\t\t}\n\t\t}\n\t}\n\tdp->dptr = ofs;\t\t\t\t\t\t/* Current entry */\n\tdp->dir = fs->win + ofs % SS(fs);\t/* Pointer to the entry in the win[] */\n\n\treturn FR_OK;\n}\n\n\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Directory handling - Reserve a block of directory entries             */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT dir_alloc (\t/* FR_OK(0):succeeded, !=0:error */\n\tDIR* dp,\t\t\t\t/* Pointer to the directory object */\n\tUINT nent\t\t\t\t/* Number of contiguous entries to allocate */\n)\n{\n\tFRESULT res;\n\tUINT n;\n\tFATFS *fs = dp->obj.fs;\n\n\n\tres = dir_sdi(dp, 0);\n\tif (res == FR_OK) {\n\t\tn = 0;\n\t\tdo {\n\t\t\tres = move_window(fs, dp->sect);\n\t\t\tif (res != FR_OK) break;\n#if FF_FS_EXFAT\n\t\t\tif ((fs->fs_type == FS_EXFAT) ? (int)((dp->dir[XDIR_Type] & 0x80) == 0) : (int)(dp->dir[DIR_Name] == DDEM || dp->dir[DIR_Name] == 0)) {\n#else\n\t\t\tif (dp->dir[DIR_Name] == DDEM || dp->dir[DIR_Name] == 0) {\n#endif\n\t\t\t\tif (++n == nent) break;\t/* A block of contiguous free entries is found */\n\t\t\t} else {\n\t\t\t\tn = 0;\t\t\t\t\t/* Not a blank entry. Restart to search */\n\t\t\t}\n\t\t\tres = dir_next(dp, 1);\n\t\t} while (res == FR_OK);\t/* Next entry with table stretch enabled */\n\t}\n\n\tif (res == FR_NO_FILE) res = FR_DENIED;\t/* No directory entry to allocate */\n\treturn res;\n}\n\n#endif\t/* !FF_FS_READONLY */\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* FAT: Directory handling - Load/Store start cluster number             */\n/*-----------------------------------------------------------------------*/\n\nstatic DWORD ld_clust (\t/* Returns the top cluster value of the SFN entry */\n\tFATFS* fs,\t\t\t/* Pointer to the fs object */\n\tconst BYTE* dir\t\t/* Pointer to the key entry */\n)\n{\n\tDWORD cl;\n\n\tcl = ld_word(dir + DIR_FstClusLO);\n\tif (fs->fs_type == FS_FAT32) {\n\t\tcl |= (DWORD)ld_word(dir + DIR_FstClusHI) << 16;\n\t}\n\n\treturn cl;\n}\n\n\n#if !FF_FS_READONLY\nstatic void st_clust (\n\tFATFS* fs,\t/* Pointer to the fs object */\n\tBYTE* dir,\t/* Pointer to the key entry */\n\tDWORD cl\t/* Value to be set */\n)\n{\n\tst_word(dir + DIR_FstClusLO, (WORD)cl);\n\tif (fs->fs_type == FS_FAT32) {\n\t\tst_word(dir + DIR_FstClusHI, (WORD)(cl >> 16));\n\t}\n}\n#endif\n\n\n\n#if FF_USE_LFN\n/*--------------------------------------------------------*/\n/* FAT-LFN: Compare a part of file name with an LFN entry */\n/*--------------------------------------------------------*/\n\nstatic int cmp_lfn (\t\t/* 1:matched, 0:not matched */\n\tconst WCHAR* lfnbuf,\t/* Pointer to the LFN working buffer to be compared */\n\tBYTE* dir\t\t\t\t/* Pointer to the directory entry containing the part of LFN */\n)\n{\n\tUINT i, s;\n\tWCHAR wc, uc;\n\n\n\tif (ld_word(dir + LDIR_FstClusLO) != 0) return 0;\t/* Check LDIR_FstClusLO */\n\n\ti = ((dir[LDIR_Ord] & 0x3F) - 1) * 13;\t/* Offset in the LFN buffer */\n\n\tfor (wc = 1, s = 0; s < 13; s++) {\t\t/* Process all characters in the entry */\n\t\tuc = ld_word(dir + LfnOfs[s]);\t\t/* Pick an LFN character */\n\t\tif (wc != 0) {\n\t\t\tif (i >= FF_MAX_LFN + 1 || ff_wtoupper(uc) != ff_wtoupper(lfnbuf[i++])) {\t/* Compare it */\n\t\t\t\treturn 0;\t\t\t\t\t/* Not matched */\n\t\t\t}\n\t\t\twc = uc;\n\t\t} else {\n\t\t\tif (uc != 0xFFFF) return 0;\t\t/* Check filler */\n\t\t}\n\t}\n\n\tif ((dir[LDIR_Ord] & LLEF) && wc && lfnbuf[i]) return 0;\t/* Last segment matched but different length */\n\n\treturn 1;\t\t/* The part of LFN matched */\n}\n\n\n#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 || FF_USE_LABEL || FF_FS_EXFAT\n/*-----------------------------------------------------*/\n/* FAT-LFN: Pick a part of file name from an LFN entry */\n/*-----------------------------------------------------*/\n\nstatic int pick_lfn (\t/* 1:succeeded, 0:buffer overflow or invalid LFN entry */\n\tWCHAR* lfnbuf,\t\t/* Pointer to the LFN working buffer */\n\tBYTE* dir\t\t\t/* Pointer to the LFN entry */\n)\n{\n\tUINT i, s;\n\tWCHAR wc, uc;\n\n\n\tif (ld_word(dir + LDIR_FstClusLO) != 0) return 0;\t/* Check LDIR_FstClusLO is 0 */\n\n\ti = ((dir[LDIR_Ord] & ~LLEF) - 1) * 13;\t/* Offset in the LFN buffer */\n\n\tfor (wc = 1, s = 0; s < 13; s++) {\t\t/* Process all characters in the entry */\n\t\tuc = ld_word(dir + LfnOfs[s]);\t\t/* Pick an LFN character */\n\t\tif (wc != 0) {\n\t\t\tif (i >= FF_MAX_LFN + 1) return 0;\t/* Buffer overflow? */\n\t\t\tlfnbuf[i++] = wc = uc;\t\t\t/* Store it */\n\t\t} else {\n\t\t\tif (uc != 0xFFFF) return 0;\t\t/* Check filler */\n\t\t}\n\t}\n\n\tif (dir[LDIR_Ord] & LLEF && wc != 0) {\t/* Put terminator if it is the last LFN part and not terminated */\n\t\tif (i >= FF_MAX_LFN + 1) return 0;\t/* Buffer overflow? */\n\t\tlfnbuf[i] = 0;\n\t}\n\n\treturn 1;\t\t/* The part of LFN is valid */\n}\n#endif\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------*/\n/* FAT-LFN: Create an entry of LFN entries */\n/*-----------------------------------------*/\n\nstatic void put_lfn (\n\tconst WCHAR* lfn,\t/* Pointer to the LFN */\n\tBYTE* dir,\t\t\t/* Pointer to the LFN entry to be created */\n\tBYTE ord,\t\t\t/* LFN order (1-20) */\n\tBYTE sum\t\t\t/* Checksum of the corresponding SFN */\n)\n{\n\tUINT i, s;\n\tWCHAR wc;\n\n\n\tdir[LDIR_Chksum] = sum;\t\t\t/* Set checksum */\n\tdir[LDIR_Attr] = AM_LFN;\t\t/* Set attribute. LFN entry */\n\tdir[LDIR_Type] = 0;\n\tst_word(dir + LDIR_FstClusLO, 0);\n\n\ti = (ord - 1) * 13;\t\t\t\t/* Get offset in the LFN working buffer */\n\ts = wc = 0;\n\tdo {\n\t\tif (wc != 0xFFFF) wc = lfn[i++];\t/* Get an effective character */\n\t\tst_word(dir + LfnOfs[s], wc);\t\t/* Put it */\n\t\tif (wc == 0) wc = 0xFFFF;\t\t/* Padding characters for left locations */\n\t} while (++s < 13);\n\tif (wc == 0xFFFF || !lfn[i]) ord |= LLEF;\t/* Last LFN part is the start of LFN sequence */\n\tdir[LDIR_Ord] = ord;\t\t\t/* Set the LFN order */\n}\n\n#endif\t/* !FF_FS_READONLY */\n#endif\t/* FF_USE_LFN */\n\n\n\n#if FF_USE_LFN && !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* FAT-LFN: Create a Numbered SFN                                        */\n/*-----------------------------------------------------------------------*/\n\nstatic void gen_numname (\n\tBYTE* dst,\t\t\t/* Pointer to the buffer to store numbered SFN */\n\tconst BYTE* src,\t/* Pointer to SFN */\n\tconst WCHAR* lfn,\t/* Pointer to LFN */\n\tUINT seq\t\t\t/* Sequence number */\n)\n{\n\tBYTE ns[8], c;\n\tUINT i, j;\n\tWCHAR wc;\n\tDWORD sr;\n\n\n\tmem_cpy(dst, src, 11);\n\n\tif (seq > 5) {\t/* In case of many collisions, generate a hash number instead of sequential number */\n\t\tsr = seq;\n\t\twhile (*lfn) {\t/* Create a CRC as hash value */\n\t\t\twc = *lfn++;\n\t\t\tfor (i = 0; i < 16; i++) {\n\t\t\t\tsr = (sr << 1) + (wc & 1);\n\t\t\t\twc >>= 1;\n\t\t\t\tif (sr & 0x10000) sr ^= 0x11021;\n\t\t\t}\n\t\t}\n\t\tseq = (UINT)sr;\n\t}\n\n\t/* itoa (hexdecimal) */\n\ti = 7;\n\tdo {\n\t\tc = (BYTE)((seq % 16) + '0');\n\t\tif (c > '9') c += 7;\n\t\tns[i--] = c;\n\t\tseq /= 16;\n\t} while (seq);\n\tns[i] = '~';\n\n\t/* Append the number to the SFN body */\n\tfor (j = 0; j < i && dst[j] != ' '; j++) {\n\t\tif (dbc_1st(dst[j])) {\n\t\t\tif (j == i - 1) break;\n\t\t\tj++;\n\t\t}\n\t}\n\tdo {\n\t\tdst[j++] = (i < 8) ? ns[i++] : ' ';\n\t} while (j < 8);\n}\n#endif\t/* FF_USE_LFN && !FF_FS_READONLY */\n\n\n\n#if FF_USE_LFN\n/*-----------------------------------------------------------------------*/\n/* FAT-LFN: Calculate checksum of an SFN entry                           */\n/*-----------------------------------------------------------------------*/\n\nstatic BYTE sum_sfn (\n\tconst BYTE* dir\t\t/* Pointer to the SFN entry */\n)\n{\n\tBYTE sum = 0;\n\tUINT n = 11;\n\n\tdo {\n\t\tsum = (sum >> 1) + (sum << 7) + *dir++;\n\t} while (--n);\n\treturn sum;\n}\n\n#endif\t/* FF_USE_LFN */\n\n\n\n#if FF_FS_EXFAT\n/*-----------------------------------------------------------------------*/\n/* exFAT: Checksum                                                       */\n/*-----------------------------------------------------------------------*/\n\nstatic WORD xdir_sum (\t/* Get checksum of the directoly entry block */\n\tconst BYTE* dir\t\t/* Directory entry block to be calculated */\n)\n{\n\tUINT i, szblk;\n\tWORD sum;\n\n\n\tszblk = (dir[XDIR_NumSec] + 1) * SZDIRE;\t/* Number of bytes of the entry block */\n\tfor (i = sum = 0; i < szblk; i++) {\n\t\tif (i == XDIR_SetSum) {\t/* Skip 2-byte sum field */\n\t\t\ti++;\n\t\t} else {\n\t\t\tsum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + dir[i];\n\t\t}\n\t}\n\treturn sum;\n}\n\n\n\nstatic WORD xname_sum (\t/* Get check sum (to be used as hash) of the file name */\n\tconst WCHAR* name\t/* File name to be calculated */\n)\n{\n\tWCHAR chr;\n\tWORD sum = 0;\n\n\n\twhile ((chr = *name++) != 0) {\n\t\tchr = (WCHAR)ff_wtoupper(chr);\t\t/* File name needs to be up-case converted */\n\t\tsum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + (chr & 0xFF);\n\t\tsum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + (chr >> 8);\n\t}\n\treturn sum;\n}\n\n\n#if !FF_FS_READONLY && FF_USE_MKFS\nstatic DWORD xsum32 (\t/* Returns 32-bit checksum */\n\tBYTE  dat,\t\t\t/* Byte to be calculated (byte-by-byte processing) */\n\tDWORD sum\t\t\t/* Previous sum value */\n)\n{\n\tsum = ((sum & 1) ? 0x80000000 : 0) + (sum >> 1) + dat;\n\treturn sum;\n}\n#endif\n\n\n#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2\n/*------------------------------------------------------*/\n/* exFAT: Get object information from a directory block */\n/*------------------------------------------------------*/\n\nstatic void get_xfileinfo (\n\tBYTE* dirb,\t\t\t/* Pointer to the direcotry entry block 85+C0+C1s */\n\tFILINFO* fno\t\t/* Buffer to store the extracted file information */\n)\n{\n\tWCHAR wc, hs;\n\tUINT di, si, nc;\n\n\t/* Get file name from the entry block */\n\tsi = SZDIRE * 2;\t/* 1st C1 entry */\n\tnc = 0; hs = 0; di = 0;\n\twhile (nc < dirb[XDIR_NumName]) {\n\t\tif (si >= MAXDIRB(FF_MAX_LFN)) { di = 0; break; }\t/* Truncated directory block? */\n\t\tif ((si % SZDIRE) == 0) si += 2;\t\t/* Skip entry type field */\n\t\twc = ld_word(dirb + si); si += 2; nc++;\t/* Get a character */\n\t\tif (hs == 0 && IsSurrogate(wc)) {\t/* Is it a surrogate? */\n\t\t\ths = wc; continue;\t/* Get low surrogate */\n\t\t}\n\t\twc = put_utf((DWORD)hs << 16 | wc, &fno->fname[di], FF_LFN_BUF - di);\t/* Store it in API encoding */\n\t\tif (wc == 0) { di = 0; break; }\t/* Buffer overflow or wrong encoding? */\n\t\tdi += wc;\n\t\ths = 0;\n\t}\n\tif (hs != 0) di = 0;\t\t\t\t\t/* Broken surrogate pair? */\n\tif (di == 0) fno->fname[di++] = '?';\t/* Inaccessible object name? */\n\tfno->fname[di] = 0;\t\t\t\t\t\t/* Terminate the name */\n\tfno->altname[0] = 0;\t\t\t\t\t/* exFAT does not support SFN */\n\n\tfno->fattrib = dirb[XDIR_Attr];\t\t\t/* Attribute */\n\tfno->fsize = (fno->fattrib & AM_DIR) ? 0 : ld_qword(dirb + XDIR_FileSize);\t/* Size */\n\tfno->ftime = ld_word(dirb + XDIR_ModTime + 0);\t/* Time */\n\tfno->fdate = ld_word(dirb + XDIR_ModTime + 2);\t/* Date */\n}\n\n#endif\t/* FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 */\n\n\n/*-----------------------------------*/\n/* exFAT: Get a directry entry block */\n/*-----------------------------------*/\n\nstatic FRESULT load_xdir (\t/* FR_INT_ERR: invalid entry block */\n\tDIR* dp\t\t\t\t\t/* Reading direcotry object pointing top of the entry block to load */\n)\n{\n\tFRESULT res;\n\tUINT i, sz_ent;\n\tBYTE* dirb = dp->obj.fs->dirbuf;\t/* Pointer to the on-memory direcotry entry block 85+C0+C1s */\n\n\n\t/* Load file-directory entry */\n\tres = move_window(dp->obj.fs, dp->sect);\n\tif (res != FR_OK) return res;\n\tif (dp->dir[XDIR_Type] != ET_FILEDIR) return FR_INT_ERR;\t/* Invalid order */\n\tmem_cpy(dirb + 0 * SZDIRE, dp->dir, SZDIRE);\n\tsz_ent = (dirb[XDIR_NumSec] + 1) * SZDIRE;\n\tif (sz_ent < 3 * SZDIRE || sz_ent > 19 * SZDIRE) return FR_INT_ERR;\n\n\t/* Load stream-extension entry */\n\tres = dir_next(dp, 0);\n\tif (res == FR_NO_FILE) res = FR_INT_ERR;\t/* It cannot be */\n\tif (res != FR_OK) return res;\n\tres = move_window(dp->obj.fs, dp->sect);\n\tif (res != FR_OK) return res;\n\tif (dp->dir[XDIR_Type] != ET_STREAM) return FR_INT_ERR;\t/* Invalid order */\n\tmem_cpy(dirb + 1 * SZDIRE, dp->dir, SZDIRE);\n\tif (MAXDIRB(dirb[XDIR_NumName]) > sz_ent) return FR_INT_ERR;\n\n\t/* Load file-name entries */\n\ti = 2 * SZDIRE;\t/* Name offset to load */\n\tdo {\n\t\tres = dir_next(dp, 0);\n\t\tif (res == FR_NO_FILE) res = FR_INT_ERR;\t/* It cannot be */\n\t\tif (res != FR_OK) return res;\n\t\tres = move_window(dp->obj.fs, dp->sect);\n\t\tif (res != FR_OK) return res;\n\t\tif (dp->dir[XDIR_Type] != ET_FILENAME) return FR_INT_ERR;\t/* Invalid order */\n\t\tif (i < MAXDIRB(FF_MAX_LFN)) mem_cpy(dirb + i, dp->dir, SZDIRE);\n\t} while ((i += SZDIRE) < sz_ent);\n\n\t/* Sanity check (do it for only accessible object) */\n\tif (i <= MAXDIRB(FF_MAX_LFN)) {\n\t\tif (xdir_sum(dirb) != ld_word(dirb + XDIR_SetSum)) return FR_INT_ERR;\n\t}\n\treturn FR_OK;\n}\n\n\n/*------------------------------------------------------------------*/\n/* exFAT: Initialize object allocation info with loaded entry block */\n/*------------------------------------------------------------------*/\n\nstatic void init_alloc_info (\n\tFATFS* fs,\t\t/* Filesystem object */\n\tFFOBJID* obj\t/* Object allocation information to be initialized */\n)\n{\n\tobj->sclust = ld_dword(fs->dirbuf + XDIR_FstClus);\t\t/* Start cluster */\n\tobj->objsize = ld_qword(fs->dirbuf + XDIR_FileSize);\t/* Size */\n\tobj->stat = fs->dirbuf[XDIR_GenFlags] & 2;\t\t\t\t/* Allocation status */\n\tobj->n_frag = 0;\t\t\t\t\t\t\t\t\t\t/* No last fragment info */\n}\n\n\n\n#if !FF_FS_READONLY || FF_FS_RPATH != 0\n/*------------------------------------------------*/\n/* exFAT: Load the object's directory entry block */\n/*------------------------------------------------*/\n\nstatic FRESULT load_obj_xdir (\n\tDIR* dp,\t\t\t/* Blank directory object to be used to access containing direcotry */\n\tconst FFOBJID* obj\t/* Object with its containing directory information */\n)\n{\n\tFRESULT res;\n\n\t/* Open object containing directory */\n\tdp->obj.fs = obj->fs;\n\tdp->obj.sclust = obj->c_scl;\n\tdp->obj.stat = (BYTE)obj->c_size;\n\tdp->obj.objsize = obj->c_size & 0xFFFFFF00;\n\tdp->obj.n_frag = 0;\n\tdp->blk_ofs = obj->c_ofs;\n\n\tres = dir_sdi(dp, dp->blk_ofs);\t/* Goto object's entry block */\n\tif (res == FR_OK) {\n\t\tres = load_xdir(dp);\t\t/* Load the object's entry block */\n\t}\n\treturn res;\n}\n#endif\n\n\n#if !FF_FS_READONLY\n/*----------------------------------------*/\n/* exFAT: Store the directory entry block */\n/*----------------------------------------*/\n\nstatic FRESULT store_xdir (\n\tDIR* dp\t\t\t\t/* Pointer to the direcotry object */\n)\n{\n\tFRESULT res;\n\tUINT nent;\n\tBYTE* dirb = dp->obj.fs->dirbuf;\t/* Pointer to the direcotry entry block 85+C0+C1s */\n\n\t/* Create set sum */\n\tst_word(dirb + XDIR_SetSum, xdir_sum(dirb));\n\tnent = dirb[XDIR_NumSec] + 1;\n\n\t/* Store the direcotry entry block to the directory */\n\tres = dir_sdi(dp, dp->blk_ofs);\n\twhile (res == FR_OK) {\n\t\tres = move_window(dp->obj.fs, dp->sect);\n\t\tif (res != FR_OK) break;\n\t\tmem_cpy(dp->dir, dirb, SZDIRE);\n\t\tdp->obj.fs->wflag = 1;\n\t\tif (--nent == 0) break;\n\t\tdirb += SZDIRE;\n\t\tres = dir_next(dp, 0);\n\t}\n\treturn (res == FR_OK || res == FR_DISK_ERR) ? res : FR_INT_ERR;\n}\n\n\n\n/*-------------------------------------------*/\n/* exFAT: Create a new directory enrty block */\n/*-------------------------------------------*/\n\nstatic void create_xdir (\n\tBYTE* dirb,\t\t\t/* Pointer to the direcotry entry block buffer */\n\tconst WCHAR* lfn\t/* Pointer to the object name */\n)\n{\n\tUINT i;\n\tBYTE nc1, nlen;\n\tWCHAR wc;\n\n\n\t/* Create file-directory and stream-extension entry */\n\tmem_set(dirb, 0, 2 * SZDIRE);\n\tdirb[0 * SZDIRE + XDIR_Type] = ET_FILEDIR;\n\tdirb[1 * SZDIRE + XDIR_Type] = ET_STREAM;\n\n\t/* Create file-name entries */\n\ti = SZDIRE * 2;\t/* Top of file_name entries */\n\tnlen = nc1 = 0; wc = 1;\n\tdo {\n\t\tdirb[i++] = ET_FILENAME; dirb[i++] = 0;\n\t\tdo {\t/* Fill name field */\n\t\t\tif (wc != 0 && (wc = lfn[nlen]) != 0) nlen++;\t/* Get a character if exist */\n\t\t\tst_word(dirb + i, wc); \t\t/* Store it */\n\t\t\ti += 2;\n\t\t} while (i % SZDIRE != 0);\n\t\tnc1++;\n\t} while (lfn[nlen]);\t/* Fill next entry if any char follows */\n\n\tdirb[XDIR_NumName] = nlen;\t\t/* Set name length */\n\tdirb[XDIR_NumSec] = 1 + nc1;\t/* Set secondary count (C0 + C1s) */\n\tst_word(dirb + XDIR_NameHash, xname_sum(lfn));\t/* Set name hash */\n}\n\n#endif\t/* !FF_FS_READONLY */\n#endif\t/* FF_FS_EXFAT */\n\n\n\n#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 || FF_USE_LABEL || FF_FS_EXFAT\n/*-----------------------------------------------------------------------*/\n/* Read an object from the directory                                     */\n/*-----------------------------------------------------------------------*/\n\n#define DIR_READ_FILE(dp) dir_read(dp, 0)\n#define DIR_READ_LABEL(dp) dir_read(dp, 1)\n\nstatic FRESULT dir_read (\n\tDIR* dp,\t\t/* Pointer to the directory object */\n\tint vol\t\t\t/* Filtered by 0:file/directory or 1:volume label */\n)\n{\n\tFRESULT res = FR_NO_FILE;\n\tFATFS *fs = dp->obj.fs;\n\tBYTE attr, b;\n#if FF_USE_LFN\n\tBYTE ord = 0xFF, sum = 0xFF;\n#endif\n\n\twhile (dp->sect) {\n\t\tres = move_window(fs, dp->sect);\n\t\tif (res != FR_OK) break;\n\t\tb = dp->dir[DIR_Name];\t/* Test for the entry type */\n\t\tif (b == 0) {\n\t\t\tres = FR_NO_FILE; break; /* Reached to end of the directory */\n\t\t}\n#if FF_FS_EXFAT\n\t\tif (fs->fs_type == FS_EXFAT) {\t/* On the exFAT volume */\n\t\t\tif (FF_USE_LABEL && vol) {\n\t\t\t\tif (b == ET_VLABEL) break;\t/* Volume label entry? */\n\t\t\t} else {\n\t\t\t\tif (b == ET_FILEDIR) {\t\t/* Start of the file entry block? */\n\t\t\t\t\tdp->blk_ofs = dp->dptr;\t/* Get location of the block */\n\t\t\t\t\tres = load_xdir(dp);\t/* Load the entry block */\n\t\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\t\tdp->obj.attr = fs->dirbuf[XDIR_Attr] & AM_MASK;\t/* Get attribute */\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else\n#endif\n\t\t{\t/* On the FAT/FAT32 volume */\n\t\t\tdp->obj.attr = attr = dp->dir[DIR_Attr] & AM_MASK;\t/* Get attribute */\n#if FF_USE_LFN\t\t/* LFN configuration */\n\t\t\tif (b == DDEM || b == '.' || (int)((attr & ~AM_ARC) == AM_VOL) != vol) {\t/* An entry without valid data */\n\t\t\t\tord = 0xFF;\n\t\t\t} else {\n\t\t\t\tif (attr == AM_LFN) {\t\t\t/* An LFN entry is found */\n\t\t\t\t\tif (b & LLEF) {\t\t\t/* Is it start of an LFN sequence? */\n\t\t\t\t\t\tsum = dp->dir[LDIR_Chksum];\n\t\t\t\t\t\tb &= (BYTE)~LLEF; ord = b;\n\t\t\t\t\t\tdp->blk_ofs = dp->dptr;\n\t\t\t\t\t}\n\t\t\t\t\t/* Check LFN validity and capture it */\n\t\t\t\t\tord = (b == ord && sum == dp->dir[LDIR_Chksum] && pick_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF;\n\t\t\t\t} else {\t\t\t\t\t/* An SFN entry is found */\n\t\t\t\t\tif (ord != 0 || sum != sum_sfn(dp->dir)) {\t/* Is there a valid LFN? */\n\t\t\t\t\t\tdp->blk_ofs = 0xFFFFFFFF;\t\t\t/* It has no LFN. */\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n#else\t\t/* Non LFN configuration */\n\t\t\tif (b != DDEM && b != '.' && attr != AM_LFN && (int)((attr & ~AM_ARC) == AM_VOL) == vol) {\t/* Is it a valid entry? */\n\t\t\t\tbreak;\n\t\t\t}\n#endif\n\t\t}\n\t\tres = dir_next(dp, 0);\t\t/* Next entry */\n\t\tif (res != FR_OK) break;\n\t}\n\n\tif (res != FR_OK) dp->sect = 0;\t\t/* Terminate the read operation on error or EOT */\n\treturn res;\n}\n\n#endif\t/* FF_FS_MINIMIZE <= 1 || FF_USE_LABEL || FF_FS_RPATH >= 2 */\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Directory handling - Find an object in the directory                  */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT dir_find (\t/* FR_OK(0):succeeded, !=0:error */\n\tDIR* dp\t\t\t\t\t/* Pointer to the directory object with the file name */\n)\n{\n\tFRESULT res;\n\tFATFS *fs = dp->obj.fs;\n\tBYTE c;\n#if FF_USE_LFN\n\tBYTE a, ord, sum;\n#endif\n\n\tres = dir_sdi(dp, 0);\t\t\t/* Rewind directory object */\n\tif (res != FR_OK) return res;\n#if FF_FS_EXFAT\n\tif (fs->fs_type == FS_EXFAT) {\t/* On the exFAT volume */\n\t\tBYTE nc;\n\t\tUINT di, ni;\n\t\tWORD hash = xname_sum(fs->lfnbuf);\t\t/* Hash value of the name to find */\n\n\t\twhile ((res = DIR_READ_FILE(dp)) == FR_OK) {\t/* Read an item */\n#if FF_MAX_LFN < 255\n\t\t\tif (fs->dirbuf[XDIR_NumName] > FF_MAX_LFN) continue;\t\t\t/* Skip comparison if inaccessible object name */\n#endif\n\t\t\tif (ld_word(fs->dirbuf + XDIR_NameHash) != hash) continue;\t/* Skip comparison if hash mismatched */\n\t\t\tfor (nc = fs->dirbuf[XDIR_NumName], di = SZDIRE * 2, ni = 0; nc; nc--, di += 2, ni++) {\t/* Compare the name */\n\t\t\t\tif ((di % SZDIRE) == 0) di += 2;\n\t\t\t\tif (ff_wtoupper(ld_word(fs->dirbuf + di)) != ff_wtoupper(fs->lfnbuf[ni])) break;\n\t\t\t}\n\t\t\tif (nc == 0 && !fs->lfnbuf[ni]) break;\t/* Name matched? */\n\t\t}\n\t\treturn res;\n\t}\n#endif\n\t/* On the FAT/FAT32 volume */\n#if FF_USE_LFN\n\tord = sum = 0xFF; dp->blk_ofs = 0xFFFFFFFF;\t/* Reset LFN sequence */\n#endif\n\tdo {\n\t\tres = move_window(fs, dp->sect);\n\t\tif (res != FR_OK) break;\n\t\tc = dp->dir[DIR_Name];\n\t\tif (c == 0) { res = FR_NO_FILE; break; }\t/* Reached to end of table */\n#if FF_USE_LFN\t\t/* LFN configuration */\n\t\tdp->obj.attr = a = dp->dir[DIR_Attr] & AM_MASK;\n\t\tif (c == DDEM || ((a & AM_VOL) && a != AM_LFN)) {\t/* An entry without valid data */\n\t\t\tord = 0xFF; dp->blk_ofs = 0xFFFFFFFF;\t/* Reset LFN sequence */\n\t\t} else {\n\t\t\tif (a == AM_LFN) {\t\t\t/* An LFN entry is found */\n\t\t\t\tif (!(dp->fn[NSFLAG] & NS_NOLFN)) {\n\t\t\t\t\tif (c & LLEF) {\t\t/* Is it start of LFN sequence? */\n\t\t\t\t\t\tsum = dp->dir[LDIR_Chksum];\n\t\t\t\t\t\tc &= (BYTE)~LLEF; ord = c;\t/* LFN start order */\n\t\t\t\t\t\tdp->blk_ofs = dp->dptr;\t/* Start offset of LFN */\n\t\t\t\t\t}\n\t\t\t\t\t/* Check validity of the LFN entry and compare it with given name */\n\t\t\t\t\tord = (c == ord && sum == dp->dir[LDIR_Chksum] && cmp_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF;\n\t\t\t\t}\n\t\t\t} else {\t\t\t\t\t/* An SFN entry is found */\n\t\t\t\tif (ord == 0 && sum == sum_sfn(dp->dir)) break;\t/* LFN matched? */\n\t\t\t\tif (!(dp->fn[NSFLAG] & NS_LOSS) && !mem_cmp(dp->dir, dp->fn, 11)) break;\t/* SFN matched? */\n\t\t\t\tord = 0xFF; dp->blk_ofs = 0xFFFFFFFF;\t/* Reset LFN sequence */\n\t\t\t}\n\t\t}\n#else\t\t/* Non LFN configuration */\n\t\tdp->obj.attr = dp->dir[DIR_Attr] & AM_MASK;\n\t\tif (!(dp->dir[DIR_Attr] & AM_VOL) && !mem_cmp(dp->dir, dp->fn, 11)) break;\t/* Is it a valid entry? */\n#endif\n\t\tres = dir_next(dp, 0);\t/* Next entry */\n\t} while (res == FR_OK);\n\n\treturn res;\n}\n\n\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Register an object to the directory                                   */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT dir_register (\t/* FR_OK:succeeded, FR_DENIED:no free entry or too many SFN collision, FR_DISK_ERR:disk error */\n\tDIR* dp\t\t\t\t\t\t/* Target directory with object name to be created */\n)\n{\n\tFRESULT res;\n\tFATFS *fs = dp->obj.fs;\n#if FF_USE_LFN\t\t/* LFN configuration */\n\tUINT n, nlen, nent;\n\tBYTE sn[12], sum;\n\n\n\tif (dp->fn[NSFLAG] & (NS_DOT | NS_NONAME)) return FR_INVALID_NAME;\t/* Check name validity */\n\tfor (nlen = 0; fs->lfnbuf[nlen]; nlen++) ;\t/* Get lfn length */\n\n#if FF_FS_EXFAT\n\tif (fs->fs_type == FS_EXFAT) {\t/* On the exFAT volume */\n\t\tnent = (nlen + 14) / 15 + 2;\t/* Number of entries to allocate (85+C0+C1s) */\n\t\tres = dir_alloc(dp, nent);\t\t/* Allocate directory entries */\n\t\tif (res != FR_OK) return res;\n\t\tdp->blk_ofs = dp->dptr - SZDIRE * (nent - 1);\t/* Set the allocated entry block offset */\n\n\t\tif (dp->obj.stat & 4) {\t\t\t/* Has the directory been stretched by new allocation? */\n\t\t\tdp->obj.stat &= ~4;\n\t\t\tres = fill_first_frag(&dp->obj);\t/* Fill the first fragment on the FAT if needed */\n\t\t\tif (res != FR_OK) return res;\n\t\t\tres = fill_last_frag(&dp->obj, dp->clust, 0xFFFFFFFF);\t/* Fill the last fragment on the FAT if needed */\n\t\t\tif (res != FR_OK) return res;\n\t\t\tif (dp->obj.sclust != 0) {\t\t/* Is it a sub-directory? */\n\t\t\t\tDIR dj;\n\n\t\t\t\tres = load_obj_xdir(&dj, &dp->obj);\t/* Load the object status */\n\t\t\t\tif (res != FR_OK) return res;\n\t\t\t\tdp->obj.objsize += (DWORD)fs->csize * SS(fs);\t\t\t/* Increase the directory size by cluster size */\n\t\t\t\tst_qword(fs->dirbuf + XDIR_FileSize, dp->obj.objsize);\t/* Update the allocation status */\n\t\t\t\tst_qword(fs->dirbuf + XDIR_ValidFileSize, dp->obj.objsize);\n\t\t\t\tfs->dirbuf[XDIR_GenFlags] = dp->obj.stat | 1;\n\t\t\t\tres = store_xdir(&dj);\t\t\t\t/* Store the object status */\n\t\t\t\tif (res != FR_OK) return res;\n\t\t\t}\n\t\t}\n\n\t\tcreate_xdir(fs->dirbuf, fs->lfnbuf);\t/* Create on-memory directory block to be written later */\n\t\treturn FR_OK;\n\t}\n#endif\n\t/* On the FAT/FAT32 volume */\n\tmem_cpy(sn, dp->fn, 12);\n\tif (sn[NSFLAG] & NS_LOSS) {\t\t\t/* When LFN is out of 8.3 format, generate a numbered name */\n\t\tdp->fn[NSFLAG] = NS_NOLFN;\t\t/* Find only SFN */\n\t\tfor (n = 1; n < 100; n++) {\n\t\t\tgen_numname(dp->fn, sn, fs->lfnbuf, n);\t/* Generate a numbered name */\n\t\t\tres = dir_find(dp);\t\t\t\t/* Check if the name collides with existing SFN */\n\t\t\tif (res != FR_OK) break;\n\t\t}\n\t\tif (n == 100) return FR_DENIED;\t\t/* Abort if too many collisions */\n\t\tif (res != FR_NO_FILE) return res;\t/* Abort if the result is other than 'not collided' */\n\t\tdp->fn[NSFLAG] = sn[NSFLAG];\n\t}\n\n\t/* Create an SFN with/without LFNs. */\n\tnent = (sn[NSFLAG] & NS_LFN) ? (nlen + 12) / 13 + 1 : 1;\t/* Number of entries to allocate */\n\tres = dir_alloc(dp, nent);\t\t/* Allocate entries */\n\tif (res == FR_OK && --nent) {\t/* Set LFN entry if needed */\n\t\tres = dir_sdi(dp, dp->dptr - nent * SZDIRE);\n\t\tif (res == FR_OK) {\n\t\t\tsum = sum_sfn(dp->fn);\t/* Checksum value of the SFN tied to the LFN */\n\t\t\tdo {\t\t\t\t\t/* Store LFN entries in bottom first */\n\t\t\t\tres = move_window(fs, dp->sect);\n\t\t\t\tif (res != FR_OK) break;\n\t\t\t\tput_lfn(fs->lfnbuf, dp->dir, (BYTE)nent, sum);\n\t\t\t\tfs->wflag = 1;\n\t\t\t\tres = dir_next(dp, 0);\t/* Next entry */\n\t\t\t} while (res == FR_OK && --nent);\n\t\t}\n\t}\n\n#else\t/* Non LFN configuration */\n\tres = dir_alloc(dp, 1);\t\t/* Allocate an entry for SFN */\n\n#endif\n\n\t/* Set SFN entry */\n\tif (res == FR_OK) {\n\t\tres = move_window(fs, dp->sect);\n\t\tif (res == FR_OK) {\n\t\t\tmem_set(dp->dir, 0, SZDIRE);\t/* Clean the entry */\n\t\t\tmem_cpy(dp->dir + DIR_Name, dp->fn, 11);\t/* Put SFN */\n#if FF_USE_LFN\n\t\t\tdp->dir[DIR_NTres] = dp->fn[NSFLAG] & (NS_BODY | NS_EXT);\t/* Put NT flag */\n#endif\n\t\t\tfs->wflag = 1;\n\t\t}\n\t}\n\n\treturn res;\n}\n\n#endif /* !FF_FS_READONLY */\n\n\n\n#if !FF_FS_READONLY && FF_FS_MINIMIZE == 0\n/*-----------------------------------------------------------------------*/\n/* Remove an object from the directory                                   */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT dir_remove (\t/* FR_OK:Succeeded, FR_DISK_ERR:A disk error */\n\tDIR* dp\t\t\t\t\t/* Directory object pointing the entry to be removed */\n)\n{\n\tFRESULT res;\n\tFATFS *fs = dp->obj.fs;\n#if FF_USE_LFN\t\t/* LFN configuration */\n\tDWORD last = dp->dptr;\n\n\tres = (dp->blk_ofs == 0xFFFFFFFF) ? FR_OK : dir_sdi(dp, dp->blk_ofs);\t/* Goto top of the entry block if LFN is exist */\n\tif (res == FR_OK) {\n\t\tdo {\n\t\t\tres = move_window(fs, dp->sect);\n\t\t\tif (res != FR_OK) break;\n\t\t\tif (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) {\t/* On the exFAT volume */\n\t\t\t\tdp->dir[XDIR_Type] &= 0x7F;\t/* Clear the entry InUse flag. */\n\t\t\t} else {\t\t\t\t\t\t\t\t\t/* On the FAT/FAT32 volume */\n\t\t\t\tdp->dir[DIR_Name] = DDEM;\t/* Mark the entry 'deleted'. */\n\t\t\t}\n\t\t\tfs->wflag = 1;\n\t\t\tif (dp->dptr >= last) break;\t/* If reached last entry then all entries of the object has been deleted. */\n\t\t\tres = dir_next(dp, 0);\t/* Next entry */\n\t\t} while (res == FR_OK);\n\t\tif (res == FR_NO_FILE) res = FR_INT_ERR;\n\t}\n#else\t\t\t/* Non LFN configuration */\n\n\tres = move_window(fs, dp->sect);\n\tif (res == FR_OK) {\n\t\tdp->dir[DIR_Name] = DDEM;\t/* Mark the entry 'deleted'.*/\n\t\tfs->wflag = 1;\n\t}\n#endif\n\n\treturn res;\n}\n\n#endif /* !FF_FS_READONLY && FF_FS_MINIMIZE == 0 */\n\n\n\n#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2\n/*-----------------------------------------------------------------------*/\n/* Get file information from directory entry                             */\n/*-----------------------------------------------------------------------*/\n\nstatic void get_fileinfo (\n\tDIR* dp,\t\t\t/* Pointer to the directory object */\n\tFILINFO* fno\t\t/* Pointer to the file information to be filled */\n)\n{\n\tUINT si, di;\n#if FF_USE_LFN\n\tBYTE lcf;\n\tWCHAR wc, hs;\n\tFATFS *fs = dp->obj.fs;\n#else\n\tTCHAR c;\n#endif\n\n\n\tfno->fname[0] = 0;\t\t\t/* Invaidate file info */\n\tif (dp->sect == 0) return;\t/* Exit if read pointer has reached end of directory */\n\n#if FF_USE_LFN\t\t/* LFN configuration */\n#if FF_FS_EXFAT\n\tif (fs->fs_type == FS_EXFAT) {\t/* On the exFAT volume */\n\t\tget_xfileinfo(fs->dirbuf, fno);\n\t\treturn;\n\t} else\n#endif\n\t{\t/* On the FAT/FAT32 volume */\n\t\tif (dp->blk_ofs != 0xFFFFFFFF) {\t/* Get LFN if available */\n\t\t\tsi = di = hs = 0;\n\t\t\twhile (fs->lfnbuf[si] != 0) {\n\t\t\t\twc = fs->lfnbuf[si++];\t\t/* Get an LFN character (UTF-16) */\n\t\t\t\tif (hs == 0 && IsSurrogate(wc)) {\t/* Is it a surrogate? */\n\t\t\t\t\ths = wc; continue;\t\t/* Get low surrogate */\n\t\t\t\t}\n\t\t\t\twc = put_utf((DWORD)hs << 16 | wc, &fno->fname[di], FF_LFN_BUF - di);\t/* Store it in UTF-16 or UTF-8 encoding */\n\t\t\t\tif (wc == 0) { di = 0; break; }\t/* Invalid char or buffer overflow? */\n\t\t\t\tdi += wc;\n\t\t\t\ths = 0;\n\t\t\t}\n\t\t\tif (hs != 0) di = 0;\t/* Broken surrogate pair? */\n\t\t\tfno->fname[di] = 0;\t\t/* Terminate the LFN (null string means LFN is invalid) */\n\t\t}\n\t}\n\n\tsi = di = 0;\n\twhile (si < 11) {\t\t/* Get SFN from SFN entry */\n\t\twc = dp->dir[si++];\t\t\t/* Get a char */\n\t\tif (wc == ' ') continue;\t/* Skip padding spaces */\n\t\tif (wc == RDDEM) wc = DDEM;\t/* Restore replaced DDEM character */\n\t\tif (si == 9 && di < FF_SFN_BUF) fno->altname[di++] = '.';\t/* Insert a . if extension is exist */\n#if FF_LFN_UNICODE >= 1\t/* Unicode output */\n\t\tif (dbc_1st((BYTE)wc) && si != 8 && si != 11 && dbc_2nd(dp->dir[si])) {\t/* Make a DBC if needed */\n\t\t\twc = wc << 8 | dp->dir[si++];\n\t\t}\n\t\twc = ff_oem2uni(wc, CODEPAGE);\t\t/* ANSI/OEM -> Unicode */\n\t\tif (wc == 0) { di = 0; break; }\t\t/* Wrong char in the current code page? */\n\t\twc = put_utf(wc, &fno->altname[di], FF_SFN_BUF - di);\t/* Store it in Unicode */\n\t\tif (wc == 0) { di = 0; break; }\t\t/* Buffer overflow? */\n\t\tdi += wc;\n#else\t\t\t\t\t/* ANSI/OEM output */\n\t\tfno->altname[di++] = (TCHAR)wc;\t/* Store it without any conversion */\n#endif\n\t}\n\tfno->altname[di] = 0;\t/* Terminate the SFN  (null string means SFN is invalid) */\n\n\tif (fno->fname[0] == 0) {\t/* If LFN is invalid, altname[] needs to be copied to fname[] */\n\t\tif (di == 0) {\t/* If LFN and SFN both are invalid, this object is inaccesible */\n\t\t\tfno->fname[di++] = '?';\n\t\t} else {\n\t\t\tfor (si = di = 0, lcf = NS_BODY; fno->altname[si]; si++, di++) {\t/* Copy altname[] to fname[] with case information */\n\t\t\t\twc = (WCHAR)fno->altname[si];\n\t\t\t\tif (wc == '.') lcf = NS_EXT;\n\t\t\t\tif (IsUpper(wc) && (dp->dir[DIR_NTres] & lcf)) wc += 0x20;\n\t\t\t\tfno->fname[di] = (TCHAR)wc;\n\t\t\t}\n\t\t}\n\t\tfno->fname[di] = 0;\t/* Terminate the LFN */\n\t\tif (!dp->dir[DIR_NTres]) fno->altname[0] = 0;\t/* Altname is not needed if neither LFN nor case info is exist. */\n\t}\n\n#else\t/* Non-LFN configuration */\n\tsi = di = 0;\n\twhile (si < 11) {\t\t/* Copy name body and extension */\n\t\tc = (TCHAR)dp->dir[si++];\n\t\tif (c == ' ') continue;\t\t/* Skip padding spaces */\n\t\tif (c == RDDEM) c = DDEM;\t/* Restore replaced DDEM character */\n\t\tif (si == 9) fno->fname[di++] = '.';/* Insert a . if extension is exist */\n\t\tfno->fname[di++] = c;\n\t}\n\tfno->fname[di] = 0;\n#endif\n\n\tfno->fattrib = dp->dir[DIR_Attr];\t\t\t\t\t/* Attribute */\n\tfno->fsize = ld_dword(dp->dir + DIR_FileSize);\t\t/* Size */\n\tfno->ftime = ld_word(dp->dir + DIR_ModTime + 0);\t/* Time */\n\tfno->fdate = ld_word(dp->dir + DIR_ModTime + 2);\t/* Date */\n}\n\n#endif /* FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 */\n\n\n\n#if FF_USE_FIND && FF_FS_MINIMIZE <= 1\n/*-----------------------------------------------------------------------*/\n/* Pattern matching                                                      */\n/*-----------------------------------------------------------------------*/\n\nstatic DWORD get_achar (\t/* Get a character and advances ptr */\n\tconst TCHAR** ptr\t\t/* Pointer to pointer to the ANSI/OEM or Unicode string */\n)\n{\n\tDWORD chr;\n\n\n#if FF_USE_LFN && FF_LFN_UNICODE >= 1\t/* Unicode input */\n\tchr = tchar2uni(ptr);\n\tif (chr == 0xFFFFFFFF) chr = 0;\t\t/* Wrong UTF encoding is recognized as end of the string */\n\tchr = ff_wtoupper(chr);\n\n#else\t\t\t\t\t\t\t\t\t/* ANSI/OEM input */\n\tchr = (BYTE)*(*ptr)++;\t\t\t\t/* Get a byte */\n\tif (IsLower(chr)) chr -= 0x20;\t\t/* To upper ASCII char */\n#if FF_CODE_PAGE == 0\n\tif (ExCvt && chr >= 0x80) chr = ExCvt[chr - 0x80];\t/* To upper SBCS extended char */\n#elif FF_CODE_PAGE < 900\n\tif (chr >= 0x80) chr = ExCvt[chr - 0x80];\t/* To upper SBCS extended char */\n#endif\n#if FF_CODE_PAGE == 0 || FF_CODE_PAGE >= 900\n\tif (dbc_1st((BYTE)chr)) {\t/* Get DBC 2nd byte if needed */\n\t\tchr = dbc_2nd((BYTE)**ptr) ? chr << 8 | (BYTE)*(*ptr)++ : 0;\n\t}\n#endif\n\n#endif\n\treturn chr;\n}\n\n\nstatic int pattern_matching (\t/* 0:not matched, 1:matched */\n\tconst TCHAR* pat,\t/* Matching pattern */\n\tconst TCHAR* nam,\t/* String to be tested */\n\tint skip,\t\t\t/* Number of pre-skip chars (number of ?s) */\n\tint inf\t\t\t\t/* Infinite search (* specified) */\n)\n{\n\tconst TCHAR *pp, *np;\n\tDWORD pc, nc;\n\tint nm, nx;\n\n\n\twhile (skip--) {\t\t\t\t/* Pre-skip name chars */\n\t\tif (!get_achar(&nam)) return 0;\t/* Branch mismatched if less name chars */\n\t}\n\tif (*pat == 0 && inf) return 1;\t/* (short circuit) */\n\n\tdo {\n\t\tpp = pat; np = nam;\t\t\t/* Top of pattern and name to match */\n\t\tfor (;;) {\n\t\t\tif (*pp == '?' || *pp == '*') {\t/* Wildcard? */\n\t\t\t\tnm = nx = 0;\n\t\t\t\tdo {\t\t\t\t/* Analyze the wildcard block */\n\t\t\t\t\tif (*pp++ == '?') nm++; else nx = 1;\n\t\t\t\t} while (*pp == '?' || *pp == '*');\n\t\t\t\tif (pattern_matching(pp, np, nm, nx)) return 1;\t/* Test new branch (recurs upto number of wildcard blocks in the pattern) */\n\t\t\t\tnc = *np; break;\t/* Branch mismatched */\n\t\t\t}\n\t\t\tpc = get_achar(&pp);\t/* Get a pattern char */\n\t\t\tnc = get_achar(&np);\t/* Get a name char */\n\t\t\tif (pc != nc) break;\t/* Branch mismatched? */\n\t\t\tif (pc == 0) return 1;\t/* Branch matched? (matched at end of both strings) */\n\t\t}\n\t\tget_achar(&nam);\t\t\t/* nam++ */\n\t} while (inf && nc);\t\t\t/* Retry until end of name if infinite search is specified */\n\n\treturn 0;\n}\n\n#endif /* FF_USE_FIND && FF_FS_MINIMIZE <= 1 */\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Pick a top segment and create the object name in directory form       */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT create_name (\t/* FR_OK: successful, FR_INVALID_NAME: could not create */\n\tDIR* dp,\t\t\t\t\t/* Pointer to the directory object */\n\tconst TCHAR** path\t\t\t/* Pointer to pointer to the segment in the path string */\n)\n{\n#if FF_USE_LFN\t\t/* LFN configuration */\n\tBYTE b, cf;\n\tWCHAR wc, *lfn;\n\tDWORD uc;\n\tUINT i, ni, si, di;\n\tconst TCHAR *p;\n\n\n\t/* Create LFN into LFN working buffer */\n\tp = *path; lfn = dp->obj.fs->lfnbuf; di = 0;\n\tfor (;;) {\n\t\tuc = tchar2uni(&p);\t\t\t/* Get a character */\n\t\tif (uc == 0xFFFFFFFF) return FR_INVALID_NAME;\t\t/* Invalid code or UTF decode error */\n\t\tif (uc >= 0x10000) lfn[di++] = (WCHAR)(uc >> 16);\t/* Store high surrogate if needed */\n\t\twc = (WCHAR)uc;\n\t\tif (wc < ' ' || wc == '/' || wc == '\\\\') break;\t/* Break if end of the path or a separator is found */\n\t\tif (wc < 0x80 && chk_chr(\"\\\"*:<>\\?|\\x7F\", wc)) return FR_INVALID_NAME;\t/* Reject illegal characters for LFN */\n\t\tif (di >= FF_MAX_LFN) return FR_INVALID_NAME;\t/* Reject too long name */\n\t\tlfn[di++] = wc;\t\t\t\t\t/* Store the Unicode character */\n\t}\n\twhile (*p == '/' || *p == '\\\\') p++;\t/* Skip duplicated separators if exist */\n\t*path = p;\t\t\t\t\t\t\t/* Return pointer to the next segment */\n\tcf = (wc < ' ') ? NS_LAST : 0;\t\t/* Set last segment flag if end of the path */\n\n#if FF_FS_RPATH != 0\n\tif ((di == 1 && lfn[di - 1] == '.') ||\n\t\t(di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) {\t/* Is this segment a dot name? */\n\t\tlfn[di] = 0;\n\t\tfor (i = 0; i < 11; i++) {\t\t/* Create dot name for SFN entry */\n\t\t\tdp->fn[i] = (i < di) ? '.' : ' ';\n\t\t}\n\t\tdp->fn[i] = cf | NS_DOT;\t\t/* This is a dot entry */\n\t\treturn FR_OK;\n\t}\n#endif\n\twhile (di) {\t\t\t\t\t\t/* Snip off trailing spaces and dots if exist */\n\t\twc = lfn[di - 1];\n\t\tif (wc != ' ' && wc != '.') break;\n\t\tdi--;\n\t}\n\tlfn[di] = 0;\t\t\t\t\t\t\t/* LFN is created into the working buffer */\n\tif (di == 0) return FR_INVALID_NAME;\t/* Reject null name */\n\n\t/* Create SFN in directory form */\n\tfor (si = 0; lfn[si] == ' '; si++) ;\t/* Remove leading spaces */\n\tif (si > 0 || lfn[si] == '.') cf |= NS_LOSS | NS_LFN;\t/* Is there any leading space or dot? */\n\twhile (di > 0 && lfn[di - 1] != '.') di--;\t/* Find last dot (di<=si: no extension) */\n\n\tmem_set(dp->fn, ' ', 11);\n\ti = b = 0; ni = 8;\n\tfor (;;) {\n\t\twc = lfn[si++];\t\t\t\t\t/* Get an LFN character */\n\t\tif (wc == 0) break;\t\t\t\t/* Break on end of the LFN */\n\t\tif (wc == ' ' || (wc == '.' && si != di)) {\t/* Remove embedded spaces and dots */\n\t\t\tcf |= NS_LOSS | NS_LFN;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (i >= ni || si == di) {\t\t/* End of field? */\n\t\t\tif (ni == 11) {\t\t\t\t/* Name extension overflow? */\n\t\t\t\tcf |= NS_LOSS | NS_LFN;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (si != di) cf |= NS_LOSS | NS_LFN;\t/* Name body overflow? */\n\t\t\tif (si > di) break;\t\t\t\t\t\t/* No name extension? */\n\t\t\tsi = di; i = 8; ni = 11; b <<= 2;\t\t/* Enter name extension */\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (wc >= 0x80) {\t/* Is this a non-ASCII character? */\n\t\t\tcf |= NS_LFN;\t/* LFN entry needs to be created */\n#if FF_CODE_PAGE == 0\n\t\t\tif (ExCvt) {\t/* At SBCS */\n\t\t\t\twc = ff_uni2oem(wc, CODEPAGE);\t\t\t/* Unicode ==> ANSI/OEM code */\n\t\t\t\tif (wc & 0x80) wc = ExCvt[wc & 0x7F];\t/* Convert extended character to upper (SBCS) */\n\t\t\t} else {\t\t/* At DBCS */\n\t\t\t\twc = ff_uni2oem(ff_wtoupper(wc), CODEPAGE);\t/* Unicode ==> Upper convert ==> ANSI/OEM code */\n\t\t\t}\n#elif FF_CODE_PAGE < 900\t/* SBCS cfg */\n\t\t\twc = ff_uni2oem(wc, CODEPAGE);\t\t\t/* Unicode ==> ANSI/OEM code */\n\t\t\tif (wc & 0x80) wc = ExCvt[wc & 0x7F];\t/* Convert extended character to upper (SBCS) */\n#else\t\t\t\t\t\t/* DBCS cfg */\n\t\t\twc = ff_uni2oem(ff_wtoupper(wc), CODEPAGE);\t/* Unicode ==> Upper convert ==> ANSI/OEM code */\n#endif\n\t\t}\n\n\t\tif (wc >= 0x100) {\t\t\t\t/* Is this a DBC? */\n\t\t\tif (i >= ni - 1) {\t\t\t/* Field overflow? */\n\t\t\t\tcf |= NS_LOSS | NS_LFN;\n\t\t\t\ti = ni; continue;\t\t/* Next field */\n\t\t\t}\n\t\t\tdp->fn[i++] = (BYTE)(wc >> 8);\t/* Put 1st byte */\n\t\t} else {\t\t\t\t\t\t/* SBC */\n\t\t\tif (wc == 0 || chk_chr(\"+,;=[]\", wc)) {\t/* Replace illegal characters for SFN if needed */\n\t\t\t\twc = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */\n\t\t\t} else {\n\t\t\t\tif (IsUpper(wc)) {\t\t/* ASCII upper case? */\n\t\t\t\t\tb |= 2;\n\t\t\t\t}\n\t\t\t\tif (IsLower(wc)) {\t\t/* ASCII lower case? */\n\t\t\t\t\tb |= 1; wc -= 0x20;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdp->fn[i++] = (BYTE)wc;\n\t}\n\n\tif (dp->fn[0] == DDEM) dp->fn[0] = RDDEM;\t/* If the first character collides with DDEM, replace it with RDDEM */\n\n\tif (ni == 8) b <<= 2;\t\t\t\t/* Shift capital flags if no extension */\n\tif ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) cf |= NS_LFN;\t/* LFN entry needs to be created if composite capitals */\n\tif (!(cf & NS_LFN)) {\t\t\t\t/* When LFN is in 8.3 format without extended character, NT flags are created */\n\t\tif (b & 0x01) cf |= NS_EXT;\t\t/* NT flag (Extension has small capital letters only) */\n\t\tif (b & 0x04) cf |= NS_BODY;\t/* NT flag (Body has small capital letters only) */\n\t}\n\n\tdp->fn[NSFLAG] = cf;\t/* SFN is created into dp->fn[] */\n\n\treturn FR_OK;\n\n\n#else\t/* FF_USE_LFN : Non-LFN configuration */\n\tBYTE c, d, *sfn;\n\tUINT ni, si, i;\n\tconst char *p;\n\n\t/* Create file name in directory form */\n\tp = *path; sfn = dp->fn;\n\tmem_set(sfn, ' ', 11);\n\tsi = i = 0; ni = 8;\n#if FF_FS_RPATH != 0\n\tif (p[si] == '.') { /* Is this a dot entry? */\n\t\tfor (;;) {\n\t\t\tc = (BYTE)p[si++];\n\t\t\tif (c != '.' || si >= 3) break;\n\t\t\tsfn[i++] = c;\n\t\t}\n\t\tif (c != '/' && c != '\\\\' && c > ' ') return FR_INVALID_NAME;\n\t\t*path = p + si;\t\t\t\t\t\t\t\t/* Return pointer to the next segment */\n\t\tsfn[NSFLAG] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT;\t/* Set last segment flag if end of the path */\n\t\treturn FR_OK;\n\t}\n#endif\n\tfor (;;) {\n\t\tc = (BYTE)p[si++];\t\t\t\t/* Get a byte */\n\t\tif (c <= ' ') break; \t\t\t/* Break if end of the path name */\n\t\tif (c == '/' || c == '\\\\') {\t/* Break if a separator is found */\n\t\t\twhile (p[si] == '/' || p[si] == '\\\\') si++;\t/* Skip duplicated separator if exist */\n\t\t\tbreak;\n\t\t}\n\t\tif (c == '.' || i >= ni) {\t\t/* End of body or field overflow? */\n\t\t\tif (ni == 11 || c != '.') return FR_INVALID_NAME;\t/* Field overflow or invalid dot? */\n\t\t\ti = 8; ni = 11;\t\t\t\t/* Enter file extension field */\n\t\t\tcontinue;\n\t\t}\n#if FF_CODE_PAGE == 0\n\t\tif (ExCvt && c >= 0x80) {\t\t/* Is SBC extended character? */\n\t\t\tc = ExCvt[c & 0x7F];\t\t/* To upper SBC extended character */\n\t\t}\n#elif FF_CODE_PAGE < 900\n\t\tif (c >= 0x80) {\t\t\t\t/* Is SBC extended character? */\n\t\t\tc = ExCvt[c & 0x7F];\t\t/* To upper SBC extended character */\n\t\t}\n#endif\n\t\tif (dbc_1st(c)) {\t\t\t\t/* Check if it is a DBC 1st byte */\n\t\t\td = (BYTE)p[si++];\t\t\t/* Get 2nd byte */\n\t\t\tif (!dbc_2nd(d) || i >= ni - 1) return FR_INVALID_NAME;\t/* Reject invalid DBC */\n\t\t\tsfn[i++] = c;\n\t\t\tsfn[i++] = d;\n\t\t} else {\t\t\t\t\t\t/* SBC */\n\t\t\tif (chk_chr(\"\\\"*+,:;<=>\\?[]|\\x7F\", c)) return FR_INVALID_NAME;\t/* Reject illegal chrs for SFN */\n\t\t\tif (IsLower(c)) c -= 0x20;\t/* To upper */\n\t\t\tsfn[i++] = c;\n\t\t}\n\t}\n\t*path = p + si;\t\t\t\t\t\t/* Return pointer to the next segment */\n\tif (i == 0) return FR_INVALID_NAME;\t/* Reject nul string */\n\n\tif (sfn[0] == DDEM) sfn[0] = RDDEM;\t/* If the first character collides with DDEM, replace it with RDDEM */\n\tsfn[NSFLAG] = (c <= ' ') ? NS_LAST : 0;\t\t/* Set last segment flag if end of the path */\n\n\treturn FR_OK;\n#endif /* FF_USE_LFN */\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Follow a file path                                                    */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT follow_path (\t/* FR_OK(0): successful, !=0: error code */\n\tDIR* dp,\t\t\t\t\t/* Directory object to return last directory and found object */\n\tconst TCHAR* path\t\t\t/* Full-path string to find a file or directory */\n)\n{\n\tFRESULT res;\n\tBYTE ns;\n\tFATFS *fs = dp->obj.fs;\n\n\n#if FF_FS_RPATH != 0\n\tif (*path != '/' && *path != '\\\\') {\t/* Without heading separator */\n\t\tdp->obj.sclust = fs->cdir;\t\t\t\t/* Start from current directory */\n\t} else\n#endif\n\t{\t\t\t\t\t\t\t\t\t\t/* With heading separator */\n\t\twhile (*path == '/' || *path == '\\\\') path++;\t/* Strip heading separator */\n\t\tdp->obj.sclust = 0;\t\t\t\t\t/* Start from root directory */\n\t}\n#if FF_FS_EXFAT\n\tdp->obj.n_frag = 0;\t/* Invalidate last fragment counter of the object */\n#if FF_FS_RPATH != 0\n\tif (fs->fs_type == FS_EXFAT && dp->obj.sclust) {\t/* exFAT: Retrieve the sub-directory's status */\n\t\tDIR dj;\n\n\t\tdp->obj.c_scl = fs->cdc_scl;\n\t\tdp->obj.c_size = fs->cdc_size;\n\t\tdp->obj.c_ofs = fs->cdc_ofs;\n\t\tres = load_obj_xdir(&dj, &dp->obj);\n\t\tif (res != FR_OK) return res;\n\t\tdp->obj.objsize = ld_dword(fs->dirbuf + XDIR_FileSize);\n\t\tdp->obj.stat = fs->dirbuf[XDIR_GenFlags] & 2;\n\t}\n#endif\n#endif\n\n\tif ((UINT)*path < ' ') {\t\t\t\t/* Null path name is the origin directory itself */\n\t\tdp->fn[NSFLAG] = NS_NONAME;\n\t\tres = dir_sdi(dp, 0);\n\n\t} else {\t\t\t\t\t\t\t\t/* Follow path */\n\t\tfor (;;) {\n\t\t\tres = create_name(dp, &path);\t/* Get a segment name of the path */\n\t\t\tif (res != FR_OK) break;\n\t\t\tres = dir_find(dp);\t\t\t\t/* Find an object with the segment name */\n\t\t\tns = dp->fn[NSFLAG];\n\t\t\tif (res != FR_OK) {\t\t\t\t/* Failed to find the object */\n\t\t\t\tif (res == FR_NO_FILE) {\t/* Object is not found */\n\t\t\t\t\tif (FF_FS_RPATH && (ns & NS_DOT)) {\t/* If dot entry is not exist, stay there */\n\t\t\t\t\t\tif (!(ns & NS_LAST)) continue;\t/* Continue to follow if not last segment */\n\t\t\t\t\t\tdp->fn[NSFLAG] = NS_NONAME;\n\t\t\t\t\t\tres = FR_OK;\n\t\t\t\t\t} else {\t\t\t\t\t\t\t/* Could not find the object */\n\t\t\t\t\t\tif (!(ns & NS_LAST)) res = FR_NO_PATH;\t/* Adjust error code if not last segment */\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (ns & NS_LAST) break;\t\t\t/* Last segment matched. Function completed. */\n\t\t\t/* Get into the sub-directory */\n\t\t\tif (!(dp->obj.attr & AM_DIR)) {\t\t/* It is not a sub-directory and cannot follow */\n\t\t\t\tres = FR_NO_PATH; break;\n\t\t\t}\n#if FF_FS_EXFAT\n\t\t\tif (fs->fs_type == FS_EXFAT) {\t\t/* Save containing directory information for next dir */\n\t\t\t\tdp->obj.c_scl = dp->obj.sclust;\n\t\t\t\tdp->obj.c_size = ((DWORD)dp->obj.objsize & 0xFFFFFF00) | dp->obj.stat;\n\t\t\t\tdp->obj.c_ofs = dp->blk_ofs;\n\t\t\t\tinit_alloc_info(fs, &dp->obj);\t/* Open next directory */\n\t\t\t} else\n#endif\n\t\t\t{\n\t\t\t\tdp->obj.sclust = ld_clust(fs, fs->win + dp->dptr % SS(fs));\t/* Open next directory */\n\t\t\t}\n\t\t}\n\t}\n\n\treturn res;\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Get logical drive number from path name                               */\n/*-----------------------------------------------------------------------*/\n\nstatic int get_ldnumber (\t/* Returns logical drive number (-1:invalid drive number or null pointer) */\n\tconst TCHAR** path\t\t/* Pointer to pointer to the path name */\n)\n{\n\tconst TCHAR *tp, *tt;\n\tTCHAR tc;\n\tint i, vol = -1;\n#if FF_STR_VOLUME_ID\t\t/* Find string volume ID */\n\tconst char *sp;\n\tchar c;\n#endif\n\n\ttt = tp = *path;\n\tif (!tp) return vol;\t/* Invalid path name? */\n\tdo tc = *tt++; while ((UINT)tc >= (FF_USE_LFN ? ' ' : '!') && tc != ':');\t/* Find a colon in the path */\n\n\tif (tc == ':') {\t/* DOS/Windows style volume ID? */\n\t\ti = FF_VOLUMES;\n\t\tif (IsDigit(*tp) && tp + 2 == tt) {\t/* Is there a numeric volume ID + colon? */\n\t\t\ti = (int)*tp - '0';\t/* Get the LD number */\n\t\t}\n#if FF_STR_VOLUME_ID == 1\t/* Arbitrary string is enabled */\n\t\telse {\n\t\t\ti = 0;\n\t\t\tdo {\n\t\t\t\tsp = VolumeStr[i]; tp = *path;\t/* This string volume ID and path name */\n\t\t\t\tdo {\t/* Compare the volume ID with path name */\n\t\t\t\t\tc = *sp++; tc = *tp++;\n\t\t\t\t\tif (IsLower(c)) c -= 0x20;\n\t\t\t\t\tif (IsLower(tc)) tc -= 0x20;\n\t\t\t\t} while (c && (TCHAR)c == tc);\n\t\t\t} while ((c || tp != tt) && ++i < FF_VOLUMES);\t/* Repeat for each id until pattern match */\n\t\t}\n#endif\n\t\tif (i < FF_VOLUMES) {\t/* If a volume ID is found, get the drive number and strip it */\n\t\t\tvol = i;\t\t/* Drive number */\n\t\t\t*path = tt;\t\t/* Snip the drive prefix off */\n\t\t}\n\t\treturn vol;\n\t}\n#if FF_STR_VOLUME_ID == 2\t\t/* Unix style volume ID is enabled */\n\tif (*tp == '/') {\n\t\ti = 0;\n\t\tdo {\n\t\t\tsp = VolumeStr[i]; tp = *path;\t/* This string volume ID and path name */\n\t\t\tdo {\t/* Compare the volume ID with path name */\n\t\t\t\tc = *sp++; tc = *(++tp);\n\t\t\t\tif (IsLower(c)) c -= 0x20;\n\t\t\t\tif (IsLower(tc)) tc -= 0x20;\n\t\t\t} while (c && (TCHAR)c == tc);\n\t\t} while ((c || (tc != '/' && (UINT)tc >= (FF_USE_LFN ? ' ' : '!'))) && ++i < FF_VOLUMES);\t/* Repeat for each ID until pattern match */\n\t\tif (i < FF_VOLUMES) {\t/* If a volume ID is found, get the drive number and strip it */\n\t\t\tvol = i;\t\t/* Drive number */\n\t\t\t*path = tp;\t\t/* Snip the drive prefix off */\n\t\t\treturn vol;\n\t\t}\n\t}\n#endif\n\t/* No drive prefix is found */\n#if FF_FS_RPATH != 0\n\tvol = CurrVol;\t/* Default drive is current drive */\n#else\n\tvol = 0;\t\t/* Default drive is 0 */\n#endif\n\treturn vol;\t\t/* Return the default drive */\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Load a sector and check if it is an FAT VBR                           */\n/*-----------------------------------------------------------------------*/\n\nstatic BYTE check_fs (\t/* 0:FAT, 1:exFAT, 2:Valid BS but not FAT, 3:Not a BS, 4:Disk error */\n\tFATFS* fs,\t\t\t/* Filesystem object */\n\tDWORD sect\t\t\t/* Sector# (lba) to load and check if it is an FAT-VBR or not */\n)\n{\n\tfs->wflag = 0; fs->winsect = 0xFFFFFFFF;\t\t/* Invaidate window */\n\tif (move_window(fs, sect) != FR_OK) return 4;\t/* Load boot record */\n\n\tif (ld_word(fs->win + BS_55AA) != 0xAA55) return 3;\t/* Check boot record signature (always here regardless of the sector size) */\n\n#if FF_FS_EXFAT\n\tif (!mem_cmp(fs->win + BS_JmpBoot, \"\\xEB\\x76\\x90\" \"EXFAT   \", 11)) return 1;\t/* Check if exFAT VBR */\n#endif\n\tif (fs->win[BS_JmpBoot] == 0xE9 || fs->win[BS_JmpBoot] == 0xEB || fs->win[BS_JmpBoot] == 0xE8) {\t/* Valid JumpBoot code? */\n\t\tif (!mem_cmp(fs->win + BS_FilSysType, \"FAT\", 3)) return 0;\t\t/* Is it an FAT VBR? */\n\t\tif (!mem_cmp(fs->win + BS_FilSysType32, \"FAT32\", 5)) return 0;\t/* Is it an FAT32 VBR? */\n\t}\n\treturn 2;\t/* Valid BS but not FAT */\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Determine logical drive number and mount the volume if needed         */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT find_volume (\t/* FR_OK(0): successful, !=0: an error occurred */\n\tconst TCHAR** path,\t\t\t/* Pointer to pointer to the path name (drive number) */\n\tFATFS** rfs,\t\t\t\t/* Pointer to pointer to the found filesystem object */\n\tBYTE mode\t\t\t\t\t/* !=0: Check write protection for write access */\n)\n{\n\tBYTE fmt, *pt;\n\tint vol;\n\tDSTATUS stat;\n\tDWORD bsect, fasize, tsect, sysect, nclst, szbfat, br[4];\n\tWORD nrsv;\n\tFATFS *fs;\n\tUINT i;\n\n\n\t/* Get logical drive number */\n\t*rfs = 0;\n\tvol = get_ldnumber(path);\n\tif (vol < 0) return FR_INVALID_DRIVE;\n\n\t/* Check if the filesystem object is valid or not */\n\tfs = FatFs[vol];\t\t\t\t\t/* Get pointer to the filesystem object */\n\tif (!fs) return FR_NOT_ENABLED;\t\t/* Is the filesystem object available? */\n#if FF_FS_REENTRANT\n\tif (!lock_fs(fs)) return FR_TIMEOUT;\t/* Lock the volume */\n#endif\n\t*rfs = fs;\t\t\t\t\t\t\t/* Return pointer to the filesystem object */\n\n\tmode &= (BYTE)~FA_READ;\t\t\t\t/* Desired access mode, write access or not */\n\tif (fs->fs_type != 0) {\t\t\t\t/* If the volume has been mounted */\n\t\tstat = disk_status(fs->pdrv);\n\t\tif (!(stat & STA_NOINIT)) {\t\t/* and the physical drive is kept initialized */\n\t\t\tif (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) {\t/* Check write protection if needed */\n\t\t\t\tEFSPRINTF(\"WPEN1\");\n\t\t\t\treturn FR_WRITE_PROTECTED;\n\t\t\t}\n\t\t\treturn FR_OK;\t\t\t\t/* The filesystem object is valid */\n\t\t}\n\t}\n\n\t/* The filesystem object is not valid. */\n\t/* Following code attempts to mount the volume. (analyze BPB and initialize the filesystem object) */\n\n\tfs->fs_type = 0;\t\t\t\t\t/* Clear the filesystem object */\n\tfs->pdrv = LD2PD(vol);\t\t\t\t/* Bind the logical drive and a physical drive */\n\tstat = disk_initialize(fs->pdrv);\t/* Initialize the physical drive */\n\tif (stat & STA_NOINIT) { \t\t\t/* Check if the initialization succeeded */\n\t\tEFSPRINTF(\"MDNR\");\n\t\treturn FR_NOT_READY;\t\t\t/* Failed to initialize due to no medium or hard error */\n\t}\n\tif (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check disk write protection if needed */\n\t\tEFSPRINTF(\"WPEN2\");\n\t\treturn FR_WRITE_PROTECTED;\n\t}\n#if FF_MAX_SS != FF_MIN_SS\t\t\t\t/* Get sector size (multiple sector size cfg only) */\n\tif (disk_ioctl(fs->pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK) return FR_DISK_ERR;\n\tif (SS(fs) > FF_MAX_SS || SS(fs) < FF_MIN_SS || (SS(fs) & (SS(fs) - 1))) return FR_DISK_ERR;\n#endif\n\n\t/* Find an FAT partition on the drive. Supports only generic partitioning rules, FDISK (MBR) and SFD (w/o partition). */\n\tbsect = 0;\n\tfmt = check_fs(fs, bsect);\t\t\t/* Load sector 0 and check if it is an FAT-VBR as SFD */\n\tif (fmt == 2 || (fmt < 2 && LD2PT(vol) != 0)) {\t/* Not an FAT-VBR or forced partition number */\n\t\tfor (i = 0; i < 4; i++) {\t\t/* Get partition offset */\n\t\t\tpt = fs->win + (MBR_Table + i * SZ_PTE);\n\t\t\tbr[i] = pt[PTE_System] ? ld_dword(pt + PTE_StLba) : 0;\n\t\t}\n\t\ti = LD2PT(vol);\t\t\t\t\t/* Partition number: 0:auto, 1-4:forced */\n\t\tif (i != 0) i--;\n\t\tdo {\t\t\t\t\t\t\t/* Find an FAT volume */\n\t\t\tbsect = br[i];\n\t\t\tfmt = bsect ? check_fs(fs, bsect) : 3;\t/* Check the partition */\n\t\t} while (LD2PT(vol) == 0 && fmt >= 2 && ++i < 4);\n\t}\n\tif (fmt == 4) {\n\t\tEFSPRINTF(\"BRNL\");\n\t\treturn FR_DISK_ERR;\t\t/* An error occured in the disk I/O layer */\n\t}\n\tif (fmt >= 2) {\n\t\tEFSPRINTF(\"NOFAT\");\n\t\treturn FR_NO_FILESYSTEM;\t/* No FAT volume is found */\n\t}\n\n\t/* An FAT volume is found (bsect). Following code initializes the filesystem object */\n\n#if FF_FS_EXFAT\n\tif (fmt == 1) {\n\t\tQWORD maxlba;\n\t\tDWORD so, cv, bcl;\n\n\t\tfor (i = BPB_ZeroedEx; i < BPB_ZeroedEx + 53 && fs->win[i] == 0; i++) ;\t/* Check zero filler */\n\t\tif (i < BPB_ZeroedEx + 53) return FR_NO_FILESYSTEM;\n\n\t\tif (ld_word(fs->win + BPB_FSVerEx) != 0x100) return FR_NO_FILESYSTEM;\t/* Check exFAT version (must be version 1.0) */\n\n\t\tif (1 << fs->win[BPB_BytsPerSecEx] != SS(fs)) {\t/* (BPB_BytsPerSecEx must be equal to the physical sector size) */\n\t\t\tEFSPRINTF(\"EXSPS\");\n\t\t\treturn FR_NO_FILESYSTEM;\n\t\t}\n\n\t\tmaxlba = ld_qword(fs->win + BPB_TotSecEx) + bsect;\t/* Last LBA + 1 of the volume */\n\t\tif (maxlba >= 0x100000000) return FR_NO_FILESYSTEM;\t/* (It cannot be handled in 32-bit LBA) */\n\n\t\tfs->fsize = ld_dword(fs->win + BPB_FatSzEx);\t/* Number of sectors per FAT */\n\n\t\tfs->n_fats = fs->win[BPB_NumFATsEx];\t\t\t/* Number of FATs */\n\t\tif (fs->n_fats != 1) {\n\t\t\tEFSPRINTF(\"EXFNF\");\n\t\t\treturn FR_NO_FILESYSTEM;\t/* (Supports only 1 FAT) */\n\t\t}\n\n\t\tfs->csize = 1 << fs->win[BPB_SecPerClusEx];\t\t/* Cluster size */\n\t\tif (fs->csize == 0)\treturn FR_NO_FILESYSTEM;\t/* (Must be 1..32768) */\n\n\t\tnclst = ld_dword(fs->win + BPB_NumClusEx);\t\t/* Number of clusters */\n\t\tif (nclst > MAX_EXFAT) return FR_NO_FILESYSTEM;\t/* (Too many clusters) */\n\t\tfs->n_fatent = nclst + 2;\n\n\t\t/* Boundaries and Limits */\n\t\tfs->volbase = bsect;\n\t\tfs->database = bsect + ld_dword(fs->win + BPB_DataOfsEx);\n\t\tfs->fatbase = bsect + ld_dword(fs->win + BPB_FatOfsEx);\n\t\tif (maxlba < (QWORD)fs->database + nclst * fs->csize) return FR_NO_FILESYSTEM;\t/* (Volume size must not be smaller than the size requiered) */\n\t\tfs->dirbase = ld_dword(fs->win + BPB_RootClusEx);\n\n\t\t/* Get bitmap location and check if it is contiguous (implementation assumption) */\n\t\tso = i = 0;\n\t\tfor (;;) {\t/* Find the bitmap entry in the root directory (in only first cluster) */\n\t\t\tif (i == 0) {\n\t\t\t\tif (so >= fs->csize) return FR_NO_FILESYSTEM;\t/* Not found? */\n\t\t\t\tif (move_window(fs, clst2sect(fs, fs->dirbase) + so) != FR_OK) {\n\t\t\t\t\tEFSPRINTF(\"EXBM1C\");\n\t\t\t\t\treturn FR_DISK_ERR;\n\t\t\t\t}\n\t\t\t\tso++;\n\t\t\t}\n\t\t\tif (fs->win[i] == ET_BITMAP) break;\t\t\t\t/* Is it a bitmap entry? */\n\t\t\ti = (i + SZDIRE) % SS(fs);\t/* Next entry */\n\t\t}\n\t\tbcl = ld_dword(fs->win + i + 20);\t\t\t\t\t/* Bitmap cluster */\n\t\tif (bcl < 2 || bcl >= fs->n_fatent) {\n\t\t\tEFSPRINTF(\"EXBMM\");\n\t\t\treturn FR_NO_FILESYSTEM;\n\t\t}\n\t\tfs->bitbase = fs->database + fs->csize * (bcl - 2);\t/* Bitmap sector */\n\t\tfor (;;) {\t/* Check if bitmap is contiguous */\n\t\t\tif (move_window(fs, fs->fatbase + bcl / (SS(fs) / 4)) != FR_OK) return FR_DISK_ERR;\n\t\t\tcv = ld_dword(fs->win + bcl % (SS(fs) / 4) * 4);\n\t\t\tif (cv == 0xFFFFFFFF) break;\t\t\t\t/* Last link? */\n\t\t\tif (cv != ++bcl) {\n\t\t\t\tEFSPRINTF(\"EXBMM\");\n\t\t\t\treturn FR_NO_FILESYSTEM;\t/* Fragmented? */\n\t\t\t}\n\t\t}\n\n#if !FF_FS_READONLY\n\t\tfs->last_clst = fs->free_clst = 0xFFFFFFFF;\t\t/* Initialize cluster allocation information */\n#endif\n\t\tfmt = FS_EXFAT;\t\t\t/* FAT sub-type */\n\t} else\n#endif\t/* FF_FS_EXFAT */\n\t{\n\t\tif (ld_word(fs->win + BPB_BytsPerSec) != SS(fs)) {\n\t\t\tEFSPRINTF(\"32SPS\");\n\t\t\treturn FR_NO_FILESYSTEM;\t/* (BPB_BytsPerSec must be equal to the physical sector size) */\n\t\t}\n\n\t\tfasize = ld_word(fs->win + BPB_FATSz16);\t\t/* Number of sectors per FAT */\n\t\tif (fasize == 0) fasize = ld_dword(fs->win + BPB_FATSz32);\n\t\tfs->fsize = fasize;\n\n\t\tfs->n_fats = fs->win[BPB_NumFATs];\t\t\t\t/* Number of FATs */\n\t\tif (fs->n_fats != 1 && fs->n_fats != 2) return FR_NO_FILESYSTEM;\t/* (Must be 1 or 2) */\n\t\tfasize *= fs->n_fats;\t\t\t\t\t\t\t/* Number of sectors for FAT area */\n\n\t\tfs->csize = fs->win[BPB_SecPerClus];\t\t\t/* Cluster size */\n\t\tif (fs->csize == 0 || (fs->csize & (fs->csize - 1))) return FR_NO_FILESYSTEM;\t/* (Must be power of 2) */\n\n\t\tfs->n_rootdir = ld_word(fs->win + BPB_RootEntCnt);\t/* Number of root directory entries */\n\t\tif (fs->n_rootdir % (SS(fs) / SZDIRE)) return FR_NO_FILESYSTEM;\t/* (Must be sector aligned) */\n\n\t\ttsect = ld_word(fs->win + BPB_TotSec16);\t\t/* Number of sectors on the volume */\n\t\tif (tsect == 0) tsect = ld_dword(fs->win + BPB_TotSec32);\n\n\t\tnrsv = ld_word(fs->win + BPB_RsvdSecCnt);\t\t/* Number of reserved sectors */\n\t\tif (nrsv == 0) return FR_NO_FILESYSTEM;\t\t\t/* (Must not be 0) */\n\n\t\t/* Determine the FAT sub type */\n\t\tsysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE);\t/* RSV + FAT + DIR */\n\t\tif (tsect < sysect) return FR_NO_FILESYSTEM;\t/* (Invalid volume size) */\n\t\tnclst = (tsect - sysect) / fs->csize;\t\t\t/* Number of clusters */\n\t\tif (nclst == 0) return FR_NO_FILESYSTEM;\t\t/* (Invalid volume size) */\n\t\tfmt = 0;\n\t\tif (nclst <= MAX_FAT32) fmt = FS_FAT32;\n\t\tif (nclst <= MAX_FAT16) fmt = FS_FAT16;\n\t\tif (nclst <= MAX_FAT12) fmt = FS_FAT12;\n\t\tif (fmt == 0) return FR_NO_FILESYSTEM;\n\n\t\t/* Boundaries and Limits */\n\t\tfs->n_fatent = nclst + 2;\t\t\t\t\t\t/* Number of FAT entries */\n\t\tfs->volbase = bsect;\t\t\t\t\t\t\t/* Volume start sector */\n\t\tfs->fatbase = bsect + nrsv; \t\t\t\t\t/* FAT start sector */\n\t\tfs->database = bsect + sysect;\t\t\t\t\t/* Data start sector */\n\t\tif (fmt == FS_FAT32) {\n\t\t\tif (ld_word(fs->win + BPB_FSVer32) != 0) return FR_NO_FILESYSTEM;\t/* (Must be FAT32 revision 0.0) */\n\t\t\tif (fs->n_rootdir != 0) return FR_NO_FILESYSTEM;\t/* (BPB_RootEntCnt must be 0) */\n\t\t\tfs->dirbase = ld_dword(fs->win + BPB_RootClus32);\t/* Root directory start cluster */\n\t\t\tszbfat = fs->n_fatent * 4;\t\t\t\t\t/* (Needed FAT size) */\n\t\t} else {\n\t\t\tif (fs->n_rootdir == 0)\treturn FR_NO_FILESYSTEM;\t/* (BPB_RootEntCnt must not be 0) */\n\t\t\tfs->dirbase = fs->fatbase + fasize;\t\t\t/* Root directory start sector */\n\t\t\tszbfat = (fmt == FS_FAT16) ?\t\t\t\t/* (Needed FAT size) */\n\t\t\t\tfs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);\n\t\t}\n\t\tif (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) return FR_NO_FILESYSTEM;\t/* (BPB_FATSz must not be less than the size needed) */\n\n#if !FF_FS_READONLY\n\t\t/* Get FSInfo if available */\n\t\tfs->last_clst = fs->free_clst = 0xFFFFFFFF;\t\t/* Initialize cluster allocation information */\n\t\tfs->fsi_flag = 0x80;\n#if (FF_FS_NOFSINFO & 3) != 3\n\t\tif (fmt == FS_FAT32\t\t\t\t/* Allow to update FSInfo only if BPB_FSInfo32 == 1 */\n\t\t\t&& ld_word(fs->win + BPB_FSInfo32) == 1\n\t\t\t&& move_window(fs, bsect + 1) == FR_OK)\n\t\t{\n\t\t\tfs->fsi_flag = 0;\n\t\t\tif (ld_word(fs->win + BS_55AA) == 0xAA55\t/* Load FSInfo data if available */\n\t\t\t\t&& ld_dword(fs->win + FSI_LeadSig) == 0x41615252\n\t\t\t\t&& ld_dword(fs->win + FSI_StrucSig) == 0x61417272)\n\t\t\t{\n#if (FF_FS_NOFSINFO & 1) == 0\n\t\t\t\tfs->free_clst = ld_dword(fs->win + FSI_Free_Count);\n#endif\n#if (FF_FS_NOFSINFO & 2) == 0\n\t\t\t\tfs->last_clst = ld_dword(fs->win + FSI_Nxt_Free);\n#endif\n\t\t\t}\n\t\t}\n#endif\t/* (FF_FS_NOFSINFO & 3) != 3 */\n#endif\t/* !FF_FS_READONLY */\n\t}\n\n\tfs->fs_type = fmt;\t\t/* FAT sub-type */\n\tfs->id = ++Fsid;\t\t/* Volume mount ID */\n#if FF_USE_LFN == 1\n\tfs->lfnbuf = LfnBuf;\t/* Static LFN working buffer */\n#if FF_FS_EXFAT\n\tfs->dirbuf = DirBuf;\t/* Static directory block scratchpad buffer */\n#endif\n#endif\n#if FF_FS_RPATH != 0\n\tfs->cdir = 0;\t\t\t/* Initialize current directory */\n#endif\n#if FF_FS_LOCK != 0\t\t\t/* Clear file lock semaphores */\n\tclear_lock(fs);\n#endif\n\treturn FR_OK;\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Check if the file/directory object is valid or not                    */\n/*-----------------------------------------------------------------------*/\n\nstatic FRESULT validate (\t/* Returns FR_OK or FR_INVALID_OBJECT */\n\tFFOBJID* obj,\t\t\t/* Pointer to the FFOBJID, the 1st member in the FIL/DIR object, to check validity */\n\tFATFS** rfs\t\t\t\t/* Pointer to pointer to the owner filesystem object to return */\n)\n{\n\tFRESULT res = FR_INVALID_OBJECT;\n\n\n\tif (obj && obj->fs && obj->fs->fs_type && obj->id == obj->fs->id) {\t/* Test if the object is valid */\n#if FF_FS_REENTRANT\n\t\tif (lock_fs(obj->fs)) {\t/* Obtain the filesystem object */\n\t\t\tif (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */\n\t\t\t\tres = FR_OK;\n\t\t\t} else {\n\t\t\t\tunlock_fs(obj->fs, FR_OK);\n\t\t\t}\n\t\t} else {\n\t\t\tres = FR_TIMEOUT;\n\t\t}\n#else\n\t\tif (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */\n\t\t\tres = FR_OK;\n\t\t}\n#endif\n\t}\n\t*rfs = (res == FR_OK) ? obj->fs : 0;\t/* Corresponding filesystem object */\n\treturn res;\n}\n\n\n\n\n/*---------------------------------------------------------------------------\n\n   Public Functions (FatFs API)\n\n----------------------------------------------------------------------------*/\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Mount/Unmount a Logical Drive                                         */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_mount (\n\tFATFS* fs,\t\t\t/* Pointer to the filesystem object (NULL:unmount)*/\n\tconst TCHAR* path,\t/* Logical drive number to be mounted/unmounted */\n\tBYTE opt\t\t\t/* Mode option 0:Do not mount (delayed mount), 1:Mount immediately */\n)\n{\n\tFATFS *cfs;\n\tint vol;\n\tFRESULT res;\n\tconst TCHAR *rp = path;\n\n\n\t/* Get logical drive number */\n\tvol = get_ldnumber(&rp);\n\tif (vol < 0) {\n\t\tEFSPRINTF(\"IDRIVE!\");\n\t\treturn FR_INVALID_DRIVE;\n\t}\n\tcfs = FatFs[vol];\t\t\t\t\t/* Pointer to fs object */\n\n\tif (cfs) {\n#if FF_FS_LOCK != 0\n\t\tclear_lock(cfs);\n#endif\n#if FF_FS_REENTRANT\t\t\t\t\t\t/* Discard sync object of the current volume */\n\t\tif (!ff_del_syncobj(cfs->sobj)) return FR_INT_ERR;\n#endif\n\t\tcfs->fs_type = 0;\t\t\t\t/* Clear old fs object */\n\t}\n\n\tif (fs) {\n\t\tfs->fs_type = 0;\t\t\t\t/* Clear new fs object */\n#if FF_FS_REENTRANT\t\t\t\t\t\t/* Create sync object for the new volume */\n\t\tif (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR;\n#endif\n\t}\n\tFatFs[vol] = fs;\t\t\t\t\t/* Register new fs object */\n\n\tif (opt == 0) return FR_OK;\t\t\t/* Do not mount now, it will be mounted later */\n\n\tres = find_volume(&path, &fs, 0);\t/* Force mounted the volume */\n\tLEAVE_FF(fs, res);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Open or Create a File                                                 */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_open (\n\tFIL* fp,\t\t\t/* Pointer to the blank file object */\n\tconst TCHAR* path,\t/* Pointer to the file name */\n\tBYTE mode\t\t\t/* Access mode and file open mode flags */\n)\n{\n\tFRESULT res;\n\tDIR dj;\n\tFATFS *fs;\n#if !FF_FS_READONLY\n\tDWORD dw, cl, bcs, clst, sc;\n\tFSIZE_t ofs;\n#endif\n\tDEF_NAMBUF\n\n\n\tif (!fp) return FR_INVALID_OBJECT;\n\n\t/* Get logical drive number */\n\tmode &= FF_FS_READONLY ? FA_READ : FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_CREATE_NEW | FA_OPEN_ALWAYS | FA_OPEN_APPEND;\n\tres = find_volume(&path, &fs, mode);\n\tif (res == FR_OK) {\n\t\tdj.obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\t\tres = follow_path(&dj, path);\t/* Follow the file path */\n#if !FF_FS_READONLY\t/* Read/Write configuration */\n\t\tif (res == FR_OK) {\n\t\t\tif (dj.fn[NSFLAG] & NS_NONAME) {\t/* Origin directory itself? */\n\t\t\t\tres = FR_INVALID_NAME;\n\t\t\t}\n#if FF_FS_LOCK != 0\n\t\t\telse {\n\t\t\t\tres = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0);\t\t/* Check if the file can be used */\n\t\t\t}\n#endif\n\t\t}\n\t\t/* Create or Open a file */\n\t\tif (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) {\n\t\t\tif (res != FR_OK) {\t\t\t\t\t/* No file, create new */\n\t\t\t\tif (res == FR_NO_FILE) {\t\t/* There is no file to open, create a new entry */\n#if FF_FS_LOCK != 0\n\t\t\t\t\tres = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES;\n#else\n\t\t\t\t\tres = dir_register(&dj);\n#endif\n\t\t\t\t}\n\t\t\t\tmode |= FA_CREATE_ALWAYS;\t\t/* File is created */\n\t\t\t}\n\t\t\telse {\t\t\t\t\t\t\t\t/* Any object with the same name is already existing */\n\t\t\t\tif (dj.obj.attr & (AM_RDO | AM_DIR)) {\t/* Cannot overwrite it (R/O or DIR) */\n\t\t\t\t\tres = FR_DENIED;\n\t\t\t\t} else {\n\t\t\t\t\tif (mode & FA_CREATE_NEW) res = FR_EXIST;\t/* Cannot create as new file */\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (res == FR_OK && (mode & FA_CREATE_ALWAYS)) {\t/* Truncate the file if overwrite mode */\n#if FF_FS_EXFAT\n\t\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\t\t/* Get current allocation info */\n\t\t\t\t\tfp->obj.fs = fs;\n\t\t\t\t\tinit_alloc_info(fs, &fp->obj);\n\t\t\t\t\t/* Set directory entry block initial state */\n\t\t\t\t\tmem_set(fs->dirbuf + 2, 0, 30);\t\t/* Clear 85 entry except for NumSec */\n\t\t\t\t\tmem_set(fs->dirbuf + 38, 0, 26);\t/* Clear C0 entry except for NumName and NameHash */\n\t\t\t\t\tfs->dirbuf[XDIR_Attr] = AM_ARC;\n\t\t\t\t\tst_dword(fs->dirbuf + XDIR_CrtTime, GET_FATTIME());\n\t\t\t\t\tfs->dirbuf[XDIR_GenFlags] = 1;\n\t\t\t\t\tres = store_xdir(&dj);\n\t\t\t\t\tif (res == FR_OK && fp->obj.sclust != 0) {\t/* Remove the cluster chain if exist */\n\t\t\t\t\t\tres = remove_chain(&fp->obj, fp->obj.sclust, 0);\n\t\t\t\t\t\tfs->last_clst = fp->obj.sclust - 1;\t\t/* Reuse the cluster hole */\n\t\t\t\t\t}\n\t\t\t\t} else\n#endif\n\t\t\t\t{\n\t\t\t\t\t/* Set directory entry initial state */\n\t\t\t\t\tcl = ld_clust(fs, dj.dir);\t\t\t/* Get current cluster chain */\n\t\t\t\t\tst_dword(dj.dir + DIR_CrtTime, GET_FATTIME());\t/* Set created time */\n\t\t\t\t\tdj.dir[DIR_Attr] = AM_ARC;\t\t\t/* Reset attribute */\n\t\t\t\t\tst_clust(fs, dj.dir, 0);\t\t\t/* Reset file allocation info */\n\t\t\t\t\tst_dword(dj.dir + DIR_FileSize, 0);\n\t\t\t\t\tfs->wflag = 1;\n\t\t\t\t\tif (cl != 0) {\t\t\t\t\t\t/* Remove the cluster chain if exist */\n\t\t\t\t\t\tdw = fs->winsect;\n\t\t\t\t\t\tres = remove_chain(&dj.obj, cl, 0);\n\t\t\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\t\t\tres = move_window(fs, dw);\n\t\t\t\t\t\t\tfs->last_clst = cl - 1;\t\t/* Reuse the cluster hole */\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\t/* Open an existing file */\n\t\t\tif (res == FR_OK) {\t\t\t\t\t/* Is the object exsiting? */\n\t\t\t\tif (dj.obj.attr & AM_DIR) {\t\t/* File open against a directory */\n\t\t\t\t\tres = FR_NO_FILE;\n\t\t\t\t} else {\n\t\t\t\t\tif ((mode & FA_WRITE) && (dj.obj.attr & AM_RDO)) { /* Write mode open against R/O file */\n\t\t\t\t\t\tres = FR_DENIED;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (res == FR_OK) {\n\t\t\tif (mode & FA_CREATE_ALWAYS) mode |= FA_MODIFIED;\t/* Set file change flag if created or overwritten */\n\t\t\tfp->dir_sect = fs->winsect;\t\t\t/* Pointer to the directory entry */\n\t\t\tfp->dir_ptr = dj.dir;\n#if FF_FS_LOCK != 0\n\t\t\tfp->obj.lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0);\t/* Lock the file for this session */\n\t\t\tif (fp->obj.lockid == 0) res = FR_INT_ERR;\n#endif\n\t\t}\n#else\t\t/* R/O configuration */\n\t\tif (res == FR_OK) {\n\t\t\tif (dj.fn[NSFLAG] & NS_NONAME) {\t/* Is it origin directory itself? */\n\t\t\t\tres = FR_INVALID_NAME;\n\t\t\t} else {\n\t\t\t\tif (dj.obj.attr & AM_DIR) {\t\t/* Is it a directory? */\n\t\t\t\t\tres = FR_NO_FILE;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n#endif\n\n\t\tif (res == FR_OK) {\n#if FF_FS_EXFAT\n\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\tfp->obj.c_scl = dj.obj.sclust;\t\t\t\t\t\t\t/* Get containing directory info */\n\t\t\t\tfp->obj.c_size = ((DWORD)dj.obj.objsize & 0xFFFFFF00) | dj.obj.stat;\n\t\t\t\tfp->obj.c_ofs = dj.blk_ofs;\n\t\t\t\tinit_alloc_info(fs, &fp->obj);\n\t\t\t} else\n#endif\n\t\t\t{\n\t\t\t\tfp->obj.sclust = ld_clust(fs, dj.dir);\t\t\t\t\t/* Get object allocation info */\n\t\t\t\tfp->obj.objsize = ld_dword(dj.dir + DIR_FileSize);\n\t\t\t}\n#if FF_USE_FASTSEEK\n\t\t\tfp->cltbl = 0;\t\t\t/* Disable fast seek mode */\n#endif\n\t\t\tfp->obj.fs = fs;\t \t/* Validate the file object */\n\t\t\tfp->obj.id = fs->id;\n\t\t\tfp->flag = mode;\t\t/* Set file access mode */\n\t\t\tfp->err = 0;\t\t\t/* Clear error flag */\n\t\t\tfp->sect = 0;\t\t\t/* Invalidate current data sector */\n\t\t\tfp->fptr = 0;\t\t\t/* Set file pointer top of the file */\n#if !FF_FS_READONLY\n#if !FF_FS_TINY\n\t\t\tmem_set(fp->buf, 0, sizeof fp->buf);\t/* Clear sector buffer */\n#endif\n\t\t\tif ((mode & FA_SEEKEND) && fp->obj.objsize > 0) {\t/* Seek to end of file if FA_OPEN_APPEND is specified */\n\t\t\t\tfp->fptr = fp->obj.objsize;\t\t\t/* Offset to seek */\n\t\t\t\tbcs = (DWORD)fs->csize * SS(fs);\t/* Cluster size in byte */\n\t\t\t\tclst = fp->obj.sclust;\t\t\t\t/* Follow the cluster chain */\n\t\t\t\tfor (ofs = fp->obj.objsize; res == FR_OK && ofs > bcs; ofs -= bcs) {\n\t\t\t\t\tclst = get_fat(&fp->obj, clst);\n\t\t\t\t\tif (clst <= 1) res = FR_INT_ERR;\n\t\t\t\t\tif (clst == 0xFFFFFFFF) res = FR_DISK_ERR;\n\t\t\t\t}\n\t\t\t\tfp->clust = clst;\n\t\t\t\tif (res == FR_OK && ofs % SS(fs)) {\t/* Fill sector buffer if not on the sector boundary */\n\t\t\t\t\tif ((sc = clst2sect(fs, clst)) == 0) {\n\t\t\t\t\t\tres = FR_INT_ERR;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfp->sect = sc + (DWORD)(ofs / SS(fs));\n#if !FF_FS_TINY\n\t\t\t\t\t\tif (disk_read(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) res = FR_DISK_ERR;\n#endif\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n#endif\n\t\t}\n\n\t\tFREE_NAMBUF();\n\t}\n\n\tif (res != FR_OK) fp->obj.fs = 0;\t/* Invalidate file object on error */\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Read File                                                             */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_read (\n\tFIL* fp, \t/* Pointer to the file object */\n\tvoid* buff,\t/* Pointer to data buffer */\n\tUINT btr,\t/* Number of bytes to read */\n\tUINT* br\t/* Pointer to number of bytes read */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDWORD clst, sect;\n\tFSIZE_t remain;\n\tUINT rcnt, cc, csect;\n\tBYTE *rbuff = (BYTE*)buff;\n\n\tUINT br_tmp;\n\tif (!br)\n\t\tbr = &br_tmp;\n\t*br = 0;\t/* Clear read byte counter */\n\tres = validate(&fp->obj, &fs);\t\t\t\t/* Check validity of the file object */\n\tif (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {\n\t\tEFSPRINTF(\"FOV\");\n\t\tLEAVE_FF(fs, res);\t/* Check validity */\n\t}\n\tif (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */\n\tremain = fp->obj.objsize - fp->fptr;\n\tif (btr > remain) btr = (UINT)remain;\t\t/* Truncate btr by remaining bytes */\n\n\tfor ( ;  btr;\t\t\t\t\t\t\t\t/* Repeat until btr bytes read */\n\t\tbtr -= rcnt, *br += rcnt, rbuff += rcnt, fp->fptr += rcnt) {\n\t\tif (fp->fptr % SS(fs) == 0) {\t\t\t/* On the sector boundary? */\n\t\t\tcsect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1));\t/* Sector offset in the cluster */\n\t\t\tif (csect == 0) {\t\t\t\t\t/* On the cluster boundary? */\n\t\t\t\tif (fp->fptr == 0) {\t\t\t/* On the top of the file? */\n\t\t\t\t\tclst = fp->obj.sclust;\t\t/* Follow cluster chain from the origin */\n\t\t\t\t} else {\t\t\t\t\t\t/* Middle or end of the file */\n#if FF_USE_FASTSEEK\n\t\t\t\t\tif (fp->cltbl) {\n\t\t\t\t\t\tclst = clmt_clust(fp, fp->fptr);\t/* Get cluster# from the CLMT */\n\t\t\t\t\t} else\n#endif\n\t\t\t\t\t{\n\t\t\t\t\t\tclst = get_fat(&fp->obj, fp->clust);\t/* Follow cluster chain on the FAT */\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (clst < 2) {\n\t\t\t\t\tEFSPRINTF(\"CCHK\");\n\t\t\t\t\tABORT(fs, FR_INT_ERR);\n\t\t\t\t}\n\t\t\t\tif (clst == 0xFFFFFFFF) {\n\t\t\t\t\tEFSPRINTF(\"DSKC\");\n\t\t\t\t\tABORT(fs, FR_DISK_ERR);\n\t\t\t\t}\n\t\t\t\tfp->clust = clst;\t\t\t\t/* Update current cluster */\n\t\t\t}\n\t\t\tsect = clst2sect(fs, fp->clust);\t/* Get current sector */\n\t\t\tif (sect == 0) ABORT(fs, FR_INT_ERR);\n\t\t\tsect += csect;\n\t\t\tcc = btr / SS(fs);\t\t\t\t\t/* When remaining bytes >= sector size, */\n\t\t\tif (cc > 0) {\t\t\t\t\t\t/* Read maximum contiguous sectors directly */\n\t\t\t\tif (csect + cc > fs->csize) {\t/* Clip at cluster boundary */\n\t\t\t\t\tcc = fs->csize - csect;\n\t\t\t\t}\n\t\t\t\tif (disk_read(fs->pdrv, rbuff, sect, cc) != RES_OK) {\n\t\t\t\t\tEFSPRINTF(\"RLIO\");\n\t\t\t\t\tABORT(fs, FR_DISK_ERR);\n\t\t\t\t}\n#if !FF_FS_READONLY && FF_FS_MINIMIZE <= 2\t\t/* Replace one of the read sectors with cached data if it contains a dirty sector */\n#if FF_FS_TINY\n\t\t\t\tif (fs->wflag && fs->winsect - sect < cc) {\n\t\t\t\t\tmem_cpy(rbuff + ((fs->winsect - sect) * SS(fs)), fs->win, SS(fs));\n\t\t\t\t}\n#else\n\t\t\t\tif ((fp->flag & FA_DIRTY) && fp->sect - sect < cc) {\n\t\t\t\t\tmem_cpy(rbuff + ((fp->sect - sect) * SS(fs)), fp->buf, SS(fs));\n\t\t\t\t}\n#endif\n#endif\n\t\t\t\trcnt = SS(fs) * cc;\t\t\t\t/* Number of bytes transferred */\n\t\t\t\tcontinue;\n\t\t\t}\n#if !FF_FS_TINY\n\t\t\tif (fp->sect != sect) {\t\t\t/* Load data sector if not in cache */\n#if !FF_FS_READONLY\n\t\t\t\tif (fp->flag & FA_DIRTY) {\t\t/* Write-back dirty sector cache */\n\t\t\t\t\tif (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) {\n\t\t\t\t\t\tEFSPRINTF(\"RDC\");\n\t\t\t\t\t\tABORT(fs, FR_DISK_ERR);\n\t\t\t\t\t}\n\t\t\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t\t\t}\n#endif\n\t\t\t\tif (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) {\n\t\t\t\t\tEFSPRINTF(\"RSC\");\n\t\t\t\t\tABORT(fs, FR_DISK_ERR);\t/* Fill sector cache */\n\t\t\t\t}\n\t\t\t}\n#endif\n\t\t\tfp->sect = sect;\n\t\t}\n\t\trcnt = SS(fs) - (UINT)fp->fptr % SS(fs);\t/* Number of bytes left in the sector */\n\t\tif (rcnt > btr) rcnt = btr;\t\t\t\t\t/* Clip it by btr if needed */\n#if FF_FS_TINY\n\t\tif (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR);\t/* Move sector window */\n\t\tmem_cpy(rbuff, fs->win + fp->fptr % SS(fs), rcnt);\t/* Extract partial sector */\n#else\n\t\tmem_cpy(rbuff, fp->buf + fp->fptr % SS(fs), rcnt);\t/* Extract partial sector */\n#endif\n\t}\n\n\tLEAVE_FF(fs, FR_OK);\n}\n\n\n\n\n#ifdef FF_FASTFS\n/*-----------------------------------------------------------------------*/\n/* Fast Read Aligned Sized File Without a Cache                         */\n/*-----------------------------------------------------------------------*/\n#if FF_USE_FASTSEEK\nFRESULT f_read_fast (\n\tFIL* fp,\t\t\t/* Pointer to the file object */\n\tconst void* buff,\t/* Pointer to the data to be written */\n\tUINT btr\t\t\t/* Number of bytes to read */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tUINT csize_bytes;\n\tDWORD clst;\n\tUINT count = 0;\n\tFSIZE_t work_sector = 0;\n\tFSIZE_t sector_base = 0;\n\tBYTE *wbuff = (BYTE*)buff;\n\n\t// TODO support sector reading inside a cluster\n\n\tres = validate(&fp->obj, &fs);\t\t\t/* Check validity of the file object */\n\tif (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {\n\t\tEFSPRINTF(\"FOV\");\n\t\tLEAVE_FF(fs, res);\t/* Check validity */\n\t}\n\n\tif (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */\n\tFSIZE_t remain = fp->obj.objsize - fp->fptr;\n\tif (btr > remain) btr = (UINT)remain;\t\t/* Truncate btr by remaining bytes */\n\n\tcsize_bytes = fs->csize * SS(fs);\n\n\tif (!fp->fptr) {\t/* On the top of the file? */\n\t\tclst = fp->obj.sclust;\t/* Follow from the origin */\n\t} else {\n\t\tif (fp->cltbl) clst = clmt_clust(fp, fp->fptr);\t/* Get cluster# from the CLMT */\n\t\telse { EFSPRINTF(\"CLTBL\"); ABORT(fs, FR_CLTBL_NO_INIT); }\n\t}\n\tif (clst < 2) { EFSPRINTF(\"CCHK\"); ABORT(fs, FR_INT_ERR); }\n\telse if (clst == 0xFFFFFFFF) { EFSPRINTF(\"DSKC\"); ABORT(fs, FR_DISK_ERR); }\n\n\tfp->clust = clst;\t/* Set working cluster */\n\t\n\tsector_base = clst2sect(fs, fp->clust);\n\tcount += fs->csize;\n\tbtr -= csize_bytes;\n\tfp->fptr += csize_bytes;\n\n\twhile (btr) {\n\t\tclst = clmt_clust(fp, fp->fptr);\t/* Get cluster# from the CLMT */\n\n\t\tif (clst < 2) { EFSPRINTF(\"CCHK2\"); ABORT(fs, FR_INT_ERR); }\n\t\telse if (clst == 0xFFFFFFFF) { EFSPRINTF(\"DSKC\"); ABORT(fs, FR_DISK_ERR); }\n\n\t\tfp->clust = clst;\n\n\t\twork_sector = clst2sect(fs, fp->clust);\n\t\tif ((work_sector - sector_base) == count) count += fs->csize;\n\t\telse {\n\t\t\tif (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t\twbuff += count * SS(fs);\n\n\t\t\tsector_base = work_sector;\n\t\t\tcount = fs->csize;\n\t\t}\n\n\t\tfp->fptr += MIN(btr, csize_bytes);\n\t\tbtr -= MIN(btr, csize_bytes);\n\n\t\t// TODO: what about if data is smaller than cluster?\n\t\t// Must read-write back that cluster.\n\n\t\tif (!btr) {\t/* Final cluster/sectors read. */\n\t\t\tif (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t}\n\t}\n\n\tLEAVE_FF(fs, FR_OK);\n}\n#endif\n#endif\n\n\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Write File                                                            */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_write (\n\tFIL* fp,\t\t\t/* Pointer to the file object */\n\tconst void* buff,\t/* Pointer to the data to be written */\n\tUINT btw,\t\t\t/* Number of bytes to write */\n\tUINT* bw\t\t\t/* Pointer to number of bytes written */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDWORD clst, sect;\n\tUINT wcnt, cc, csect;\n\tconst BYTE *wbuff = (const BYTE*)buff;\n\n\tUINT bw_tmp;\n\tif (!bw)\n\t\tbw = &bw_tmp;\n\t*bw = 0;\t/* Clear write byte counter */\n\tres = validate(&fp->obj, &fs);\t\t\t/* Check validity of the file object */\n\tif (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {\n\t\tEFSPRINTF(\"FOV\");\n\t\tLEAVE_FF(fs, res);\t/* Check validity */\n\t}\n\tif (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED);\t/* Check access mode */\n\n\t/* Check fptr wrap-around (file size cannot reach 4 GiB at FAT volume) */\n\tif ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) {\n\t\tbtw = (UINT)(0xFFFFFFFF - (DWORD)fp->fptr);\n\t}\n\n\tfor ( ;  btw;\t\t\t\t\t\t\t/* Repeat until all data written */\n\t\tbtw -= wcnt, *bw += wcnt, wbuff += wcnt, fp->fptr += wcnt, fp->obj.objsize = (fp->fptr > fp->obj.objsize) ? fp->fptr : fp->obj.objsize) {\n\t\tif (fp->fptr % SS(fs) == 0) {\t\t/* On the sector boundary? */\n\t\t\tcsect = (UINT)(fp->fptr / SS(fs)) & (fs->csize - 1);\t/* Sector offset in the cluster */\n\t\t\tif (csect == 0) {\t\t\t\t/* On the cluster boundary? */\n\t\t\t\tif (fp->fptr == 0) {\t\t/* On the top of the file? */\n\t\t\t\t\tclst = fp->obj.sclust;\t/* Follow from the origin */\n\t\t\t\t\tif (clst == 0) {\t\t/* If no cluster is allocated, */\n\t\t\t\t\t\tclst = create_chain(&fp->obj, 0);\t/* create a new cluster chain */\n\t\t\t\t\t}\n\t\t\t\t} else {\t\t\t\t\t/* On the middle or end of the file */\n#if FF_USE_FASTSEEK\n\t\t\t\t\tif (fp->cltbl) {\n\t\t\t\t\t\tclst = clmt_clust(fp, fp->fptr);\t/* Get cluster# from the CLMT */\n\t\t\t\t\t} else\n#endif\n\t\t\t\t\t{\n\t\t\t\t\t\tclst = create_chain(&fp->obj, fp->clust);\t/* Follow or stretch cluster chain on the FAT */\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (clst == 0) {\n\t\t\t\t\tEFSPRINTF(\"DSKFULL\");\n\t\t\t\t\tbreak;\t\t/* Could not allocate a new cluster (disk full) */\n\t\t\t\t}\n\t\t\t\tif (clst == 1) {\n\t\t\t\t\tEFSPRINTF(\"CCHK\");\n\t\t\t\t\tABORT(fs, FR_INT_ERR);\n\t\t\t\t}\n\t\t\t\tif (clst == 0xFFFFFFFF) {\n\t\t\t\t\tEFSPRINTF(\"DERR\");\n\t\t\t\t\tABORT(fs, FR_DISK_ERR);\n\t\t\t\t}\n\t\t\t\tfp->clust = clst;\t\t\t/* Update current cluster */\n\t\t\t\tif (fp->obj.sclust == 0) fp->obj.sclust = clst;\t/* Set start cluster if the first write */\n\t\t\t}\n#if FF_FS_TINY\n\t\t\tif (fs->winsect == fp->sect && sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR);\t/* Write-back sector cache */\n#else\n\t\t\tif (fp->flag & FA_DIRTY) {\t\t/* Write-back sector cache */\n\t\t\t\tif (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t\t}\n#endif\n\t\t\tsect = clst2sect(fs, fp->clust);\t/* Get current sector */\n\t\t\tif (sect == 0) ABORT(fs, FR_INT_ERR);\n\t\t\tsect += csect;\n\t\t\tcc = btw / SS(fs);\t\t\t\t/* When remaining bytes >= sector size, */\n\t\t\tif (cc > 0) {\t\t\t\t\t/* Write maximum contiguous sectors directly */\n\t\t\t\tif (csect + cc > fs->csize) {\t/* Clip at cluster boundary */\n\t\t\t\t\tcc = fs->csize - csect;\n\t\t\t\t}\n\t\t\t\tif (disk_write(fs->pdrv, wbuff, sect, cc) != RES_OK) {\n\t\t\t\t\tEFSPRINTF(\"WLIO\");\n\t\t\t\t\tABORT(fs, FR_DISK_ERR);\n\t\t\t\t}\n#if FF_FS_MINIMIZE <= 2\n#if FF_FS_TINY\n\t\t\t\tif (fs->winsect - sect < cc) {\t/* Refill sector cache if it gets invalidated by the direct write */\n\t\t\t\t\tmem_cpy(fs->win, wbuff + ((fs->winsect - sect) * SS(fs)), SS(fs));\n\t\t\t\t\tfs->wflag = 0;\n\t\t\t\t}\n#else\n\t\t\t\tif (fp->sect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */\n\t\t\t\t\tmem_cpy(fp->buf, wbuff + ((fp->sect - sect) * SS(fs)), SS(fs));\n\t\t\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t\t\t}\n#endif\n#endif\n\t\t\t\twcnt = SS(fs) * cc;\t\t/* Number of bytes transferred */\n\t\t\t\tcontinue;\n\t\t\t}\n#if FF_FS_TINY\n\t\t\tif (fp->fptr >= fp->obj.objsize) {\t/* Avoid silly cache filling on the growing edge */\n\t\t\t\tif (sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR);\n\t\t\t\tfs->winsect = sect;\n\t\t\t}\n#else\n\t\t\tif (fp->sect != sect && \t\t/* Fill sector cache with file data */\n\t\t\t\tfp->fptr < fp->obj.objsize &&\n\t\t\t\tdisk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) {\n\t\t\t\t\tABORT(fs, FR_DISK_ERR);\n\t\t\t}\n#endif\n\t\t\tfp->sect = sect;\n\t\t}\n\t\twcnt = SS(fs) - (UINT)fp->fptr % SS(fs);\t/* Number of bytes left in the sector */\n\t\tif (wcnt > btw) wcnt = btw;\t\t\t\t\t/* Clip it by btw if needed */\n#if FF_FS_TINY\n\t\tif (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR);\t/* Move sector window */\n\t\tmem_cpy(fs->win + fp->fptr % SS(fs), wbuff, wcnt);\t/* Fit data to the sector */\n\t\tfs->wflag = 1;\n#else\n\t\tmem_cpy(fp->buf + fp->fptr % SS(fs), wbuff, wcnt);\t/* Fit data to the sector */\n\t\tfp->flag |= FA_DIRTY;\n#endif\n\t}\n\n\tfp->flag |= FA_MODIFIED;\t\t\t\t/* Set file change flag */\n\n\tLEAVE_FF(fs, FR_OK);\n}\n\n\n\n\n#ifdef FF_FASTFS\n/*-----------------------------------------------------------------------*/\n/* Fast Write Aligned Sized File Without a Cache                         */\n/*-----------------------------------------------------------------------*/\n#if FF_USE_FASTSEEK\nFRESULT f_write_fast (\n\tFIL* fp,\t\t\t/* Pointer to the file object */\n\tconst void* buff,\t/* Pointer to the data to be written */\n\tUINT btw\t\t\t/* Number of bytes to write */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tUINT csize_bytes;\n\tDWORD clst;\n\tUINT count = 0;\n\tFSIZE_t work_sector = 0;\n\tFSIZE_t sector_base = 0;\n\tconst BYTE *wbuff = (const BYTE*)buff;\n\n\t// TODO support sector writing inside a cluster\n\n\tres = validate(&fp->obj, &fs);\t\t\t/* Check validity of the file object */\n\tif (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {\n\t\tEFSPRINTF(\"FOV\");\n\t\tLEAVE_FF(fs, res);\t/* Check validity */\n\t}\n\n\tif (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED);\t/* Check access mode */\n\t/* Check fptr wrap-around (file size cannot reach 4 GiB at FAT volume) */\n\tif ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) {\n\t\tbtw = (UINT)(0xFFFFFFFF - (DWORD)fp->fptr);\n\t}\n\n\tcsize_bytes = fs->csize * SS(fs);\n\n\tif (!fp->fptr) {\t/* On the top of the file? */\n\t\tclst = fp->obj.sclust;\t/* Follow from the origin */\n\t} else {\n\t\tif (fp->cltbl) clst = clmt_clust(fp, fp->fptr);\t/* Get cluster# from the CLMT */\n\t\telse { EFSPRINTF(\"CLTBL\"); ABORT(fs, FR_CLTBL_NO_INIT); }\n\t}\n\n\tif (clst < 2) { EFSPRINTF(\"CCHK\"); ABORT(fs, FR_INT_ERR); }\n\telse if (clst == 0xFFFFFFFF) { EFSPRINTF(\"DERR\"); ABORT(fs, FR_DISK_ERR); }\n\n\tfp->clust = clst;\t/* Set working cluster */\n\t\n\tsector_base = clst2sect(fs, fp->clust);\n\tcount += fs->csize;\n\tbtw -= csize_bytes;\n\tfp->fptr += csize_bytes;\n\n\twhile (btw) {\n\t\tclst = clmt_clust(fp, fp->fptr);\t/* Get cluster# from the CLMT */\n\n\t\tif (clst < 2) { EFSPRINTF(\"CCHK2\"); ABORT(fs, FR_INT_ERR); }\n\t\telse if (clst == 0xFFFFFFFF) { EFSPRINTF(\"DERR\"); ABORT(fs, FR_DISK_ERR); }\n\n\t\tfp->clust = clst;\n\n\t\twork_sector = clst2sect(fs, fp->clust);\n\t\tif ((work_sector - sector_base) == count) count += fs->csize;\n\t\telse {\n\t\t\tif (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t\twbuff += count * SS(fs);\n\n\t\t\tsector_base = work_sector;\n\t\t\tcount = fs->csize;\n\t\t}\n\n\t\tfp->fptr += MIN(btw, csize_bytes);\n\t\tbtw -= MIN(btw, csize_bytes);\n\n\t\t// what about if data is smaller than cluster?\n\t\t// Probably must read-write back that cluster.\n\t\tif (!btw) {\t/* Final cluster/sectors write. */\n\t\t\tif (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t}\n\t}\n\n\tfp->flag |= FA_MODIFIED;\t/* Set file change flag */\n\n\tLEAVE_FF(fs, FR_OK);\n}\n#endif\n#endif\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Synchronize the File                                                  */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_sync (\n\tFIL* fp\t\t/* Pointer to the file object */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDWORD tm;\n\tBYTE *dir;\n\n\n\tres = validate(&fp->obj, &fs);\t/* Check validity of the file object */\n\tif (res == FR_OK) {\n\t\tif (fp->flag & FA_MODIFIED) {\t/* Is there any change to the file? */\n#if !FF_FS_TINY\n\t\t\tif (fp->flag & FA_DIRTY) {\t/* Write-back cached data if needed */\n\t\t\t\tif (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) LEAVE_FF(fs, FR_DISK_ERR);\n\t\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t\t}\n#endif\n\t\t\t/* Update the directory entry */\n\t\t\ttm = GET_FATTIME();\t\t\t\t/* Modified time */\n#if FF_FS_EXFAT\n\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\tres = fill_first_frag(&fp->obj);\t/* Fill first fragment on the FAT if needed */\n\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\tres = fill_last_frag(&fp->obj, fp->clust, 0xFFFFFFFF);\t/* Fill last fragment on the FAT if needed */\n\t\t\t\t}\n\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\tDIR dj;\n\t\t\t\t\tDEF_NAMBUF\n\n\t\t\t\t\tINIT_NAMBUF(fs);\n\t\t\t\t\tres = load_obj_xdir(&dj, &fp->obj);\t/* Load directory entry block */\n\t\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\t\tfs->dirbuf[XDIR_Attr] |= AM_ARC;\t\t\t\t/* Set archive attribute to indicate that the file has been changed */\n\t\t\t\t\t\tfs->dirbuf[XDIR_GenFlags] = fp->obj.stat | 1;\t/* Update file allocation information */\n\t\t\t\t\t\tst_dword(fs->dirbuf + XDIR_FstClus, fp->obj.sclust);\n\t\t\t\t\t\tst_qword(fs->dirbuf + XDIR_FileSize, fp->obj.objsize);\n\t\t\t\t\t\tst_qword(fs->dirbuf + XDIR_ValidFileSize, fp->obj.objsize);\n\t\t\t\t\t\tst_dword(fs->dirbuf + XDIR_ModTime, tm);\t\t/* Update modified time */\n\t\t\t\t\t\tfs->dirbuf[XDIR_ModTime10] = 0;\n\t\t\t\t\t\tst_dword(fs->dirbuf + XDIR_AccTime, 0);\n\t\t\t\t\t\tres = store_xdir(&dj);\t/* Restore it to the directory */\n\t\t\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\t\t\tres = sync_fs(fs);\n\t\t\t\t\t\t\tfp->flag &= (BYTE)~FA_MODIFIED;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tFREE_NAMBUF();\n\t\t\t\t}\n\t\t\t} else\n#endif\n\t\t\t{\n\t\t\t\tres = move_window(fs, fp->dir_sect);\n\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\tdir = fp->dir_ptr;\n\t\t\t\t\tdir[DIR_Attr] |= AM_ARC;\t\t\t\t\t\t/* Set archive attribute to indicate that the file has been changed */\n\t\t\t\t\tst_clust(fp->obj.fs, dir, fp->obj.sclust);\t\t/* Update file allocation information  */\n\t\t\t\t\tst_dword(dir + DIR_FileSize, (DWORD)fp->obj.objsize);\t/* Update file size */\n\t\t\t\t\tst_dword(dir + DIR_ModTime, tm);\t\t\t\t/* Update modified time */\n\t\t\t\t\tst_word(dir + DIR_LstAccDate, 0);\n\t\t\t\t\tfs->wflag = 1;\n\t\t\t\t\tres = sync_fs(fs);\t\t\t\t\t/* Restore it to the directory */\n\t\t\t\t\tfp->flag &= (BYTE)~FA_MODIFIED;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n#endif /* !FF_FS_READONLY */\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Close File                                                            */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_close (\n\tFIL* fp\t\t/* Pointer to the file object to be closed */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\n#if !FF_FS_READONLY\n\tres = f_sync(fp);\t\t\t\t\t/* Flush cached data */\n\tif (res == FR_OK)\n#endif\n\t{\n\t\tres = validate(&fp->obj, &fs);\t/* Lock volume */\n\t\tif (res == FR_OK) {\n#if FF_FS_LOCK != 0\n\t\t\tres = dec_lock(fp->obj.lockid);\t\t/* Decrement file open counter */\n\t\t\tif (res == FR_OK) fp->obj.fs = 0;\t/* Invalidate file object */\n#else\n\t\t\tfp->obj.fs = 0;\t/* Invalidate file object */\n#endif\n#if FF_FS_REENTRANT\n\t\t\tunlock_fs(fs, FR_OK);\t\t/* Unlock volume */\n#endif\n\t\t}\n\t}\n\treturn res;\n}\n\n\n\n\n#if FF_FS_RPATH >= 1\n/*-----------------------------------------------------------------------*/\n/* Change Current Directory or Current Drive, Get Current Directory      */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_chdrive (\n\tconst TCHAR* path\t\t/* Drive number to set */\n)\n{\n\tint vol;\n\n\n\t/* Get logical drive number */\n\tvol = get_ldnumber(&path);\n\tif (vol < 0) return FR_INVALID_DRIVE;\n\tCurrVol = (BYTE)vol;\t/* Set it as current volume */\n\n\treturn FR_OK;\n}\n\n\n\nFRESULT f_chdir (\n\tconst TCHAR* path\t/* Pointer to the directory path */\n)\n{\n#if FF_STR_VOLUME_ID == 2\n\tUINT i;\n#endif\n\tFRESULT res;\n\tDIR dj;\n\tFATFS *fs;\n\tDEF_NAMBUF\n\n\n\t/* Get logical drive */\n\tres = find_volume(&path, &fs, 0);\n\tif (res == FR_OK) {\n\t\tdj.obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\t\tres = follow_path(&dj, path);\t\t/* Follow the path */\n\t\tif (res == FR_OK) {\t\t\t\t\t/* Follow completed */\n\t\t\tif (dj.fn[NSFLAG] & NS_NONAME) {\t/* Is it the start directory itself? */\n\t\t\t\tfs->cdir = dj.obj.sclust;\n#if FF_FS_EXFAT\n\t\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\t\tfs->cdc_scl = dj.obj.c_scl;\n\t\t\t\t\tfs->cdc_size = dj.obj.c_size;\n\t\t\t\t\tfs->cdc_ofs = dj.obj.c_ofs;\n\t\t\t\t}\n#endif\n\t\t\t} else {\n\t\t\t\tif (dj.obj.attr & AM_DIR) {\t/* It is a sub-directory */\n#if FF_FS_EXFAT\n\t\t\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\t\t\tfs->cdir = ld_dword(fs->dirbuf + XDIR_FstClus);\t\t/* Sub-directory cluster */\n\t\t\t\t\t\tfs->cdc_scl = dj.obj.sclust;\t\t\t\t\t\t/* Save containing directory information */\n\t\t\t\t\t\tfs->cdc_size = ((DWORD)dj.obj.objsize & 0xFFFFFF00) | dj.obj.stat;\n\t\t\t\t\t\tfs->cdc_ofs = dj.blk_ofs;\n\t\t\t\t\t} else\n#endif\n\t\t\t\t\t{\n\t\t\t\t\t\tfs->cdir = ld_clust(fs, dj.dir);\t\t\t\t\t/* Sub-directory cluster */\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tres = FR_NO_PATH;\t\t/* Reached but a file */\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tFREE_NAMBUF();\n\t\tif (res == FR_NO_FILE) res = FR_NO_PATH;\n#if FF_STR_VOLUME_ID == 2\t/* Also current drive is changed at Unix style volume ID */\n\t\tif (res == FR_OK) {\n\t\t\tfor (i = FF_VOLUMES - 1; i && fs != FatFs[i]; i--) ;\t/* Set current drive */\n\t\t\tCurrVol = (BYTE)i;\n\t\t}\n#endif\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n\n#if FF_FS_RPATH >= 2\nFRESULT f_getcwd (\n\tTCHAR* buff,\t/* Pointer to the directory path */\n\tUINT len\t\t/* Size of buff in unit of TCHAR */\n)\n{\n\tFRESULT res;\n\tDIR dj;\n\tFATFS *fs;\n\tUINT i, n;\n\tDWORD ccl;\n\tTCHAR *tp = buff;\n#if FF_VOLUMES >= 2\n\tUINT vl;\n#endif\n#if FF_STR_VOLUME_ID\n\tconst char *vp;\n#endif\n\tFILINFO fno;\n\tDEF_NAMBUF\n\n\n\t/* Get logical drive */\n\tbuff[0] = 0;\t/* Set null string to get current volume */\n\tres = find_volume((const TCHAR**)&buff, &fs, 0);\t/* Get current volume */\n\tif (res == FR_OK) {\n\t\tdj.obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\n\t\t/* Follow parent directories and create the path */\n\t\ti = len;\t\t\t/* Bottom of buffer (directory stack base) */\n\t\tif (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) {\t/* (Cannot do getcwd on exFAT and returns root path) */\n\t\t\tdj.obj.sclust = fs->cdir;\t\t\t\t/* Start to follow upper directory from current directory */\n\t\t\twhile ((ccl = dj.obj.sclust) != 0) {\t/* Repeat while current directory is a sub-directory */\n\t\t\t\tres = dir_sdi(&dj, 1 * SZDIRE);\t/* Get parent directory */\n\t\t\t\tif (res != FR_OK) break;\n\t\t\t\tres = move_window(fs, dj.sect);\n\t\t\t\tif (res != FR_OK) break;\n\t\t\t\tdj.obj.sclust = ld_clust(fs, dj.dir);\t/* Goto parent directory */\n\t\t\t\tres = dir_sdi(&dj, 0);\n\t\t\t\tif (res != FR_OK) break;\n\t\t\t\tdo {\t\t\t\t\t\t\t/* Find the entry links to the child directory */\n\t\t\t\t\tres = DIR_READ_FILE(&dj);\n\t\t\t\t\tif (res != FR_OK) break;\n\t\t\t\t\tif (ccl == ld_clust(fs, dj.dir)) break;\t/* Found the entry */\n\t\t\t\t\tres = dir_next(&dj, 0);\n\t\t\t\t} while (res == FR_OK);\n\t\t\t\tif (res == FR_NO_FILE) res = FR_INT_ERR;/* It cannot be 'not found'. */\n\t\t\t\tif (res != FR_OK) break;\n\t\t\t\tget_fileinfo(&dj, &fno);\t\t/* Get the directory name and push it to the buffer */\n\t\t\t\tfor (n = 0; fno.fname[n]; n++) ;\t/* Name length */\n\t\t\t\tif (i < n + 1) {\t/* Insufficient space to store the path name? */\n\t\t\t\t\tres = FR_NOT_ENOUGH_CORE; break;\n\t\t\t\t}\n\t\t\t\twhile (n) buff[--i] = fno.fname[--n];\t/* Stack the name */\n\t\t\t\tbuff[--i] = '/';\n\t\t\t}\n\t\t}\n\t\tif (res == FR_OK) {\n\t\t\tif (i == len) buff[--i] = '/';\t/* Is it the root-directory? */\n#if FF_VOLUMES >= 2\t\t\t/* Put drive prefix */\n\t\t\tvl = 0;\n#if FF_STR_VOLUME_ID >= 1\t/* String volume ID */\n\t\t\tfor (n = 0, vp = (const char*)VolumeStr[CurrVol]; vp[n]; n++) ;\n\t\t\tif (i >= n + 2) {\n\t\t\t\tif (FF_STR_VOLUME_ID == 2) *tp++ = (TCHAR)'/';\n\t\t\t\tfor (vl = 0; vl < n; *tp++ = (TCHAR)vp[vl], vl++) ;\n\t\t\t\tif (FF_STR_VOLUME_ID == 1) *tp++ = (TCHAR)':';\n\t\t\t\tvl++;\n\t\t\t}\n#else\t\t\t\t\t\t/* Numeric volume ID */\n\t\t\tif (i >= 3) {\n\t\t\t\t*tp++ = (TCHAR)'0' + CurrVol;\n\t\t\t\t*tp++ = (TCHAR)':';\n\t\t\t\tvl = 2;\n\t\t\t}\n#endif\n\t\t\tif (vl == 0) res = FR_NOT_ENOUGH_CORE;\n#endif\n\t\t\t/* Add current directory path */\n\t\t\tif (res == FR_OK) {\n\t\t\t\tdo *tp++ = buff[i++]; while (i < len);\t/* Copy stacked path string */\n\t\t\t}\n\t\t}\n\t\tFREE_NAMBUF();\n\t}\n\n\t*tp = 0;\n\tLEAVE_FF(fs, res);\n}\n\n#endif /* FF_FS_RPATH >= 2 */\n#endif /* FF_FS_RPATH >= 1 */\n\n\n\n#if FF_FS_MINIMIZE <= 2\n/*-----------------------------------------------------------------------*/\n/* Seek File Read/Write Pointer                                          */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_lseek (\n\tFIL* fp,\t\t/* Pointer to the file object */\n\tFSIZE_t ofs\t\t/* File pointer from top of file */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDWORD clst, bcs, nsect;\n\tFSIZE_t ifptr;\n#if FF_USE_FASTSEEK\n\tDWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl;\n#endif\n\n\tres = validate(&fp->obj, &fs);\t\t/* Check validity of the file object */\n\tif (res == FR_OK) res = (FRESULT)fp->err;\n#if FF_FS_EXFAT && !FF_FS_READONLY\n\tif (res == FR_OK && fs->fs_type == FS_EXFAT) {\n\t\tres = fill_last_frag(&fp->obj, fp->clust, 0xFFFFFFFF);\t/* Fill last fragment on the FAT if needed */\n\t}\n#endif\n\tif (res != FR_OK) LEAVE_FF(fs, res);\n\n#if FF_USE_FASTSEEK\n\tif (fp->cltbl) {\t/* Fast seek */\n\t\tif (ofs == CREATE_LINKMAP) {\t/* Create CLMT */\n\t\t\ttbl = fp->cltbl;\n\t\t\ttlen = *tbl++; ulen = 2;\t/* Given table size and required table size */\n\t\t\tcl = fp->obj.sclust;\t\t/* Origin of the chain */\n\t\t\tif (cl != 0) {\n\t\t\t\tdo {\n\t\t\t\t\t/* Get a fragment */\n\t\t\t\t\ttcl = cl; ncl = 0; ulen += 2;\t/* Top, length and used items */\n\t\t\t\t\tdo {\n\t\t\t\t\t\tpcl = cl; ncl++;\n\t\t\t\t\t\tcl = get_fat(&fp->obj, cl);\n\t\t\t\t\t\tif (cl <= 1) ABORT(fs, FR_INT_ERR);\n\t\t\t\t\t\tif (cl == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);\n\t\t\t\t\t} while (cl == pcl + 1);\n\t\t\t\t\tif (ulen <= tlen) {\t\t/* Store the length and top of the fragment */\n\t\t\t\t\t\t*tbl++ = ncl; *tbl++ = tcl;\n\t\t\t\t\t}\n\t\t\t\t} while (cl < fs->n_fatent);\t/* Repeat until end of chain */\n\t\t\t}\n\t\t\t*fp->cltbl = ulen;\t/* Number of items used */\n\t\t\tif (ulen <= tlen) {\n\t\t\t\t*tbl = 0;\t\t/* Terminate table */\n\t\t\t} else {\n\t\t\t\tres = FR_NOT_ENOUGH_CORE;\t/* Given table size is smaller than required */\n\t\t\t}\n\t\t} else {\t\t\t\t\t\t/* Fast seek */\n\t\t\tif (ofs > fp->obj.objsize) ofs = fp->obj.objsize;\t/* Clip offset at the file size */\n\t\t\tfp->fptr = ofs;\t\t\t\t/* Set file pointer */\n\t\t\tif (ofs > 0) {\n\t\t\t\tfp->clust = clmt_clust(fp, ofs - 1);\n\t\t\t\tdsc = clst2sect(fs, fp->clust);\n\t\t\t\tif (dsc == 0) ABORT(fs, FR_INT_ERR);\n\t\t\t\tdsc += (DWORD)((ofs - 1) / SS(fs)) & (fs->csize - 1);\n\t\t\t\tif (fp->fptr % SS(fs) && dsc != fp->sect) {\t/* Refill sector cache if needed */\n#if !FF_FS_TINY\n#if !FF_FS_READONLY\n\t\t\t\t\tif (fp->flag & FA_DIRTY) {\t\t/* Write-back dirty sector cache */\n\t\t\t\t\t\tif (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t\t\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t\t\t\t}\n#endif\n\t\t\t\t\tif (disk_read(fs->pdrv, fp->buf, dsc, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);\t/* Load current sector */\n#endif\n\t\t\t\t\tfp->sect = dsc;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else\n#endif\n\n\t/* Normal Seek */\n\t{\n#if FF_FS_EXFAT\n\t\tif (fs->fs_type != FS_EXFAT && ofs >= 0x100000000) ofs = 0xFFFFFFFF;\t/* Clip at 4 GiB - 1 if at FATxx */\n#endif\n\t\tif (ofs > fp->obj.objsize && (FF_FS_READONLY || !(fp->flag & FA_WRITE))) {\t/* In read-only mode, clip offset with the file size */\n\t\t\tofs = fp->obj.objsize;\n\t\t}\n\t\tifptr = fp->fptr;\n\t\tfp->fptr = nsect = 0;\n\t\tif (ofs > 0) {\n\t\t\tbcs = (DWORD)fs->csize * SS(fs);\t/* Cluster size (byte) */\n\t\t\tif (ifptr > 0 &&\n\t\t\t\t(ofs - 1) / bcs >= (ifptr - 1) / bcs) {\t/* When seek to same or following cluster, */\n\t\t\t\tfp->fptr = (ifptr - 1) & ~(FSIZE_t)(bcs - 1);\t/* start from the current cluster */\n\t\t\t\tofs -= fp->fptr;\n\t\t\t\tclst = fp->clust;\n\t\t\t} else {\t\t\t\t\t\t\t\t\t/* When seek to back cluster, */\n\t\t\t\tclst = fp->obj.sclust;\t\t\t\t\t/* start from the first cluster */\n#if !FF_FS_READONLY\n\t\t\t\tif (clst == 0) {\t\t\t\t\t\t/* If no cluster chain, create a new chain */\n\t\t\t\t\tclst = create_chain(&fp->obj, 0);\n\t\t\t\t\tif (clst == 1) ABORT(fs, FR_INT_ERR);\n\t\t\t\t\tif (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);\n\t\t\t\t\tfp->obj.sclust = clst;\n\t\t\t\t}\n#endif\n\t\t\t\tfp->clust = clst;\n\t\t\t}\n\t\t\tif (clst != 0) {\n\t\t\t\twhile (ofs > bcs) {\t\t\t\t\t\t/* Cluster following loop */\n\t\t\t\t\tofs -= bcs; fp->fptr += bcs;\n#if !FF_FS_READONLY\n\t\t\t\t\tif (fp->flag & FA_WRITE) {\t\t\t/* Check if in write mode or not */\n\t\t\t\t\t\tif (FF_FS_EXFAT && fp->fptr > fp->obj.objsize) {\t/* No FAT chain object needs correct objsize to generate FAT value */\n\t\t\t\t\t\t\tfp->obj.objsize = fp->fptr;\n\t\t\t\t\t\t\tfp->flag |= FA_MODIFIED;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tclst = create_chain(&fp->obj, clst);\t/* Follow chain with forceed stretch */\n\t\t\t\t\t\tif (clst == 0) {\t\t\t\t/* Clip file size in case of disk full */\n\t\t\t\t\t\t\tofs = 0; break;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else\n#endif\n\t\t\t\t\t{\n\t\t\t\t\t\tclst = get_fat(&fp->obj, clst);\t/* Follow cluster chain if not in write mode */\n\t\t\t\t\t}\n\t\t\t\t\tif (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);\n\t\t\t\t\tif (clst <= 1 || clst >= fs->n_fatent) ABORT(fs, FR_INT_ERR);\n\t\t\t\t\tfp->clust = clst;\n\t\t\t\t}\n\t\t\t\tfp->fptr += ofs;\n\t\t\t\tif (ofs % SS(fs)) {\n\t\t\t\t\tnsect = clst2sect(fs, clst);\t/* Current sector */\n\t\t\t\t\tif (nsect == 0) ABORT(fs, FR_INT_ERR);\n\t\t\t\t\tnsect += (DWORD)(ofs / SS(fs));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!FF_FS_READONLY && fp->fptr > fp->obj.objsize) {\t/* Set file change flag if the file size is extended */\n\t\t\tfp->obj.objsize = fp->fptr;\n\t\t\tfp->flag |= FA_MODIFIED;\n\t\t}\n\t\tif (fp->fptr % SS(fs) && nsect != fp->sect) {\t/* Fill sector cache if needed */\n#if !FF_FS_TINY\n#if !FF_FS_READONLY\n\t\t\tif (fp->flag & FA_DIRTY) {\t\t\t/* Write-back dirty sector cache */\n\t\t\t\tif (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t\t}\n#endif\n\t\t\tif (disk_read(fs->pdrv, fp->buf, nsect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);\t/* Fill sector cache */\n#endif\n\t\t\tfp->sect = nsect;\n\t\t}\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n#ifdef FF_FASTFS\n#if FF_USE_FASTSEEK\n/*-----------------------------------------------------------------------*/\n/* Seek File Read/Write Pointer                                          */\n/*-----------------------------------------------------------------------*/\n\nDWORD *f_expand_cltbl (\n\tFIL* fp,\t\t/* Pointer to the file object */\n\tUINT tblsz,\t\t/* Size of table */\n\tFSIZE_t ofs\t\t/* File pointer from top of file */\n)\n{\n\tif (fp->flag & FA_WRITE) f_lseek(fp, ofs);\t/* Expand file if write is enabled */\n\tif (!fp->cltbl) {\t/* Allocate memory for cluster link table */\n\t\tfp->cltbl = (DWORD *)ff_memalloc(tblsz);\n\t\tfp->cltbl[0] = tblsz;\n\t}\n\tif (f_lseek(fp, CREATE_LINKMAP)) {\t/* Create cluster link table */\n\t\tff_memfree(fp->cltbl);\n\t\tfp->cltbl = NULL;\n\t\tEFSPRINTF(\"CLTBLSZ\");\n\t\treturn NULL;\n\t}\n\tf_lseek(fp, 0);\n\n\treturn fp->cltbl;\n}\n#endif\n#endif\n\n\n\n\n#if FF_FS_MINIMIZE <= 1\n/*-----------------------------------------------------------------------*/\n/* Create a Directory Object                                             */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_opendir (\n\tDIR* dp,\t\t\t/* Pointer to directory object to create */\n\tconst TCHAR* path\t/* Pointer to the directory path */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDEF_NAMBUF\n\n\n\tif (!dp) return FR_INVALID_OBJECT;\n\n\t/* Get logical drive */\n\tres = find_volume(&path, &fs, 0);\n\tif (res == FR_OK) {\n\t\tdp->obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\t\tres = follow_path(dp, path);\t\t\t/* Follow the path to the directory */\n\t\tif (res == FR_OK) {\t\t\t\t\t\t/* Follow completed */\n\t\t\tif (!(dp->fn[NSFLAG] & NS_NONAME)) {\t/* It is not the origin directory itself */\n\t\t\t\tif (dp->obj.attr & AM_DIR) {\t\t/* This object is a sub-directory */\n#if FF_FS_EXFAT\n\t\t\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\t\t\tdp->obj.c_scl = dp->obj.sclust;\t\t\t\t\t\t\t/* Get containing directory inforamation */\n\t\t\t\t\t\tdp->obj.c_size = ((DWORD)dp->obj.objsize & 0xFFFFFF00) | dp->obj.stat;\n\t\t\t\t\t\tdp->obj.c_ofs = dp->blk_ofs;\n\t\t\t\t\t\tinit_alloc_info(fs, &dp->obj);\t/* Get object allocation info */\n\t\t\t\t\t} else\n#endif\n\t\t\t\t\t{\n\t\t\t\t\t\tdp->obj.sclust = ld_clust(fs, dp->dir);\t/* Get object allocation info */\n\t\t\t\t\t}\n\t\t\t\t} else {\t\t\t\t\t\t/* This object is a file */\n\t\t\t\t\tres = FR_NO_PATH;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (res == FR_OK) {\n\t\t\t\tdp->obj.id = fs->id;\n\t\t\t\tres = dir_sdi(dp, 0);\t\t\t/* Rewind directory */\n#if FF_FS_LOCK != 0\n\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\tif (dp->obj.sclust != 0) {\n\t\t\t\t\t\tdp->obj.lockid = inc_lock(dp, 0);\t/* Lock the sub directory */\n\t\t\t\t\t\tif (!dp->obj.lockid) res = FR_TOO_MANY_OPEN_FILES;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdp->obj.lockid = 0;\t/* Root directory need not to be locked */\n\t\t\t\t\t}\n\t\t\t\t}\n#endif\n\t\t\t}\n\t\t}\n\t\tFREE_NAMBUF();\n\t\tif (res == FR_NO_FILE) res = FR_NO_PATH;\n\t}\n\tif (res != FR_OK) dp->obj.fs = 0;\t\t/* Invalidate the directory object if function faild */\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Close Directory                                                       */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_closedir (\n\tDIR *dp\t\t/* Pointer to the directory object to be closed */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\n\n\tres = validate(&dp->obj, &fs);\t/* Check validity of the file object */\n\tif (res == FR_OK) {\n#if FF_FS_LOCK != 0\n\t\tif (dp->obj.lockid) res = dec_lock(dp->obj.lockid);\t/* Decrement sub-directory open counter */\n\t\tif (res == FR_OK) dp->obj.fs = 0;\t/* Invalidate directory object */\n#else\n\t\tdp->obj.fs = 0;\t/* Invalidate directory object */\n#endif\n#if FF_FS_REENTRANT\n\t\tunlock_fs(fs, FR_OK);\t\t/* Unlock volume */\n#endif\n\t}\n\treturn res;\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Read Directory Entries in Sequence                                    */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_readdir (\n\tDIR* dp,\t\t\t/* Pointer to the open directory object */\n\tFILINFO* fno\t\t/* Pointer to file information to return */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDEF_NAMBUF\n\n\n\tres = validate(&dp->obj, &fs);\t/* Check validity of the directory object */\n\tif (res == FR_OK) {\n\t\tif (!fno) {\n\t\t\tres = dir_sdi(dp, 0);\t\t\t/* Rewind the directory object */\n\t\t} else {\n\t\t\tINIT_NAMBUF(fs);\n\t\t\tres = DIR_READ_FILE(dp);\t\t/* Read an item */\n\t\t\tif (res == FR_NO_FILE) res = FR_OK;\t/* Ignore end of directory */\n\t\t\tif (res == FR_OK) {\t\t\t\t/* A valid entry is found */\n\t\t\t\tget_fileinfo(dp, fno);\t\t/* Get the object information */\n\t\t\t\tres = dir_next(dp, 0);\t\t/* Increment index for next */\n\t\t\t\tif (res == FR_NO_FILE) res = FR_OK;\t/* Ignore end of directory now */\n\t\t\t}\n\t\t\tFREE_NAMBUF();\n\t\t}\n\t}\n\tLEAVE_FF(fs, res);\n}\n\n\n\n#if FF_USE_FIND\n/*-----------------------------------------------------------------------*/\n/* Find Next File                                                        */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_findnext (\n\tDIR* dp,\t\t/* Pointer to the open directory object */\n\tFILINFO* fno\t/* Pointer to the file information structure */\n)\n{\n\tFRESULT res;\n\n\n\tfor (;;) {\n\t\tres = f_readdir(dp, fno);\t\t/* Get a directory item */\n\t\tif (res != FR_OK || !fno || !fno->fname[0]) break;\t/* Terminate if any error or end of directory */\n\t\tif (pattern_matching(dp->pat, fno->fname, 0, 0)) break;\t\t/* Test for the file name */\n#if FF_USE_LFN && FF_USE_FIND == 2\n\t\tif (pattern_matching(dp->pat, fno->altname, 0, 0)) break;\t/* Test for alternative name if exist */\n#endif\n\t}\n\treturn res;\n}\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Find First File                                                       */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_findfirst (\n\tDIR* dp,\t\t\t\t/* Pointer to the blank directory object */\n\tFILINFO* fno,\t\t\t/* Pointer to the file information structure */\n\tconst TCHAR* path,\t\t/* Pointer to the directory to open */\n\tconst TCHAR* pattern\t/* Pointer to the matching pattern */\n)\n{\n\tFRESULT res;\n\n\n\tdp->pat = pattern;\t\t/* Save pointer to pattern string */\n\tres = f_opendir(dp, path);\t\t/* Open the target directory */\n\tif (res == FR_OK) {\n\t\tres = f_findnext(dp, fno);\t/* Find the first item */\n\t}\n\treturn res;\n}\n\n#endif\t/* FF_USE_FIND */\n\n\n\n#if FF_FS_MINIMIZE == 0\n/*-----------------------------------------------------------------------*/\n/* Get File Status                                                       */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_stat (\n\tconst TCHAR* path,\t/* Pointer to the file path */\n\tFILINFO* fno\t\t/* Pointer to file information to return */\n)\n{\n\tFRESULT res;\n\tDIR dj;\n\tDEF_NAMBUF\n\n\n\t/* Get logical drive */\n\tres = find_volume(&path, &dj.obj.fs, 0);\n\tif (res == FR_OK) {\n\t\tINIT_NAMBUF(dj.obj.fs);\n\t\tres = follow_path(&dj, path);\t/* Follow the file path */\n\t\tif (res == FR_OK) {\t\t\t\t/* Follow completed */\n\t\t\tif (dj.fn[NSFLAG] & NS_NONAME) {\t/* It is origin directory */\n\t\t\t\tres = FR_INVALID_NAME;\n\t\t\t} else {\t\t\t\t\t\t\t/* Found an object */\n\t\t\t\tif (fno) get_fileinfo(&dj, fno);\n\t\t\t}\n\t\t}\n\t\tFREE_NAMBUF();\n\t}\n\n\tLEAVE_FF(dj.obj.fs, res);\n}\n\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Get Number of Free Clusters                                           */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_getfree (\n\tconst TCHAR* path,\t/* Logical drive number */\n\tDWORD* nclst,\t\t/* Pointer to a variable to return number of free clusters */\n\tFATFS** fatfs\t\t/* Pointer to return pointer to corresponding filesystem object */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDWORD nfree, clst, sect, stat;\n\tUINT i;\n\tFFOBJID obj;\n\n\n\t/* Get logical drive */\n\tres = find_volume(&path, &fs, 0);\n\tif (res == FR_OK) {\n\t\tif (fatfs) *fatfs = fs;\t/* Return ptr to the fs object */\n\t\t/* If free_clst is valid, return it without full FAT scan */\n\t\tif (fs->free_clst <= fs->n_fatent - 2) {\n\t\t\t*nclst = fs->free_clst;\n\t\t} else {\n\t\t\t/* Scan FAT to obtain number of free clusters */\n\t\t\tnfree = 0;\n\t\t\tif (fs->fs_type == FS_FAT12) {\t/* FAT12: Scan bit field FAT entries */\n\t\t\t\tclst = 2; obj.fs = fs;\n\t\t\t\tdo {\n\t\t\t\t\tstat = get_fat(&obj, clst);\n\t\t\t\t\tif (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }\n\t\t\t\t\tif (stat == 1) { res = FR_INT_ERR; break; }\n\t\t\t\t\tif (stat == 0) nfree++;\n\t\t\t\t} while (++clst < fs->n_fatent);\n\t\t\t} else {\n#if FF_FS_EXFAT\n\t\t\t\tif (fs->fs_type == FS_EXFAT) {\t/* exFAT: Scan allocation bitmap */\n\t\t\t\t\tBYTE bm;\n\t\t\t\t\tUINT b;\n\n\t\t\t\t\tclst = fs->n_fatent - 2;\t/* Number of clusters */\n\t\t\t\t\tsect = fs->bitbase;\t\t\t/* Bitmap sector */\n\t\t\t\t\ti = 0;\t\t\t\t\t\t/* Offset in the sector */\n\t\t\t\t\tdo {\t/* Counts numbuer of bits with zero in the bitmap */\n\t\t\t\t\t\tif (i == 0) {\n\t\t\t\t\t\t\tres = move_window(fs, sect++);\n\t\t\t\t\t\t\tif (res != FR_OK) break;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (b = 8, bm = fs->win[i]; b && clst; b--, clst--) {\n\t\t\t\t\t\t\tif (!(bm & 1)) nfree++;\n\t\t\t\t\t\t\tbm >>= 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ti = (i + 1) % SS(fs);\n\t\t\t\t\t} while (clst);\n\t\t\t\t} else\n#endif\n\t\t\t\t{\t/* FAT16/32: Scan WORD/DWORD FAT entries */\n\t\t\t\t\tclst = fs->n_fatent;\t/* Number of entries */\n\t\t\t\t\tsect = fs->fatbase;\t\t/* Top of the FAT */\n\t\t\t\t\ti = 0;\t\t\t\t\t/* Offset in the sector */\n\t\t\t\t\tdo {\t/* Counts numbuer of entries with zero in the FAT */\n\t\t\t\t\t\tif (i == 0) {\n\t\t\t\t\t\t\tres = move_window(fs, sect++);\n\t\t\t\t\t\t\tif (res != FR_OK) break;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (fs->fs_type == FS_FAT16) {\n\t\t\t\t\t\t\tif (ld_word(fs->win + i) == 0) nfree++;\n\t\t\t\t\t\t\ti += 2;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif ((ld_dword(fs->win + i) & 0x0FFFFFFF) == 0) nfree++;\n\t\t\t\t\t\t\ti += 4;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ti %= SS(fs);\n\t\t\t\t\t} while (--clst);\n\t\t\t\t}\n\t\t\t}\n\t\t\t*nclst = nfree;\t\t\t/* Return the free clusters */\n\t\t\tfs->free_clst = nfree;\t/* Now free_clst is valid */\n\t\t\tfs->fsi_flag |= 1;\t\t/* FAT32: FSInfo is to be updated */\n\t\t}\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Truncate File                                                         */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_truncate (\n\tFIL* fp\t\t/* Pointer to the file object */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDWORD ncl;\n\n\n\tres = validate(&fp->obj, &fs);\t/* Check validity of the file object */\n\tif (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res);\n\tif (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED);\t/* Check access mode */\n\n\tif (fp->fptr < fp->obj.objsize) {\t/* Process when fptr is not on the eof */\n\t\tif (fp->fptr == 0) {\t/* When set file size to zero, remove entire cluster chain */\n\t\t\tres = remove_chain(&fp->obj, fp->obj.sclust, 0);\n\t\t\tfp->obj.sclust = 0;\n\t\t} else {\t\t\t\t/* When truncate a part of the file, remove remaining clusters */\n\t\t\tncl = get_fat(&fp->obj, fp->clust);\n\t\t\tres = FR_OK;\n\t\t\tif (ncl == 0xFFFFFFFF) res = FR_DISK_ERR;\n\t\t\tif (ncl == 1) res = FR_INT_ERR;\n\t\t\tif (res == FR_OK && ncl < fs->n_fatent) {\n\t\t\t\tres = remove_chain(&fp->obj, ncl, fp->clust);\n\t\t\t}\n\t\t}\n\t\tfp->obj.objsize = fp->fptr;\t/* Set file size to current read/write point */\n\t\tfp->flag |= FA_MODIFIED;\n#if !FF_FS_TINY\n\t\tif (res == FR_OK && (fp->flag & FA_DIRTY)) {\n\t\t\tif (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) {\n\t\t\t\tres = FR_DISK_ERR;\n\t\t\t} else {\n\t\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t\t}\n\t\t}\n#endif\n\t\tif (res != FR_OK) ABORT(fs, res);\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Delete a File/Directory                                               */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_unlink (\n\tconst TCHAR* path\t\t/* Pointer to the file or directory path */\n)\n{\n\tFRESULT res;\n\tDIR dj, sdj;\n\tDWORD dclst = 0;\n\tFATFS *fs;\n#if FF_FS_EXFAT\n\tFFOBJID obj;\n#endif\n\tDEF_NAMBUF\n\n\n\t/* Get logical drive */\n\tres = find_volume(&path, &fs, FA_WRITE);\n\tif (res == FR_OK) {\n\t\tdj.obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\t\tres = follow_path(&dj, path);\t\t/* Follow the file path */\n\t\tif (FF_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT)) {\n\t\t\tres = FR_INVALID_NAME;\t\t\t/* Cannot remove dot entry */\n\t\t}\n#if FF_FS_LOCK != 0\n\t\tif (res == FR_OK) res = chk_lock(&dj, 2);\t/* Check if it is an open object */\n#endif\n\t\tif (res == FR_OK) {\t\t\t\t\t/* The object is accessible */\n\t\t\tif (dj.fn[NSFLAG] & NS_NONAME) {\n\t\t\t\tres = FR_INVALID_NAME;\t\t/* Cannot remove the origin directory */\n\t\t\t} else {\n\t\t\t\tif (dj.obj.attr & AM_RDO) {\n\t\t\t\t\tres = FR_DENIED;\t\t/* Cannot remove R/O object */\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (res == FR_OK) {\n#if FF_FS_EXFAT\n\t\t\t\tobj.fs = fs;\n\t\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\t\tinit_alloc_info(fs, &obj);\n\t\t\t\t\tdclst = obj.sclust;\n\t\t\t\t} else\n#endif\n\t\t\t\t{\n\t\t\t\t\tdclst = ld_clust(fs, dj.dir);\n\t\t\t\t}\n\t\t\t\tif (dj.obj.attr & AM_DIR) {\t\t\t/* Is it a sub-directory? */\n#if FF_FS_RPATH != 0\n\t\t\t\t\tif (dclst == fs->cdir) {\t\t \t/* Is it the current directory? */\n\t\t\t\t\t\tres = FR_DENIED;\n\t\t\t\t\t} else\n#endif\n\t\t\t\t\t{\n\t\t\t\t\t\tsdj.obj.fs = fs;\t\t\t\t/* Open the sub-directory */\n\t\t\t\t\t\tsdj.obj.sclust = dclst;\n#if FF_FS_EXFAT\n\t\t\t\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\t\t\t\tsdj.obj.objsize = obj.objsize;\n\t\t\t\t\t\t\tsdj.obj.stat = obj.stat;\n\t\t\t\t\t\t}\n#endif\n\t\t\t\t\t\tres = dir_sdi(&sdj, 0);\n\t\t\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\t\t\tres = DIR_READ_FILE(&sdj);\t\t\t/* Test if the directory is empty */\n\t\t\t\t\t\t\tif (res == FR_OK) res = FR_DENIED;\t/* Not empty? */\n\t\t\t\t\t\t\tif (res == FR_NO_FILE) res = FR_OK;\t/* Empty? */\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (res == FR_OK) {\n\t\t\t\tres = dir_remove(&dj);\t\t\t/* Remove the directory entry */\n\t\t\t\tif (res == FR_OK && dclst != 0) {\t/* Remove the cluster chain if exist */\n#if FF_FS_EXFAT\n\t\t\t\t\tres = remove_chain(&obj, dclst, 0);\n#else\n\t\t\t\t\tres = remove_chain(&dj.obj, dclst, 0);\n#endif\n\t\t\t\t}\n\t\t\t\tif (res == FR_OK) res = sync_fs(fs);\n\t\t\t}\n\t\t}\n\t\tFREE_NAMBUF();\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Create a Directory                                                    */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_mkdir (\n\tconst TCHAR* path\t\t/* Pointer to the directory path */\n)\n{\n\tFRESULT res;\n\tDIR dj;\n\tFFOBJID sobj;\n\tFATFS *fs;\n\tDWORD dcl, pcl, tm;\n\tDEF_NAMBUF\n\n\n\tres = find_volume(&path, &fs, FA_WRITE);\t/* Get logical drive */\n\tif (res == FR_OK) {\n\t\tdj.obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\t\tres = follow_path(&dj, path);\t\t\t/* Follow the file path */\n\t\tif (res == FR_OK) res = FR_EXIST;\t\t/* Name collision? */\n\t\tif (FF_FS_RPATH && res == FR_NO_FILE && (dj.fn[NSFLAG] & NS_DOT)) {\t/* Invalid name? */\n\t\t\tres = FR_INVALID_NAME;\n\t\t}\n\t\tif (res == FR_NO_FILE) {\t\t\t\t/* It is clear to create a new directory */\n\t\t\tsobj.fs = fs;\t\t\t\t\t\t/* New object id to create a new chain */\n\t\t\tdcl = create_chain(&sobj, 0);\t\t/* Allocate a cluster for the new directory */\n\t\t\tres = FR_OK;\n\t\t\tif (dcl == 0) res = FR_DENIED;\t\t/* No space to allocate a new cluster? */\n\t\t\tif (dcl == 1) res = FR_INT_ERR;\t\t/* Any insanity? */\n\t\t\tif (dcl == 0xFFFFFFFF) res = FR_DISK_ERR;\t/* Disk error? */\n\t\t\ttm = GET_FATTIME();\n\t\t\tif (res == FR_OK) {\n\t\t\t\tres = dir_clear(fs, dcl);\t\t/* Clean up the new table */\n\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\tif (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) {\t/* Create dot entries (FAT only) */\n\t\t\t\t\t\tmem_set(fs->win + DIR_Name, ' ', 11);\t/* Create \".\" entry */\n\t\t\t\t\t\tfs->win[DIR_Name] = '.';\n\t\t\t\t\t\tfs->win[DIR_Attr] = AM_DIR;\n\t\t\t\t\t\tst_dword(fs->win + DIR_ModTime, tm);\n\t\t\t\t\t\tst_clust(fs, fs->win, dcl);\n\t\t\t\t\t\tmem_cpy(fs->win + SZDIRE, fs->win, SZDIRE); /* Create \"..\" entry */\n\t\t\t\t\t\tfs->win[SZDIRE + 1] = '.'; pcl = dj.obj.sclust;\n\t\t\t\t\t\tst_clust(fs, fs->win + SZDIRE, pcl);\n\t\t\t\t\t\tfs->wflag = 1;\n\t\t\t\t\t}\n\t\t\t\t\tres = dir_register(&dj);\t/* Register the object to the parent directoy */\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (res == FR_OK) {\n#if FF_FS_EXFAT\n\t\t\t\tif (fs->fs_type == FS_EXFAT) {\t/* Initialize directory entry block */\n\t\t\t\t\tst_dword(fs->dirbuf + XDIR_ModTime, tm);\t/* Created time */\n\t\t\t\t\tst_dword(fs->dirbuf + XDIR_FstClus, dcl);\t/* Table start cluster */\n\t\t\t\t\tst_dword(fs->dirbuf + XDIR_FileSize, (DWORD)fs->csize * SS(fs));\t/* File size needs to be valid */\n\t\t\t\t\tst_dword(fs->dirbuf + XDIR_ValidFileSize, (DWORD)fs->csize * SS(fs));\n\t\t\t\t\tfs->dirbuf[XDIR_GenFlags] = 3;\t\t\t\t/* Initialize the object flag */\n\t\t\t\t\tfs->dirbuf[XDIR_Attr] = AM_DIR;\t\t\t\t/* Attribute */\n\t\t\t\t\tres = store_xdir(&dj);\n\t\t\t\t} else\n#endif\n\t\t\t\t{\n\t\t\t\t\tst_dword(dj.dir + DIR_ModTime, tm);\t/* Created time */\n\t\t\t\t\tst_clust(fs, dj.dir, dcl);\t\t\t/* Table start cluster */\n\t\t\t\t\tdj.dir[DIR_Attr] = AM_DIR;\t\t\t/* Attribute */\n\t\t\t\t\tfs->wflag = 1;\n\t\t\t\t}\n\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\tres = sync_fs(fs);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tremove_chain(&sobj, dcl, 0);\t\t/* Could not register, remove the allocated cluster */\n\t\t\t}\n\t\t}\n\t\tFREE_NAMBUF();\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Rename a File/Directory                                               */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_rename (\n\tconst TCHAR* path_old,\t/* Pointer to the object name to be renamed */\n\tconst TCHAR* path_new\t/* Pointer to the new name */\n)\n{\n\tFRESULT res;\n\tDIR djo, djn;\n\tFATFS *fs;\n\tBYTE buf[FF_FS_EXFAT ? SZDIRE * 2 : SZDIRE], *dir;\n\tDWORD dw;\n\tDEF_NAMBUF\n\n\n\tget_ldnumber(&path_new);\t\t\t\t\t\t/* Snip the drive number of new name off */\n\tres = find_volume(&path_old, &fs, FA_WRITE);\t/* Get logical drive of the old object */\n\tif (res == FR_OK) {\n\t\tdjo.obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\t\tres = follow_path(&djo, path_old);\t\t/* Check old object */\n\t\tif (res == FR_OK && (djo.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME;\t/* Check validity of name */\n#if FF_FS_LOCK != 0\n\t\tif (res == FR_OK) {\n\t\t\tres = chk_lock(&djo, 2);\n\t\t}\n#endif\n\t\tif (res == FR_OK) {\t\t\t\t\t\t/* Object to be renamed is found */\n#if FF_FS_EXFAT\n\t\t\tif (fs->fs_type == FS_EXFAT) {\t/* At exFAT volume */\n\t\t\t\tBYTE nf, nn;\n\t\t\t\tWORD nh;\n\n\t\t\t\tmem_cpy(buf, fs->dirbuf, SZDIRE * 2);\t/* Save 85+C0 entry of old object */\n\t\t\t\tmem_cpy(&djn, &djo, sizeof djo);\n\t\t\t\tres = follow_path(&djn, path_new);\t\t/* Make sure if new object name is not in use */\n\t\t\t\tif (res == FR_OK) {\t\t\t\t\t\t/* Is new name already in use by any other object? */\n\t\t\t\t\tres = (djn.obj.sclust == djo.obj.sclust && djn.dptr == djo.dptr) ? FR_NO_FILE : FR_EXIST;\n\t\t\t\t}\n\t\t\t\tif (res == FR_NO_FILE) { \t\t\t\t/* It is a valid path and no name collision */\n\t\t\t\t\tres = dir_register(&djn);\t\t\t/* Register the new entry */\n\t\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\t\tnf = fs->dirbuf[XDIR_NumSec]; nn = fs->dirbuf[XDIR_NumName];\n\t\t\t\t\t\tnh = ld_word(fs->dirbuf + XDIR_NameHash);\n\t\t\t\t\t\tmem_cpy(fs->dirbuf, buf, SZDIRE * 2);\t/* Restore 85+C0 entry */\n\t\t\t\t\t\tfs->dirbuf[XDIR_NumSec] = nf; fs->dirbuf[XDIR_NumName] = nn;\n\t\t\t\t\t\tst_word(fs->dirbuf + XDIR_NameHash, nh);\n\t\t\t\t\t\tif (!(fs->dirbuf[XDIR_Attr] & AM_DIR)) fs->dirbuf[XDIR_Attr] |= AM_ARC;\t/* Set archive attribute if it is a file */\n/* Start of critical section where an interruption can cause a cross-link */\n\t\t\t\t\t\tres = store_xdir(&djn);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else\n#endif\n\t\t\t{\t/* At FAT/FAT32 volume */\n\t\t\t\tmem_cpy(buf, djo.dir, SZDIRE);\t\t\t/* Save directory entry of the object */\n\t\t\t\tmem_cpy(&djn, &djo, sizeof (DIR));\t\t/* Duplicate the directory object */\n\t\t\t\tres = follow_path(&djn, path_new);\t\t/* Make sure if new object name is not in use */\n\t\t\t\tif (res == FR_OK) {\t\t\t\t\t\t/* Is new name already in use by any other object? */\n\t\t\t\t\tres = (djn.obj.sclust == djo.obj.sclust && djn.dptr == djo.dptr) ? FR_NO_FILE : FR_EXIST;\n\t\t\t\t}\n\t\t\t\tif (res == FR_NO_FILE) { \t\t\t\t/* It is a valid path and no name collision */\n\t\t\t\t\tres = dir_register(&djn);\t\t\t/* Register the new entry */\n\t\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\t\tdir = djn.dir;\t\t\t\t\t/* Copy directory entry of the object except name */\n\t\t\t\t\t\tmem_cpy(dir + 13, buf + 13, SZDIRE - 13);\n\t\t\t\t\t\tdir[DIR_Attr] = buf[DIR_Attr];\n\t\t\t\t\t\tif (!(dir[DIR_Attr] & AM_DIR)) dir[DIR_Attr] |= AM_ARC;\t/* Set archive attribute if it is a file */\n\t\t\t\t\t\tfs->wflag = 1;\n\t\t\t\t\t\tif ((dir[DIR_Attr] & AM_DIR) && djo.obj.sclust != djn.obj.sclust) {\t/* Update .. entry in the sub-directory if needed */\n\t\t\t\t\t\t\tdw = clst2sect(fs, ld_clust(fs, dir));\n\t\t\t\t\t\t\tif (dw == 0) {\n\t\t\t\t\t\t\t\tres = FR_INT_ERR;\n\t\t\t\t\t\t\t} else {\n/* Start of critical section where an interruption can cause a cross-link */\n\t\t\t\t\t\t\t\tres = move_window(fs, dw);\n\t\t\t\t\t\t\t\tdir = fs->win + SZDIRE * 1;\t/* Ptr to .. entry */\n\t\t\t\t\t\t\t\tif (res == FR_OK && dir[1] == '.') {\n\t\t\t\t\t\t\t\t\tst_clust(fs, dir, djn.obj.sclust);\n\t\t\t\t\t\t\t\t\tfs->wflag = 1;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (res == FR_OK) {\n\t\t\t\tres = dir_remove(&djo);\t\t/* Remove old entry */\n\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\tres = sync_fs(fs);\n\t\t\t\t}\n\t\t\t}\n/* End of the critical section */\n\t\t}\n\t\tFREE_NAMBUF();\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n#endif /* !FF_FS_READONLY */\n#endif /* FF_FS_MINIMIZE == 0 */\n#endif /* FF_FS_MINIMIZE <= 1 */\n#endif /* FF_FS_MINIMIZE <= 2 */\n\n\n\n#if FF_USE_CHMOD && !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Change Attribute                                                      */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_chmod (\n\tconst TCHAR* path,\t/* Pointer to the file path */\n\tBYTE attr,\t\t\t/* Attribute bits */\n\tBYTE mask\t\t\t/* Attribute mask to change */\n)\n{\n\tFRESULT res;\n\tDIR dj;\n\tFATFS *fs;\n\tDEF_NAMBUF\n\n\n\tres = find_volume(&path, &fs, FA_WRITE);\t/* Get logical drive */\n\tif (res == FR_OK) {\n\t\tdj.obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\t\tres = follow_path(&dj, path);\t/* Follow the file path */\n\t\tif (res == FR_OK && (dj.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME;\t/* Check object validity */\n\t\tif (res == FR_OK) {\n\t\t\tmask &= AM_RDO|AM_HID|AM_SYS|AM_ARC;\t/* Valid attribute mask */\n#if FF_FS_EXFAT\n\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\tfs->dirbuf[XDIR_Attr] = (attr & mask) | (fs->dirbuf[XDIR_Attr] & (BYTE)~mask);\t/* Apply attribute change */\n\t\t\t\tres = store_xdir(&dj);\n\t\t\t} else\n#endif\n\t\t\t{\n\t\t\t\tdj.dir[DIR_Attr] = (attr & mask) | (dj.dir[DIR_Attr] & (BYTE)~mask);\t/* Apply attribute change */\n\t\t\t\tfs->wflag = 1;\n\t\t\t}\n\t\t\tif (res == FR_OK) {\n\t\t\t\tres = sync_fs(fs);\n\t\t\t}\n\t\t}\n\t\tFREE_NAMBUF();\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Change Timestamp                                                      */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_utime (\n\tconst TCHAR* path,\t/* Pointer to the file/directory name */\n\tconst FILINFO* fno\t/* Pointer to the timestamp to be set */\n)\n{\n\tFRESULT res;\n\tDIR dj;\n\tFATFS *fs;\n\tDEF_NAMBUF\n\n\n\tres = find_volume(&path, &fs, FA_WRITE);\t/* Get logical drive */\n\tif (res == FR_OK) {\n\t\tdj.obj.fs = fs;\n\t\tINIT_NAMBUF(fs);\n\t\tres = follow_path(&dj, path);\t/* Follow the file path */\n\t\tif (res == FR_OK && (dj.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME;\t/* Check object validity */\n\t\tif (res == FR_OK) {\n#if FF_FS_EXFAT\n\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\tst_dword(fs->dirbuf + XDIR_ModTime, (DWORD)fno->fdate << 16 | fno->ftime);\n\t\t\t\tres = store_xdir(&dj);\n\t\t\t} else\n#endif\n\t\t\t{\n\t\t\t\tst_dword(dj.dir + DIR_ModTime, (DWORD)fno->fdate << 16 | fno->ftime);\n\t\t\t\tfs->wflag = 1;\n\t\t\t}\n\t\t\tif (res == FR_OK) {\n\t\t\t\tres = sync_fs(fs);\n\t\t\t}\n\t\t}\n\t\tFREE_NAMBUF();\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n#endif\t/* FF_USE_CHMOD && !FF_FS_READONLY */\n\n\n\n#if FF_USE_LABEL\n/*-----------------------------------------------------------------------*/\n/* Get Volume Label                                                      */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_getlabel (\n\tconst TCHAR* path,\t/* Logical drive number */\n\tTCHAR* label,\t\t/* Buffer to store the volume label */\n\tDWORD* vsn\t\t\t/* Variable to store the volume serial number */\n)\n{\n\tFRESULT res;\n\tDIR dj;\n\tFATFS *fs;\n\tUINT si, di;\n\tWCHAR wc;\n\n\t/* Get logical drive */\n\tres = find_volume(&path, &fs, 0);\n\n\t/* Get volume label */\n\tif (res == FR_OK && label) {\n\t\tdj.obj.fs = fs; dj.obj.sclust = 0;\t/* Open root directory */\n\t\tres = dir_sdi(&dj, 0);\n\t\tif (res == FR_OK) {\n\t\t \tres = DIR_READ_LABEL(&dj);\t\t/* Find a volume label entry */\n\t\t \tif (res == FR_OK) {\n#if FF_FS_EXFAT\n\t\t\t\tif (fs->fs_type == FS_EXFAT) {\n\t\t\t\t\tWCHAR hs;\n\n\t\t\t\t\tfor (si = di = hs = 0; si < dj.dir[XDIR_NumLabel]; si++) {\t/* Extract volume label from 83 entry */\n\t\t\t\t\t\twc = ld_word(dj.dir + XDIR_Label + si * 2);\n\t\t\t\t\t\tif (hs == 0 && IsSurrogate(wc)) {\t/* Is the code a surrogate? */\n\t\t\t\t\t\t\ths = wc; continue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\twc = put_utf((DWORD)hs << 16 | wc, &label[di], 4);\n\t\t\t\t\t\tif (wc == 0) { di = 0; break; }\n\t\t\t\t\t\tdi += wc;\n\t\t\t\t\t\ths = 0;\n\t\t\t\t\t}\n\t\t\t\t\tif (hs != 0) di = 0;\t/* Broken surrogate pair? */\n\t\t\t\t\tlabel[di] = 0;\n\t\t\t\t} else\n#endif\n\t\t\t\t{\n\t\t\t\t\tsi = di = 0;\t\t/* Extract volume label from AM_VOL entry */\n\t\t\t\t\twhile (si < 11) {\n\t\t\t\t\t\twc = dj.dir[si++];\n#if FF_USE_LFN && FF_LFN_UNICODE >= 1 \t/* Unicode output */\n\t\t\t\t\t\tif (dbc_1st((BYTE)wc) && si < 11) wc = wc << 8 | dj.dir[si++];\t/* Is it a DBC? */\n\t\t\t\t\t\twc = ff_oem2uni(wc, CODEPAGE);\t\t\t\t\t/* Convert it into Unicode */\n\t\t\t\t\t\tif (wc != 0) wc = put_utf(wc, &label[di], 4);\t/* Put it in Unicode */\n\t\t\t\t\t\tif (wc == 0) { di = 0; break; }\n\t\t\t\t\t\tdi += wc;\n#else\t\t\t\t\t\t\t\t\t/* ANSI/OEM output */\n\t\t\t\t\t\tlabel[di++] = (TCHAR)wc;\n#endif\n\t\t\t\t\t}\n\t\t\t\t\tdo {\t\t\t\t/* Truncate trailing spaces */\n\t\t\t\t\t\tlabel[di] = 0;\n\t\t\t\t\t\tif (di == 0) break;\n\t\t\t\t\t} while (label[--di] == ' ');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (res == FR_NO_FILE) {\t/* No label entry and return nul string */\n\t\t\tlabel[0] = 0;\n\t\t\tres = FR_OK;\n\t\t}\n\t}\n\n\t/* Get volume serial number */\n\tif (res == FR_OK && vsn) {\n\t\tres = move_window(fs, fs->volbase);\n\t\tif (res == FR_OK) {\n\t\t\tswitch (fs->fs_type) {\n\t\t\tcase FS_EXFAT:\n\t\t\t\tdi = BPB_VolIDEx; break;\n\n\t\t\tcase FS_FAT32:\n\t\t\t\tdi = BS_VolID32; break;\n\n\t\t\tdefault:\n\t\t\t\tdi = BS_VolID;\n\t\t\t}\n\t\t\t*vsn = ld_dword(fs->win + di);\n\t\t}\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n\n\n#if !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Set Volume Label                                                      */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_setlabel (\n\tconst TCHAR* label\t/* Volume label to set with heading logical drive number */\n)\n{\n\tFRESULT res;\n\tDIR dj;\n\tFATFS *fs;\n\tBYTE dirvn[22];\n\tUINT di;\n\tWCHAR wc;\n\tstatic const char badchr[] = \"+.,;=[]/\\\\\\\"*:<>\\?|\\x7F\";\t/* [0..] for FAT, [7..] for exFAT */\n#if FF_USE_LFN\n\tDWORD dc;\n#endif\n\n\t/* Get logical drive */\n\tres = find_volume(&label, &fs, FA_WRITE);\n\tif (res != FR_OK) LEAVE_FF(fs, res);\n\n#if FF_FS_EXFAT\n\tif (fs->fs_type == FS_EXFAT) {\t/* On the exFAT volume */\n\t\tmem_set(dirvn, 0, 22);\n\t\tdi = 0;\n\t\twhile ((UINT)*label >= ' ') {\t/* Create volume label */\n\t\t\tdc = tchar2uni(&label);\t/* Get a Unicode character */\n\t\t\tif (dc >= 0x10000) {\n\t\t\t\tif (dc == 0xFFFFFFFF || di >= 10) {\t/* Wrong surrogate or buffer overflow */\n\t\t\t\t\tdc = 0;\n\t\t\t\t} else {\n\t\t\t\t\tst_word(dirvn + di * 2, (WCHAR)(dc >> 16)); di++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (dc == 0 || chk_chr(badchr + 7, (int)dc) || di >= 11) {\t/* Check validity of the volume label */\n\t\t\t\tLEAVE_FF(fs, FR_INVALID_NAME);\n\t\t\t}\n\t\t\tst_word(dirvn + di * 2, (WCHAR)dc); di++;\n\t\t}\n\t} else\n#endif\n\t{\t/* On the FAT/FAT32 volume */\n\t\tmem_set(dirvn, ' ', 11);\n\t\tdi = 0;\n\t\twhile ((UINT)*label >= ' ') {\t/* Create volume label */\n#if FF_USE_LFN\n\t\t\tdc = tchar2uni(&label);\n\t\t\twc = (dc < 0x10000) ? ff_uni2oem(ff_wtoupper(dc), CODEPAGE) : 0;\n#else\t\t\t\t\t\t\t\t\t/* ANSI/OEM input */\n\t\t\twc = (BYTE)*label++;\n\t\t\tif (dbc_1st((BYTE)wc)) wc = dbc_2nd((BYTE)*label) ? wc << 8 | (BYTE)*label++ : 0;\n\t\t\tif (IsLower(wc)) wc -= 0x20;\t\t/* To upper ASCII characters */\n#if FF_CODE_PAGE == 0\n\t\t\tif (ExCvt && wc >= 0x80) wc = ExCvt[wc - 0x80];\t/* To upper extended characters (SBCS cfg) */\n#elif FF_CODE_PAGE < 900\n\t\t\tif (wc >= 0x80) wc = ExCvt[wc - 0x80];\t/* To upper extended characters (SBCS cfg) */\n#endif\n#endif\n\t\t\tif (wc == 0 || chk_chr(badchr + 0, (int)wc) || di >= (UINT)((wc >= 0x100) ? 10 : 11)) {\t/* Reject invalid characters for volume label */\n\t\t\t\tLEAVE_FF(fs, FR_INVALID_NAME);\n\t\t\t}\n\t\t\tif (wc >= 0x100) dirvn[di++] = (BYTE)(wc >> 8);\n\t\t\tdirvn[di++] = (BYTE)wc;\n\t\t}\n\t\tif (dirvn[0] == DDEM) LEAVE_FF(fs, FR_INVALID_NAME);\t/* Reject illegal name (heading DDEM) */\n\t\twhile (di && dirvn[di - 1] == ' ') di--;\t\t\t\t/* Snip trailing spaces */\n\t}\n\n\t/* Set volume label */\n\tdj.obj.fs = fs; dj.obj.sclust = 0;\t/* Open root directory */\n\tres = dir_sdi(&dj, 0);\n\tif (res == FR_OK) {\n\t\tres = DIR_READ_LABEL(&dj);\t/* Get volume label entry */\n\t\tif (res == FR_OK) {\n\t\t\tif (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) {\n\t\t\t\tdj.dir[XDIR_NumLabel] = (BYTE)di;\t/* Change the volume label */\n\t\t\t\tmem_cpy(dj.dir + XDIR_Label, dirvn, 22);\n\t\t\t} else {\n\t\t\t\tif (di != 0) {\n\t\t\t\t\tmem_cpy(dj.dir, dirvn, 11);\t/* Change the volume label */\n\t\t\t\t} else {\n\t\t\t\t\tdj.dir[DIR_Name] = DDEM;\t/* Remove the volume label */\n\t\t\t\t}\n\t\t\t}\n\t\t\tfs->wflag = 1;\n\t\t\tres = sync_fs(fs);\n\t\t} else {\t\t\t/* No volume label entry or an error */\n\t\t\tif (res == FR_NO_FILE) {\n\t\t\t\tres = FR_OK;\n\t\t\t\tif (di != 0) {\t/* Create a volume label entry */\n\t\t\t\t\tres = dir_alloc(&dj, 1);\t/* Allocate an entry */\n\t\t\t\t\tif (res == FR_OK) {\n\t\t\t\t\t\tmem_set(dj.dir, 0, SZDIRE);\t/* Clean the entry */\n\t\t\t\t\t\tif (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) {\n\t\t\t\t\t\t\tdj.dir[XDIR_Type] = ET_VLABEL;\t/* Create volume label entry */\n\t\t\t\t\t\t\tdj.dir[XDIR_NumLabel] = (BYTE)di;\n\t\t\t\t\t\t\tmem_cpy(dj.dir + XDIR_Label, dirvn, 22);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdj.dir[DIR_Attr] = AM_VOL;\t\t/* Create volume label entry */\n\t\t\t\t\t\t\tmem_cpy(dj.dir, dirvn, 11);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfs->wflag = 1;\n\t\t\t\t\t\tres = sync_fs(fs);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n#endif /* !FF_FS_READONLY */\n#endif /* FF_USE_LABEL */\n\n\n\n#if FF_USE_EXPAND && !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Allocate a Contiguous Blocks to the File                              */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_expand (\n\tFIL* fp,\t\t/* Pointer to the file object */\n\tFSIZE_t fsz,\t/* File size to be expanded to */\n\tBYTE opt\t\t/* Operation mode 0:Find and prepare or 1:Find and allocate */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDWORD n, clst, stcl, scl, ncl, tcl, lclst;\n\n\n\tres = validate(&fp->obj, &fs);\t\t/* Check validity of the file object */\n\tif (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res);\n\tif (fsz == 0 || fp->obj.objsize != 0 || !(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED);\n#if FF_FS_EXFAT\n\tif (fs->fs_type != FS_EXFAT && fsz >= 0x100000000) LEAVE_FF(fs, FR_DENIED);\t/* Check if in size limit */\n#endif\n\tn = (DWORD)fs->csize * SS(fs);\t/* Cluster size */\n\ttcl = (DWORD)(fsz / n) + ((fsz & (n - 1)) ? 1 : 0);\t/* Number of clusters required */\n\tstcl = fs->last_clst; lclst = 0;\n\tif (stcl < 2 || stcl >= fs->n_fatent) stcl = 2;\n\n#if FF_FS_EXFAT\n\tif (fs->fs_type == FS_EXFAT) {\n\t\tscl = find_bitmap(fs, stcl, tcl);\t\t\t/* Find a contiguous cluster block */\n\t\tif (scl == 0) res = FR_DENIED;\t\t\t\t/* No contiguous cluster block was found */\n\t\tif (scl == 0xFFFFFFFF) res = FR_DISK_ERR;\n\t\tif (res == FR_OK) {\t/* A contiguous free area is found */\n\t\t\tif (opt) {\t\t/* Allocate it now */\n\t\t\t\tres = change_bitmap(fs, scl, tcl, 1);\t/* Mark the cluster block 'in use' */\n\t\t\t\tlclst = scl + tcl - 1;\n\t\t\t} else {\t\t/* Set it as suggested point for next allocation */\n\t\t\t\tlclst = scl - 1;\n\t\t\t}\n\t\t}\n\t} else\n#endif\n\t{\n\t\tscl = clst = stcl; ncl = 0;\n\t\tfor (;;) {\t/* Find a contiguous cluster block */\n\t\t\tn = get_fat(&fp->obj, clst);\n\t\t\tif (++clst >= fs->n_fatent) clst = 2;\n\t\t\tif (n == 1) { res = FR_INT_ERR; break; }\n\t\t\tif (n == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }\n\t\t\tif (n == 0) {\t/* Is it a free cluster? */\n\t\t\t\tif (++ncl == tcl) break;\t/* Break if a contiguous cluster block is found */\n\t\t\t} else {\n\t\t\t\tscl = clst; ncl = 0;\t\t/* Not a free cluster */\n\t\t\t}\n\t\t\tif (clst == stcl) { res = FR_DENIED; break; }\t/* No contiguous cluster? */\n\t\t}\n\t\tif (res == FR_OK) {\t/* A contiguous free area is found */\n\t\t\tif (opt) {\t\t/* Allocate it now */\n\t\t\t\tfor (clst = scl, n = tcl; n; clst++, n--) {\t/* Create a cluster chain on the FAT */\n\t\t\t\t\tres = put_fat(fs, clst, (n == 1) ? 0xFFFFFFFF : clst + 1);\n\t\t\t\t\tif (res != FR_OK) break;\n\t\t\t\t\tlclst = clst;\n\t\t\t\t}\n\t\t\t} else {\t\t/* Set it as suggested point for next allocation */\n\t\t\t\tlclst = scl - 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (res == FR_OK) {\n\t\tfs->last_clst = lclst;\t\t/* Set suggested start cluster to start next */\n\t\tif (opt) {\t/* Is it allocated now? */\n\t\t\tfp->obj.sclust = scl;\t\t/* Update object allocation information */\n\t\t\tfp->obj.objsize = fsz;\n\t\t\tif (FF_FS_EXFAT) fp->obj.stat = 2;\t/* Set status 'contiguous chain' */\n\t\t\tfp->flag |= FA_MODIFIED;\n\t\t\tif (fs->free_clst <= fs->n_fatent - 2) {\t/* Update FSINFO */\n\t\t\t\tfs->free_clst -= tcl;\n\t\t\t\tfs->fsi_flag |= 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tLEAVE_FF(fs, res);\n}\n\n#endif /* FF_USE_EXPAND && !FF_FS_READONLY */\n\n\n\n#if FF_USE_FORWARD\n/*-----------------------------------------------------------------------*/\n/* Forward Data to the Stream Directly                                   */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_forward (\n\tFIL* fp, \t\t\t\t\t\t/* Pointer to the file object */\n\tUINT (*func)(const BYTE*,UINT),\t/* Pointer to the streaming function */\n\tUINT btf,\t\t\t\t\t\t/* Number of bytes to forward */\n\tUINT* bf\t\t\t\t\t\t/* Pointer to number of bytes forwarded */\n)\n{\n\tFRESULT res;\n\tFATFS *fs;\n\tDWORD clst, sect;\n\tFSIZE_t remain;\n\tUINT rcnt, csect;\n\tBYTE *dbuf;\n\n\n\t*bf = 0;\t/* Clear transfer byte counter */\n\tres = validate(&fp->obj, &fs);\t\t/* Check validity of the file object */\n\tif (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res);\n\tif (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED);\t/* Check access mode */\n\n\tremain = fp->obj.objsize - fp->fptr;\n\tif (btf > remain) btf = (UINT)remain;\t\t\t/* Truncate btf by remaining bytes */\n\n\tfor ( ;  btf && (*func)(0, 0);\t\t\t\t\t/* Repeat until all data transferred or stream goes busy */\n\t\tfp->fptr += rcnt, *bf += rcnt, btf -= rcnt) {\n\t\tcsect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1));\t/* Sector offset in the cluster */\n\t\tif (fp->fptr % SS(fs) == 0) {\t\t\t\t/* On the sector boundary? */\n\t\t\tif (csect == 0) {\t\t\t\t\t\t/* On the cluster boundary? */\n\t\t\t\tclst = (fp->fptr == 0) ?\t\t\t/* On the top of the file? */\n\t\t\t\t\tfp->obj.sclust : get_fat(&fp->obj, fp->clust);\n\t\t\t\tif (clst <= 1) ABORT(fs, FR_INT_ERR);\n\t\t\t\tif (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);\n\t\t\t\tfp->clust = clst;\t\t\t\t\t/* Update current cluster */\n\t\t\t}\n\t\t}\n\t\tsect = clst2sect(fs, fp->clust);\t\t\t/* Get current data sector */\n\t\tif (sect == 0) ABORT(fs, FR_INT_ERR);\n\t\tsect += csect;\n#if FF_FS_TINY\n\t\tif (move_window(fs, sect) != FR_OK) ABORT(fs, FR_DISK_ERR);\t/* Move sector window to the file data */\n\t\tdbuf = fs->win;\n#else\n\t\tif (fp->sect != sect) {\t\t/* Fill sector cache with file data */\n#if !FF_FS_READONLY\n\t\t\tif (fp->flag & FA_DIRTY) {\t\t/* Write-back dirty sector cache */\n\t\t\t\tif (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t\t\tfp->flag &= (BYTE)~FA_DIRTY;\n\t\t\t}\n#endif\n\t\t\tif (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);\n\t\t}\n\t\tdbuf = fp->buf;\n#endif\n\t\tfp->sect = sect;\n\t\trcnt = SS(fs) - (UINT)fp->fptr % SS(fs);\t/* Number of bytes left in the sector */\n\t\tif (rcnt > btf) rcnt = btf;\t\t\t\t\t/* Clip it by btr if needed */\n\t\trcnt = (*func)(dbuf + ((UINT)fp->fptr % SS(fs)), rcnt);\t/* Forward the file data */\n\t\tif (rcnt == 0) ABORT(fs, FR_INT_ERR);\n\t}\n\n\tLEAVE_FF(fs, FR_OK);\n}\n#endif /* FF_USE_FORWARD */\n\n\n\n#if FF_USE_MKFS && !FF_FS_READONLY\n/*-----------------------------------------------------------------------*/\n/* Create an FAT/exFAT volume                                            */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_mkfs (\n\tconst TCHAR* path,\t/* Logical drive number */\n\tBYTE opt,\t\t\t/* Format option */\n\tDWORD au,\t\t\t/* Size of allocation unit (cluster) [byte] */\n\tvoid* work,\t\t\t/* Pointer to working buffer (null: use heap memory) */\n\tUINT len\t\t\t/* Size of working buffer [byte] */\n)\n{\n\tconst UINT n_fats = 1;\t\t/* Number of FATs for FAT/FAT32 volume (1 or 2) */\n\tconst UINT n_rootdir = 512;\t/* Number of root directory entries for FAT volume */\n\tstatic const WORD cst[] = {1, 4, 16, 64, 256, 512, 0};\t/* Cluster size boundary for FAT volume (4Ks unit) */\n\tstatic const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0};\t/* Cluster size boundary for FAT32 volume (128Ks unit) */\n\tBYTE fmt, sys, *buf, *pte, pdrv, part;\n\tWORD ss;\t/* Sector size */\n\tDWORD szb_buf, sz_buf, sz_blk, n_clst, pau, sect, nsect, n;\n\tDWORD b_vol, b_fat, b_data;\t\t\t\t/* Base LBA for volume, fat, data */\n\tDWORD sz_vol, sz_rsv, sz_fat, sz_dir;\t/* Size for volume, fat, dir, data */\n\tUINT i;\n\tint vol;\n\tDSTATUS stat;\n#if FF_USE_TRIM || FF_FS_EXFAT\n\tDWORD tbl[3];\n#endif\n\n\n\t/* Check mounted drive and clear work area */\n\tvol = get_ldnumber(&path);\t\t\t\t\t/* Get target logical drive */\n\tif (vol < 0) return FR_INVALID_DRIVE;\n\tif (FatFs[vol]) FatFs[vol]->fs_type = 0;\t/* Clear the volume if mounted */\n\tpdrv = LD2PD(vol);\t/* Physical drive */\n\tpart = LD2PT(vol);\t/* Partition (0:create as new, 1-4:get from partition table) */\n\n\t/* Check physical drive status */\n\tstat = disk_initialize(pdrv);\n\tif (stat & STA_NOINIT) return FR_NOT_READY;\n\tif (stat & STA_PROTECT) return FR_WRITE_PROTECTED;\n\tif (disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_blk) != RES_OK || !sz_blk || sz_blk > 32768 || (sz_blk & (sz_blk - 1))) sz_blk = 1;\t/* Erase block to align data area */\n#if FF_MAX_SS != FF_MIN_SS\t\t/* Get sector size of the medium if variable sector size cfg. */\n\tif (disk_ioctl(pdrv, GET_SECTOR_SIZE, &ss) != RES_OK) return FR_DISK_ERR;\n\tif (ss > FF_MAX_SS || ss < FF_MIN_SS || (ss & (ss - 1))) return FR_DISK_ERR;\n#else\n\tss = FF_MAX_SS;\n#endif\n\tif ((au != 0 && au < ss) || au > 0x1000000 || (au & (au - 1))) return FR_INVALID_PARAMETER;\t/* Check if au is valid */\n\tau /= ss;\t/* Cluster size in unit of sector */\n\n\t/* Get working buffer */\n#if FF_USE_LFN == 3\n\tif (!work) {\t/* Use heap memory for working buffer */\n\t\tfor (szb_buf = MAX_MALLOC, buf = 0; szb_buf >= ss && (buf = ff_memalloc(szb_buf)) == 0; szb_buf /= 2) ;\n\t\tsz_buf = szb_buf / ss;\t\t/* Size of working buffer (sector) */\n\t} else\n#endif\n\t{\n\t\tbuf = (BYTE*)work;\t\t/* Working buffer */\n\t\tsz_buf = len / ss;\t\t/* Size of working buffer (sector) */\n\t\tszb_buf = sz_buf * ss;\t/* Size of working buffer (byte) */\n\t}\n\tif (!buf || sz_buf == 0) return FR_NOT_ENOUGH_CORE;\n\n\t/* Determine where the volume to be located (b_vol, sz_vol) */\n\tif (FF_MULTI_PARTITION && part != 0) {\n\t\t/* Get partition information from partition table in the MBR */\n\t\tif (disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\t/* Load MBR */\n\t\tif (ld_word(buf + BS_55AA) != 0xAA55) LEAVE_MKFS(FR_MKFS_ABORTED);\t/* Check if MBR is valid */\n\t\tpte = buf + (MBR_Table + (part - 1) * SZ_PTE);\n\t\tif (pte[PTE_System] == 0) LEAVE_MKFS(FR_MKFS_ABORTED);\t/* No partition? */\n\t\tb_vol = ld_dword(pte + PTE_StLba);\t\t/* Get volume start sector */\n\t\tsz_vol = ld_dword(pte + PTE_SizLba);\t/* Get volume size */\n\t} else {\n\t\t/* Create a single-partition in this function */\n\t\tif (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\tb_vol = (opt & FM_SFD) ? 0 : 63;\t\t/* Volume start sector */\n\t\tif (sz_vol < b_vol) LEAVE_MKFS(FR_MKFS_ABORTED);\n\t\tsz_vol -= b_vol;\t\t\t\t\t\t/* Volume size */\n\t}\n\tif (sz_vol < 128) LEAVE_MKFS(FR_MKFS_ABORTED);\t/* Check if volume size is >=128s */\n\n\t/* Pre-determine the FAT type */\n\tdo {\n\t\tif (FF_FS_EXFAT && (opt & FM_EXFAT)) {\t/* exFAT possible? */\n\t\t\tif ((opt & FM_ANY) == FM_EXFAT || sz_vol >= 0x4000000 || au > 128) {\t/* exFAT only, vol >= 64Ms or au > 128s ? */\n\t\t\t\tfmt = FS_EXFAT; break;\n\t\t\t}\n\t\t}\n\t\tif (au > 128) LEAVE_MKFS(FR_INVALID_PARAMETER);\t/* Too large au for FAT/FAT32 */\n\t\tif (opt & FM_FAT32) {\t/* FAT32 possible? */\n\t\t\tif ((opt & FM_ANY) == FM_FAT32 || !(opt & FM_FAT)) {\t/* FAT32 only or no-FAT? */\n\t\t\t\tfmt = FS_FAT32; break;\n\t\t\t}\n\t\t}\n\t\tif (!(opt & FM_FAT)) LEAVE_MKFS(FR_INVALID_PARAMETER);\t/* no-FAT? */\n\t\tfmt = FS_FAT16;\n\t} while (0);\n\n#if FF_FS_EXFAT\n\tif (fmt == FS_EXFAT) {\t/* Create an exFAT volume */\n\t\tDWORD szb_bit, szb_case, sum, nb, cl;\n\t\tWCHAR ch, si;\n\t\tUINT j, st;\n\t\tBYTE b;\n\n\t\tif (sz_vol < 0x1000) LEAVE_MKFS(FR_MKFS_ABORTED);\t/* Too small volume? */\n#if FF_USE_TRIM\n\t\ttbl[0] = b_vol; tbl[1] = b_vol + sz_vol - 1;\t/* Inform the device the volume area may be erased */\n\t\tdisk_ioctl(pdrv, CTRL_TRIM, tbl);\n#endif\n\t\t/* Determine FAT location, data location and number of clusters */\n\t\tif (au == 0) {\t/* au auto-selection */\n\t\t\tau = 8;\n\t\t\tif (sz_vol >= 0x80000) au = 64;\t\t/* >= 512Ks */\n\t\t\tif (sz_vol >= 0x4000000) au = 256;\t/* >= 64Ms */\n\t\t}\n\t\tb_fat = b_vol + 32;\t\t\t\t\t\t\t\t\t\t/* FAT start at offset 32 */\n\t\tsz_fat = ((sz_vol / au + 2) * 4 + ss - 1) / ss;\t\t\t/* Number of FAT sectors */\n\t\tb_data = (b_fat + sz_fat + sz_blk - 1) & ~(sz_blk - 1);\t/* Align data area to the erase block boundary */\n\t\tif (b_data - b_vol >= sz_vol / 2) LEAVE_MKFS(FR_MKFS_ABORTED);\t/* Too small volume? */\n\t\tn_clst = (sz_vol - (b_data - b_vol)) / au;\t\t\t\t/* Number of clusters */\n\t\tif (n_clst <16) LEAVE_MKFS(FR_MKFS_ABORTED);\t\t\t/* Too few clusters? */\n\t\tif (n_clst > MAX_EXFAT) LEAVE_MKFS(FR_MKFS_ABORTED);\t/* Too many clusters? */\n\n\t\tszb_bit = (n_clst + 7) / 8;\t\t\t\t\t\t/* Size of allocation bitmap */\n\t\ttbl[0] = (szb_bit + au * ss - 1) / (au * ss);\t/* Number of allocation bitmap clusters */\n\n\t\t/* Create a compressed up-case table */\n\t\tsect = b_data + au * tbl[0];\t/* Table start sector */\n\t\tsum = 0;\t\t\t\t\t\t/* Table checksum to be stored in the 82 entry */\n\t\tst = 0; si = 0; i = 0; j = 0; szb_case = 0;\n\t\tdo {\n\t\t\tswitch (st) {\n\t\t\tcase 0:\n\t\t\t\tch = (WCHAR)ff_wtoupper(si);\t/* Get an up-case char */\n\t\t\t\tif (ch != si) {\n\t\t\t\t\tsi++; break;\t\t/* Store the up-case char if exist */\n\t\t\t\t}\n\t\t\t\tfor (j = 1; (WCHAR)(si + j) && (WCHAR)(si + j) == ff_wtoupper((WCHAR)(si + j)); j++) ;\t/* Get run length of no-case block */\n\t\t\t\tif (j >= 128) {\n\t\t\t\t\tch = 0xFFFF; st = 2; break;\t/* Compress the no-case block if run is >= 128 */\n\t\t\t\t}\n\t\t\t\tst = 1;\t\t\t/* Do not compress short run */\n\t\t\t\t/* go to next case */\n\t\t\tcase 1:\n\t\t\t\tch = si++;\t\t/* Fill the short run */\n\t\t\t\tif (--j == 0) st = 0;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tch = (WCHAR)j; si += (WCHAR)j;\t/* Number of chars to skip */\n\t\t\t\tst = 0;\n\t\t\t}\n\t\t\tsum = xsum32(buf[i + 0] = (BYTE)ch, sum);\t\t/* Put it into the write buffer */\n\t\t\tsum = xsum32(buf[i + 1] = (BYTE)(ch >> 8), sum);\n\t\t\ti += 2; szb_case += 2;\n\t\t\tif (si == 0 || i == szb_buf) {\t\t/* Write buffered data when buffer full or end of process */\n\t\t\t\tn = (i + ss - 1) / ss;\n\t\t\t\tif (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\t\tsect += n; i = 0;\n\t\t\t}\n\t\t} while (si);\n\t\ttbl[1] = (szb_case + au * ss - 1) / (au * ss);\t/* Number of up-case table clusters */\n\t\ttbl[2] = 1;\t\t\t\t\t\t\t\t\t\t/* Number of root dir clusters */\n\n\t\t/* Initialize the allocation bitmap */\n\t\tsect = b_data; nsect = (szb_bit + ss - 1) / ss;\t/* Start of bitmap and number of sectors */\n\t\tnb = tbl[0] + tbl[1] + tbl[2];\t\t\t\t\t/* Number of clusters in-use by system */\n\t\tdo {\n\t\t\tmem_set(buf, 0, szb_buf);\n\t\t\tfor (i = 0; nb >= 8 && i < szb_buf; buf[i++] = 0xFF, nb -= 8) ;\n\t\t\tfor (b = 1; nb != 0 && i < szb_buf; buf[i] |= b, b <<= 1, nb--) ;\n\t\t\tn = (nsect > sz_buf) ? sz_buf : nsect;\t\t/* Write the buffered data */\n\t\t\tif (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\tsect += n; nsect -= n;\n\t\t} while (nsect);\n\n\t\t/* Initialize the FAT */\n\t\tsect = b_fat; nsect = sz_fat;\t/* Start of FAT and number of FAT sectors */\n\t\tj = nb = cl = 0;\n\t\tdo {\n\t\t\tmem_set(buf, 0, szb_buf); i = 0;\t/* Clear work area and reset write index */\n\t\t\tif (cl == 0) {\t/* Set entry 0 and 1 */\n\t\t\t\tst_dword(buf + i, 0xFFFFFFF8); i += 4; cl++;\n\t\t\t\tst_dword(buf + i, 0xFFFFFFFF); i += 4; cl++;\n\t\t\t}\n\t\t\tdo {\t\t\t/* Create chains of bitmap, up-case and root dir */\n\t\t\t\twhile (nb != 0 && i < szb_buf) {\t\t\t/* Create a chain */\n\t\t\t\t\tst_dword(buf + i, (nb > 1) ? cl + 1 : 0xFFFFFFFF);\n\t\t\t\t\ti += 4; cl++; nb--;\n\t\t\t\t}\n\t\t\t\tif (nb == 0 && j < 3) nb = tbl[j++];\t/* Next chain */\n\t\t\t} while (nb != 0 && i < szb_buf);\n\t\t\tn = (nsect > sz_buf) ? sz_buf : nsect;\t/* Write the buffered data */\n\t\t\tif (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\tsect += n; nsect -= n;\n\t\t} while (nsect);\n\n\t\t/* Initialize the root directory */\n\t\tmem_set(buf, 0, szb_buf);\n\t\tbuf[SZDIRE * 0 + 0] = ET_VLABEL;\t\t/* Volume label entry */\n\t\tbuf[SZDIRE * 1 + 0] = ET_BITMAP;\t\t/* Bitmap entry */\n\t\tst_dword(buf + SZDIRE * 1 + 20, 2);\t\t\t\t/* cluster */\n\t\tst_dword(buf + SZDIRE * 1 + 24, szb_bit);\t\t/* size */\n\t\tbuf[SZDIRE * 2 + 0] = ET_UPCASE;\t\t/* Up-case table entry */\n\t\tst_dword(buf + SZDIRE * 2 + 4, sum);\t\t\t/* sum */\n\t\tst_dword(buf + SZDIRE * 2 + 20, 2 + tbl[0]);\t/* cluster */\n\t\tst_dword(buf + SZDIRE * 2 + 24, szb_case);\t\t/* size */\n\t\tsect = b_data + au * (tbl[0] + tbl[1]);\tnsect = au;\t/* Start of the root directory and number of sectors */\n\t\tdo {\t/* Fill root directory sectors */\n\t\t\tn = (nsect > sz_buf) ? sz_buf : nsect;\n\t\t\tif (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\tmem_set(buf, 0, ss);\n\t\t\tsect += n; nsect -= n;\n\t\t} while (nsect);\n\n\t\t/* Create two set of the exFAT VBR blocks */\n\t\tsect = b_vol;\n\t\tfor (n = 0; n < 2; n++) {\n\t\t\t/* Main record (+0) */\n\t\t\tmem_set(buf, 0, ss);\n\t\t\tmem_cpy(buf + BS_JmpBoot, \"\\xEB\\x76\\x90\" \"EXFAT   \", 11);\t/* Boot jump code (x86), OEM name */\n\t\t\tst_dword(buf + BPB_VolOfsEx, b_vol);\t\t\t\t\t/* Volume offset in the physical drive [sector] */\n\t\t\tst_dword(buf + BPB_TotSecEx, sz_vol);\t\t\t\t\t/* Volume size [sector] */\n\t\t\tst_dword(buf + BPB_FatOfsEx, b_fat - b_vol);\t\t\t/* FAT offset [sector] */\n\t\t\tst_dword(buf + BPB_FatSzEx, sz_fat);\t\t\t\t\t/* FAT size [sector] */\n\t\t\tst_dword(buf + BPB_DataOfsEx, b_data - b_vol);\t\t\t/* Data offset [sector] */\n\t\t\tst_dword(buf + BPB_NumClusEx, n_clst);\t\t\t\t\t/* Number of clusters */\n\t\t\tst_dword(buf + BPB_RootClusEx, 2 + tbl[0] + tbl[1]);\t/* Root dir cluster # */\n\t\t\tst_dword(buf + BPB_VolIDEx, GET_FATTIME());\t\t\t\t/* VSN */\n\t\t\tst_word(buf + BPB_FSVerEx, 0x100);\t\t\t\t\t\t/* Filesystem version (1.00) */\n\t\t\tfor (buf[BPB_BytsPerSecEx] = 0, i = ss; i >>= 1; buf[BPB_BytsPerSecEx]++) ;\t/* Log2 of sector size [byte] */\n\t\t\tfor (buf[BPB_SecPerClusEx] = 0, i = au; i >>= 1; buf[BPB_SecPerClusEx]++) ;\t/* Log2 of cluster size [sector] */\n\t\t\tbuf[BPB_NumFATsEx] = 1;\t\t\t\t\t/* Number of FATs */\n\t\t\tbuf[BPB_DrvNumEx] = 0x80;\t\t\t\t/* Drive number (for int13) */\n\t\t\tst_word(buf + BS_BootCodeEx, 0xFEEB);\t/* Boot code (x86) */\n\t\t\tst_word(buf + BS_55AA, 0xAA55);\t\t\t/* Signature (placed here regardless of sector size) */\n\t\t\tfor (i = sum = 0; i < ss; i++) {\t\t/* VBR checksum */\n\t\t\t\tif (i != BPB_VolFlagEx && i != BPB_VolFlagEx + 1 && i != BPB_PercInUseEx) sum = xsum32(buf[i], sum);\n\t\t\t}\n\t\t\tif (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\t/* Extended bootstrap record (+1..+8) */\n\t\t\tmem_set(buf, 0, ss);\n\t\t\tst_word(buf + ss - 2, 0xAA55);\t/* Signature (placed at end of sector) */\n\t\t\tfor (j = 1; j < 9; j++) {\n\t\t\t\tfor (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ;\t/* VBR checksum */\n\t\t\t\tif (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\t}\n\t\t\t/* OEM/Reserved record (+9..+10) */\n\t\t\tmem_set(buf, 0, ss);\n\t\t\tfor ( ; j < 11; j++) {\n\t\t\t\tfor (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ;\t/* VBR checksum */\n\t\t\t\tif (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\t}\n\t\t\t/* Sum record (+11) */\n\t\t\tfor (i = 0; i < ss; i += 4) st_dword(buf + i, sum);\t\t/* Fill with checksum value */\n\t\t\tif (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t}\n\n\t} else\n#endif\t/* FF_FS_EXFAT */\n\t{\t/* Create an FAT/FAT32 volume */\n\t\tdo {\n\t\t\tpau = au;\n\t\t\t/* Pre-determine number of clusters and FAT sub-type */\n\t\t\tif (fmt == FS_FAT32) {\t/* FAT32 volume */\n\t\t\t\tif (pau == 0) {\t/* au auto-selection */\n\t\t\t\t\tn = sz_vol / 0x20000;\t/* Volume size in unit of 128KS */\n\t\t\t\t\tfor (i = 0, pau = 1; cst32[i] && cst32[i] <= n; i++, pau <<= 1) ;\t/* Get from table */\n\t\t\t\t}\n\t\t\t\tn_clst = sz_vol / pau;\t/* Number of clusters */\n\t\t\t\tsz_fat = (n_clst * 4 + 8 + ss - 1) / ss;\t/* FAT size [sector] */\n\t\t\t\tsz_rsv = 32;\t/* Number of reserved sectors */\n\t\t\t\tsz_dir = 0;\t\t/* No static directory */\n\t\t\t\tif (n_clst <= MAX_FAT16 || n_clst > MAX_FAT32) LEAVE_MKFS(FR_MKFS_ABORTED);\n\t\t\t} else {\t\t\t\t/* FAT volume */\n\t\t\t\tif (pau == 0) {\t/* au auto-selection */\n\t\t\t\t\tn = sz_vol / 0x1000;\t/* Volume size in unit of 4KS */\n\t\t\t\t\tfor (i = 0, pau = 1; cst[i] && cst[i] <= n; i++, pau <<= 1) ;\t/* Get from table */\n\t\t\t\t}\n\t\t\t\tn_clst = sz_vol / pau;\n\t\t\t\tif (n_clst > MAX_FAT12) {\n\t\t\t\t\tn = n_clst * 2 + 4;\t\t/* FAT size [byte] */\n\t\t\t\t} else {\n\t\t\t\t\tfmt = FS_FAT12;\n\t\t\t\t\tn = (n_clst * 3 + 1) / 2 + 3;\t/* FAT size [byte] */\n\t\t\t\t}\n\t\t\t\tsz_fat = (n + ss - 1) / ss;\t\t/* FAT size [sector] */\n\t\t\t\tsz_rsv = 1;\t\t\t\t\t\t/* Number of reserved sectors */\n\t\t\t\tsz_dir = (DWORD)n_rootdir * SZDIRE / ss;\t/* Rootdir size [sector] */\n\t\t\t}\n\t\t\tb_fat = b_vol + sz_rsv;\t\t\t\t\t\t/* FAT base */\n\t\t\tb_data = b_fat + sz_fat * n_fats + sz_dir;\t/* Data base */\n\n\t\t\t/* Align data base to erase block boundary (for flash memory media) */\n\t\t\tn = ((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data;\t/* Next nearest erase block from current data base */\n\t\t\tif (fmt == FS_FAT32) {\t\t/* FAT32: Move FAT base */\n\t\t\t\tsz_rsv += n; b_fat += n;\n\t\t\t} else {\t\t\t\t\t/* FAT: Expand FAT size */\n\t\t\t\tsz_fat += n / n_fats;\n\t\t\t}\n\n\t\t\t/* Determine number of clusters and final check of validity of the FAT sub-type */\n\t\t\tif (sz_vol < b_data + pau * 16 - b_vol) LEAVE_MKFS(FR_MKFS_ABORTED);\t/* Too small volume */\n\t\t\tn_clst = (sz_vol - sz_rsv - sz_fat * n_fats - sz_dir) / pau;\n\t\t\tif (fmt == FS_FAT32) {\n\t\t\t\tif (n_clst <= MAX_FAT16) {\t/* Too few clusters for FAT32 */\n\t\t\t\t\tif (au == 0 && (au = pau / 2) != 0) continue;\t/* Adjust cluster size and retry */\n\t\t\t\t\tLEAVE_MKFS(FR_MKFS_ABORTED);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (fmt == FS_FAT16) {\n\t\t\t\tif (n_clst > MAX_FAT16) {\t/* Too many clusters for FAT16 */\n\t\t\t\t\tif (au == 0 && (pau * 2) <= 64) {\n\t\t\t\t\t\tau = pau * 2; continue;\t\t/* Adjust cluster size and retry */\n\t\t\t\t\t}\n\t\t\t\t\tif ((opt & FM_FAT32)) {\n\t\t\t\t\t\tfmt = FS_FAT32; continue;\t/* Switch type to FAT32 and retry */\n\t\t\t\t\t}\n\t\t\t\t\tif (au == 0 && (au = pau * 2) <= 128) continue;\t/* Adjust cluster size and retry */\n\t\t\t\t\tLEAVE_MKFS(FR_MKFS_ABORTED);\n\t\t\t\t}\n\t\t\t\tif  (n_clst <= MAX_FAT12) {\t/* Too few clusters for FAT16 */\n\t\t\t\t\tif (au == 0 && (au = pau * 2) <= 128) continue;\t/* Adjust cluster size and retry */\n\t\t\t\t\tLEAVE_MKFS(FR_MKFS_ABORTED);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (fmt == FS_FAT12 && n_clst > MAX_FAT12) LEAVE_MKFS(FR_MKFS_ABORTED);\t/* Too many clusters for FAT12 */\n\n\t\t\t/* Ok, it is the valid cluster configuration */\n\t\t\tbreak;\n\t\t} while (1);\n\n#if FF_USE_TRIM\n\t\ttbl[0] = b_vol; tbl[1] = b_vol + sz_vol - 1;\t/* Inform the device the volume area can be erased */\n\t\tdisk_ioctl(pdrv, CTRL_TRIM, tbl);\n#endif\n\t\t/* Create FAT VBR */\n\t\tmem_set(buf, 0, ss);\n\t\tmem_cpy(buf + BS_JmpBoot, \"\\xEB\\xFE\\x90\" \"MSDOS5.0\", 11);/* Boot jump code (x86), OEM name */\n\t\tst_word(buf + BPB_BytsPerSec, ss);\t\t\t\t/* Sector size [byte] */\n\t\tbuf[BPB_SecPerClus] = (BYTE)pau;\t\t\t\t/* Cluster size [sector] */\n\t\tst_word(buf + BPB_RsvdSecCnt, (WORD)sz_rsv);\t/* Size of reserved area */\n\t\tbuf[BPB_NumFATs] = (BYTE)n_fats;\t\t\t\t/* Number of FATs */\n\t\tst_word(buf + BPB_RootEntCnt, (WORD)((fmt == FS_FAT32) ? 0 : n_rootdir));\t/* Number of root directory entries */\n\t\tif (sz_vol < 0x10000) {\n\t\t\tst_word(buf + BPB_TotSec16, (WORD)sz_vol);\t/* Volume size in 16-bit LBA */\n\t\t} else {\n\t\t\tst_dword(buf + BPB_TotSec32, sz_vol);\t\t/* Volume size in 32-bit LBA */\n\t\t}\n\t\tbuf[BPB_Media] = 0xF8;\t\t\t\t\t\t\t/* Media descriptor byte */\n\t\tst_word(buf + BPB_SecPerTrk, 63);\t\t\t\t/* Number of sectors per track (for int13) */\n\t\tst_word(buf + BPB_NumHeads, 255);\t\t\t\t/* Number of heads (for int13) */\n\t\tst_dword(buf + BPB_HiddSec, b_vol);\t\t\t\t/* Volume offset in the physical drive [sector] */\n\t\tif (fmt == FS_FAT32) {\n\t\t\tst_dword(buf + BS_VolID32, GET_FATTIME());\t/* VSN */\n\t\t\tst_dword(buf + BPB_FATSz32, sz_fat);\t\t/* FAT size [sector] */\n\t\t\tst_dword(buf + BPB_RootClus32, 2);\t\t\t/* Root directory cluster # (2) */\n\t\t\tst_word(buf + BPB_FSInfo32, 1);\t\t\t\t/* Offset of FSINFO sector (VBR + 1) */\n\t\t\tst_word(buf + BPB_BkBootSec32, 6);\t\t\t/* Offset of backup VBR (VBR + 6) */\n\t\t\tbuf[BS_DrvNum32] = 0x80;\t\t\t\t\t/* Drive number (for int13) */\n\t\t\tbuf[BS_BootSig32] = 0x29;\t\t\t\t\t/* Extended boot signature */\n\t\t\tmem_cpy(buf + BS_VolLab32, \"NO NAME    \" \"FAT32   \", 19);\t/* Volume label, FAT signature */\n\t\t} else {\n\t\t\tst_dword(buf + BS_VolID, GET_FATTIME());\t/* VSN */\n\t\t\tst_word(buf + BPB_FATSz16, (WORD)sz_fat);\t/* FAT size [sector] */\n\t\t\tbuf[BS_DrvNum] = 0x80;\t\t\t\t\t\t/* Drive number (for int13) */\n\t\t\tbuf[BS_BootSig] = 0x29;\t\t\t\t\t\t/* Extended boot signature */\n\t\t\tmem_cpy(buf + BS_VolLab, \"NO NAME    \" \"FAT     \", 19);\t/* Volume label, FAT signature */\n\t\t}\n\t\tst_word(buf + BS_55AA, 0xAA55);\t\t\t\t\t/* Signature (offset is fixed here regardless of sector size) */\n\t\tif (disk_write(pdrv, buf, b_vol, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\t/* Write it to the VBR sector */\n\n\t\t/* Create FSINFO record if needed */\n\t\tif (fmt == FS_FAT32) {\n\t\t\tdisk_write(pdrv, buf, b_vol + 6, 1);\t\t/* Write backup VBR (VBR + 6) */\n\t\t\tmem_set(buf, 0, ss);\n\t\t\tst_dword(buf + FSI_LeadSig, 0x41615252);\n\t\t\tst_dword(buf + FSI_StrucSig, 0x61417272);\n\t\t\tst_dword(buf + FSI_Free_Count, n_clst - 1);\t/* Number of free clusters */\n\t\t\tst_dword(buf + FSI_Nxt_Free, 2);\t\t\t/* Last allocated cluster# */\n\t\t\tst_word(buf + BS_55AA, 0xAA55);\n\t\t\tdisk_write(pdrv, buf, b_vol + 7, 1);\t\t/* Write backup FSINFO (VBR + 7) */\n\t\t\tdisk_write(pdrv, buf, b_vol + 1, 1);\t\t/* Write original FSINFO (VBR + 1) */\n\t\t}\n\n\t\t/* Initialize FAT area */\n\t\tmem_set(buf, 0, (UINT)szb_buf);\n\t\tsect = b_fat;\t\t/* FAT start sector */\n\t\tfor (i = 0; i < n_fats; i++) {\t\t\t/* Initialize FATs each */\n\t\t\tif (fmt == FS_FAT32) {\n\t\t\t\tst_dword(buf + 0, 0xFFFFFFF8);\t/* Entry 0 */\n\t\t\t\tst_dword(buf + 4, 0xFFFFFFFF);\t/* Entry 1 */\n\t\t\t\tst_dword(buf + 8, 0x0FFFFFFF);\t/* Entry 2 (root directory) */\n\t\t\t} else {\n\t\t\t\tst_dword(buf + 0, (fmt == FS_FAT12) ? 0xFFFFF8 : 0xFFFFFFF8);\t/* Entry 0 and 1 */\n\t\t\t}\n\t\t\tnsect = sz_fat;\t\t/* Number of FAT sectors */\n\t\t\tdo {\t/* Fill FAT sectors */\n\t\t\t\tn = (nsect > sz_buf) ? sz_buf : nsect;\n\t\t\t\tif (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\t\tmem_set(buf, 0, ss);\n\t\t\t\tsect += n; nsect -= n;\n\t\t\t} while (nsect);\n\t\t}\n\n\t\t/* Initialize root directory (fill with zero) */\n\t\tnsect = (fmt == FS_FAT32) ? pau : sz_dir;\t/* Number of root directory sectors */\n\t\tdo {\n\t\t\tn = (nsect > sz_buf) ? sz_buf : nsect;\n\t\t\tif (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\t\t\tsect += n; nsect -= n;\n\t\t} while (nsect);\n\t}\n\n\t/* Determine system ID in the partition table */\n\tif (FF_FS_EXFAT && fmt == FS_EXFAT) {\n\t\tsys = 0x07;\t\t\t/* HPFS/NTFS/exFAT */\n\t} else {\n\t\tif (fmt == FS_FAT32) {\n\t\t\tsys = 0x0C;\t\t/* FAT32X */\n\t\t} else {\n\t\t\tif (sz_vol >= 0x10000) {\n\t\t\t\tsys = 0x06;\t/* FAT12/16 (large) */\n\t\t\t} else {\n\t\t\t\tsys = (fmt == FS_FAT16) ? 0x04 : 0x01;\t/* FAT16 : FAT12 */\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Update partition information */\n\tif (FF_MULTI_PARTITION && part != 0) {\t/* Created in the existing partition */\n\t\t/* Update system ID in the partition table */\n\t\tif (disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\t/* Read the MBR */\n\t\tbuf[MBR_Table + (part - 1) * SZ_PTE + PTE_System] = sys;\t\t/* Set system ID */\n\t\tif (disk_write(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\t/* Write it back to the MBR */\n\t} else {\t\t\t\t\t\t\t\t/* Created as a new single partition */\n\t\tif (!(opt & FM_SFD)) {\t/* Create partition table if in FDISK format */\n\t\t\tmem_set(buf, 0, ss);\n\t\t\tst_word(buf + BS_55AA, 0xAA55);\t\t/* MBR signature */\n\t\t\tpte = buf + MBR_Table;\t\t\t\t/* Create partition table for single partition in the drive */\n\t\t\tpte[PTE_Boot] = 0;\t\t\t\t\t/* Boot indicator */\n\t\t\tpte[PTE_StHead] = 1;\t\t\t\t/* Start head */\n\t\t\tpte[PTE_StSec] = 1;\t\t\t\t\t/* Start sector */\n\t\t\tpte[PTE_StCyl] = 0;\t\t\t\t\t/* Start cylinder */\n\t\t\tpte[PTE_System] = sys;\t\t\t\t/* System type */\n\t\t\tn = (b_vol + sz_vol) / (63 * 255);\t/* (End CHS may be invalid) */\n\t\t\tpte[PTE_EdHead] = 254;\t\t\t\t/* End head */\n\t\t\tpte[PTE_EdSec] = (BYTE)(((n >> 2) & 0xC0) | 63);\t/* End sector */\n\t\t\tpte[PTE_EdCyl] = (BYTE)n;\t\t\t/* End cylinder */\n\t\t\tst_dword(pte + PTE_StLba, b_vol);\t/* Start offset in LBA */\n\t\t\tst_dword(pte + PTE_SizLba, sz_vol);\t/* Size in sectors */\n\t\t\tif (disk_write(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\t/* Write it to the MBR */\n\t\t}\n\t}\n\n\tif (disk_ioctl(pdrv, CTRL_SYNC, 0) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);\n\n\tLEAVE_MKFS(FR_OK);\n}\n\n\n\n#if FF_MULTI_PARTITION\n/*-----------------------------------------------------------------------*/\n/* Create Partition Table on the Physical Drive                          */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_fdisk (\n\tBYTE pdrv,\t\t\t/* Physical drive number */\n\tconst DWORD* szt,\t/* Pointer to the size table for each partitions */\n\tvoid* work\t\t\t/* Pointer to the working buffer (null: use heap memory) */\n)\n{\n\tUINT i, n, sz_cyl, tot_cyl, b_cyl, e_cyl, p_cyl;\n\tBYTE s_hd, e_hd, *p, *buf = (BYTE*)work;\n\tDSTATUS stat;\n\tDWORD sz_disk, sz_part, s_part;\n\tFRESULT res;\n\n\n\tstat = disk_initialize(pdrv);\n\tif (stat & STA_NOINIT) return FR_NOT_READY;\n\tif (stat & STA_PROTECT) return FR_WRITE_PROTECTED;\n\tif (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_disk)) return FR_DISK_ERR;\n\n\tbuf = (BYTE*)work;\n#if FF_USE_LFN == 3\n\tif (!buf) buf = ff_memalloc(FF_MAX_SS);\t/* Use heap memory for working buffer */\n#endif\n\tif (!buf) return FR_NOT_ENOUGH_CORE;\n\n\t/* Determine the CHS without any consideration of the drive geometry */\n\tfor (n = 16; n < 256 && sz_disk / n / 63 > 1024; n *= 2) ;\n\tif (n == 256) n--;\n\te_hd = (BYTE)(n - 1);\n\tsz_cyl = 63 * n;\n\ttot_cyl = sz_disk / sz_cyl;\n\n\t/* Create partition table */\n\tmem_set(buf, 0, FF_MAX_SS);\n\tp = buf + MBR_Table; b_cyl = 0;\n\tfor (i = 0; i < 4; i++, p += SZ_PTE) {\n\t\tp_cyl = (szt[i] <= 100U) ? (DWORD)tot_cyl * szt[i] / 100 : szt[i] / sz_cyl;\t/* Number of cylinders */\n\t\tif (p_cyl == 0) continue;\n\t\ts_part = (DWORD)sz_cyl * b_cyl;\n\t\tsz_part = (DWORD)sz_cyl * p_cyl;\n\t\tif (i == 0) {\t/* Exclude first track of cylinder 0 */\n\t\t\ts_hd = 1;\n\t\t\ts_part += 63; sz_part -= 63;\n\t\t} else {\n\t\t\ts_hd = 0;\n\t\t}\n\t\te_cyl = b_cyl + p_cyl - 1;\t/* End cylinder */\n\t\tif (e_cyl >= tot_cyl) LEAVE_MKFS(FR_INVALID_PARAMETER);\n\n\t\t/* Set partition table */\n\t\tp[1] = s_hd;\t\t\t\t\t\t/* Start head */\n\t\tp[2] = (BYTE)(((b_cyl >> 2) & 0xC0) | 1);\t/* Start sector */\n\t\tp[3] = (BYTE)b_cyl;\t\t\t\t\t/* Start cylinder */\n\t\tp[4] = 0x07;\t\t\t\t\t\t/* System type (temporary setting) */\n\t\tp[5] = e_hd;\t\t\t\t\t\t/* End head */\n\t\tp[6] = (BYTE)(((e_cyl >> 2) & 0xC0) | 63);\t/* End sector */\n\t\tp[7] = (BYTE)e_cyl;\t\t\t\t\t/* End cylinder */\n\t\tst_dword(p + 8, s_part);\t\t\t/* Start sector in LBA */\n\t\tst_dword(p + 12, sz_part);\t\t\t/* Number of sectors */\n\n\t\t/* Next partition */\n\t\tb_cyl += p_cyl;\n\t}\n\tst_word(p, 0xAA55);\t\t/* MBR signature (always at offset 510) */\n\n\t/* Write it to the MBR */\n\tres = (disk_write(pdrv, buf, 0, 1) == RES_OK && disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR;\n\tLEAVE_MKFS(res);\n}\n\n#endif /* FF_MULTI_PARTITION */\n#endif /* FF_USE_MKFS && !FF_FS_READONLY */\n\n\n\n\n#if FF_USE_STRFUNC\n#if FF_USE_LFN && FF_LFN_UNICODE && (FF_STRF_ENCODE < 0 || FF_STRF_ENCODE > 3)\n#error Wrong FF_STRF_ENCODE setting\n#endif\n/*-----------------------------------------------------------------------*/\n/* Get a String from the File                                            */\n/*-----------------------------------------------------------------------*/\n\nTCHAR* f_gets (\n\tTCHAR* buff,\t/* Pointer to the string buffer to read */\n\tint len,\t\t/* Size of string buffer (items) */\n\tFIL* fp\t\t\t/* Pointer to the file object */\n)\n{\n\tint nc = 0;\n\tTCHAR *p = buff;\n\tBYTE s[4];\n\tUINT rc;\n\tDWORD dc;\n#if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE <= 2\n\tWCHAR wc;\n#endif\n#if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE == 3\n\tUINT ct;\n#endif\n\n#if FF_USE_LFN && FF_LFN_UNICODE\t\t\t/* With code conversion (Unicode API) */\n\t/* Make a room for the character and terminator  */\n\tif (FF_LFN_UNICODE == 1) len -= (FF_STRF_ENCODE == 0) ? 1 : 2;\n\tif (FF_LFN_UNICODE == 2) len -= (FF_STRF_ENCODE == 0) ? 3 : 4;\n\tif (FF_LFN_UNICODE == 3) len -= 1;\n\twhile (nc < len) {\n#if FF_STRF_ENCODE == 0\t\t/* Read a character in ANSI/OEM */\n\t\tf_read(fp, s, 1, &rc);\n\t\tif (rc != 1) break;\n\t\twc = s[0];\n\t\tif (dbc_1st((BYTE)wc)) {\n\t\t\tf_read(fp, s, 1, &rc);\n\t\t\tif (rc != 1 || !dbc_2nd(s[0])) continue;\n\t\t\twc = wc << 8 | s[0];\n\t\t}\n\t\tdc = ff_oem2uni(wc, CODEPAGE);\n\t\tif (dc == 0) continue;\n#elif FF_STRF_ENCODE == 1 || FF_STRF_ENCODE == 2 \t/* Read a character in UTF-16LE/BE */\n\t\tf_read(fp, s, 2, &rc);\n\t\tif (rc != 2) break;\n\t\tdc = (FF_STRF_ENCODE == 1) ? ld_word(s) : s[0] << 8 | s[1];\n\t\tif (IsSurrogateL(dc)) continue;\n\t\tif (IsSurrogateH(dc)) {\n\t\t\tf_read(fp, s, 2, &rc);\n\t\t\tif (rc != 2) break;\n\t\t\twc = (FF_STRF_ENCODE == 1) ? ld_word(s) : s[0] << 8 | s[1];\n\t\t\tif (!IsSurrogateL(wc)) continue;\n\t\t\tdc = ((dc & 0x3FF) + 0x40) << 10 | (wc & 0x3FF);\n\t\t}\n#else\t/* Read a character in UTF-8 */\n\t\tf_read(fp, s, 1, &rc);\n\t\tif (rc != 1) break;\n\t\tdc = s[0];\n\t\tif (dc >= 0x80) {\t/* Multi-byte character? */\n\t\t\tct = 0;\n\t\t\tif ((dc & 0xE0) == 0xC0) { dc &= 0x1F; ct = 1; }\t/* 2-byte? */\n\t\t\tif ((dc & 0xF0) == 0xE0) { dc &= 0x0F; ct = 2; }\t/* 3-byte? */\n\t\t\tif ((dc & 0xF8) == 0xF0) { dc &= 0x07; ct = 3; }\t/* 4-byte? */\n\t\t\tif (ct == 0) continue;\n\t\t\tf_read(fp, s, ct, &rc);\t\t/* Get trailing bytes */\n\t\t\tif (rc != ct) break;\n\t\t\trc = 0;\n\t\t\tdo {\t/* Merge trailing bytes */\n\t\t\t\tif ((s[rc] & 0xC0) != 0x80) break;\n\t\t\t\tdc = dc << 6 | (s[rc] & 0x3F);\n\t\t\t} while (++rc < ct);\n\t\t\tif (rc != ct || dc < 0x80 || IsSurrogate(dc) || dc >= 0x110000) continue;\t/* Wrong encoding? */\n\t\t}\n#endif\n\t\tif (FF_USE_STRFUNC == 2 && dc == '\\r') continue;\t/* Strip \\r off if needed */\n#if FF_LFN_UNICODE == 1\t|| FF_LFN_UNICODE == 3\t/* Output it in UTF-16/32 encoding */\n\t\tif (FF_LFN_UNICODE == 1 && dc >= 0x10000) {\t/* Out of BMP at UTF-16? */\n\t\t\t*p++ = (TCHAR)(0xD800 | ((dc >> 10) - 0x40)); nc++;\t/* Make and output high surrogate */\n\t\t\tdc = 0xDC00 | (dc & 0x3FF);\t\t/* Make low surrogate */\n\t\t}\n\t\t*p++ = (TCHAR)dc; nc++;\n\t\tif (dc == '\\n') break;\t/* End of line? */\n#elif FF_LFN_UNICODE == 2\t\t/* Output it in UTF-8 encoding */\n\t\tif (dc < 0x80) {\t/* 1-byte */\n\t\t\t*p++ = (TCHAR)dc;\n\t\t\tnc++;\n\t\t\tif (dc == '\\n') break;\t/* End of line? */\n\t\t} else {\n\t\t\tif (dc < 0x800) {\t\t/* 2-byte */\n\t\t\t\t*p++ = (TCHAR)(0xC0 | (dc >> 6 & 0x1F));\n\t\t\t\t*p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F));\n\t\t\t\tnc += 2;\n\t\t\t} else {\n\t\t\t\tif (dc < 0x10000) {\t/* 3-byte */\n\t\t\t\t\t*p++ = (TCHAR)(0xE0 | (dc >> 12 & 0x0F));\n\t\t\t\t\t*p++ = (TCHAR)(0x80 | (dc >> 6 & 0x3F));\n\t\t\t\t\t*p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F));\n\t\t\t\t\tnc += 3;\n\t\t\t\t} else {\t\t\t/* 4-byte */\n\t\t\t\t\t*p++ = (TCHAR)(0xF0 | (dc >> 18 & 0x07));\n\t\t\t\t\t*p++ = (TCHAR)(0x80 | (dc >> 12 & 0x3F));\n\t\t\t\t\t*p++ = (TCHAR)(0x80 | (dc >> 6 & 0x3F));\n\t\t\t\t\t*p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F));\n\t\t\t\t\tnc += 4;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n#endif\n\t}\n\n#else\t\t\t/* Byte-by-byte without any conversion (ANSI/OEM API) */\n\tlen -= 1;\t/* Make a room for the terminator */\n\twhile (nc < len) {\n\t\tf_read(fp, s, 1, &rc);\n\t\tif (rc != 1) break;\n\t\tdc = s[0];\n\t\tif (FF_USE_STRFUNC == 2 && dc == '\\r') continue;\n\t\t*p++ = (TCHAR)dc; nc++;\n\t\tif (dc == '\\n') break;\n\t}\n#endif\n\n\t*p = 0;\t\t/* Terminate the string */\n\treturn nc ? buff : 0;\t/* When no data read due to EOF or error, return with error. */\n}\n\n\n\n\n#if !FF_FS_READONLY\n#include <stdarg.h>\n/*-----------------------------------------------------------------------*/\n/* Put a Character to the File                                           */\n/*-----------------------------------------------------------------------*/\n\ntypedef struct {\t/* Putchar output buffer and work area */\n\tFIL *fp;\t\t/* Ptr to the writing file */\n\tint idx, nchr;\t/* Write index of buf[] (-1:error), number of encoding units written */\n#if FF_USE_LFN && FF_LFN_UNICODE == 1\n\tWCHAR hs;\n#elif FF_USE_LFN && FF_LFN_UNICODE == 2\n\tBYTE bs[4];\n\tUINT wi, ct;\n#endif\n\tBYTE buf[64];\t/* Write buffer */\n} putbuff;\n\n\nstatic void putc_bfd (\t\t/* Buffered write with code conversion */\n\tputbuff* pb,\n\tTCHAR c\n)\n{\n\tUINT n;\n\tint i, nc;\n#if FF_USE_LFN && FF_LFN_UNICODE\n\tWCHAR hs, wc;\n#if FF_LFN_UNICODE == 2\n\tDWORD dc;\n\tTCHAR *tp;\n#endif\n#endif\n\n\tif (FF_USE_STRFUNC == 2 && c == '\\n') {\t /* LF -> CRLF conversion */\n\t\tputc_bfd(pb, '\\r');\n\t}\n\n\ti = pb->idx;\t\t\t/* Write index of pb->buf[] */\n\tif (i < 0) return;\n\tnc = pb->nchr;\t\t\t/* Write unit counter */\n\n#if FF_USE_LFN && FF_LFN_UNICODE\n#if FF_LFN_UNICODE == 1\t\t/* UTF-16 input */\n\tif (IsSurrogateH(c)) {\n\t\tpb->hs = c; return;\n\t}\n\ths = pb->hs; pb->hs = 0;\n\tif (hs != 0) {\n\t\tif (!IsSurrogateL(c)) hs = 0;\n\t} else {\n\t\tif (IsSurrogateL(c)) return;\n\t}\n\twc = c;\n#elif FF_LFN_UNICODE == 2\t/* UTF-8 input */\n\tfor (;;) {\n\t\tif (pb->ct == 0) {\t/* Out of multi-byte sequence? */\n\t\t\tpb->bs[pb->wi = 0] = (BYTE)c;\t/* Save 1st byte */\n\t\t\tif ((BYTE)c < 0x80) break;\t\t\t\t\t/* 1-byte? */\n\t\t\tif (((BYTE)c & 0xE0) == 0xC0) pb->ct = 1;\t/* 2-byte? */\n\t\t\tif (((BYTE)c & 0xF0) == 0xE0) pb->ct = 2;\t/* 3-byte? */\n\t\t\tif (((BYTE)c & 0xF1) == 0xF0) pb->ct = 3;\t/* 4-byte? */\n\t\t\treturn;\n\t\t} else {\t\t\t\t/* In the multi-byte sequence */\n\t\t\tif (((BYTE)c & 0xC0) != 0x80) {\t/* Broken sequence? */\n\t\t\t\tpb->ct = 0; continue;\n\t\t\t}\n\t\t\tpb->bs[++pb->wi] = (BYTE)c;\t/* Save the trailing byte */\n\t\t\tif (--pb->ct == 0) break;\t/* End of multi-byte sequence? */\n\t\t\treturn;\n\t\t}\n\t}\n\ttp = (TCHAR*)pb->bs;\n\tdc = tchar2uni(&tp);\t/* UTF-8 ==> UTF-16 */\n\tif (dc == 0xFFFFFFFF) return;\n\twc = (WCHAR)dc;\n\ths = (WCHAR)(dc >> 16);\n#elif FF_LFN_UNICODE == 3\t/* UTF-32 input */\n\tif (IsSurrogate(c) || c >= 0x110000) return;\n\tif (c >= 0x10000) {\n\t\ths = (WCHAR)(0xD800 | ((c >> 10) - 0x40)); \t/* Make high surrogate */\n\t\twc = 0xDC00 | (c & 0x3FF);\t\t\t\t\t/* Make low surrogate */\n\t} else {\n\t\ths = 0;\n\t\twc = (WCHAR)c;\n\t}\n#endif\n\n#if FF_STRF_ENCODE == 1\t\t/* Write a character in UTF-16LE */\n\tif (hs != 0) {\n\t\tst_word(&pb->buf[i], hs);\n\t\ti += 2;\n\t\tnc++;\n\t}\n\tst_word(&pb->buf[i], wc);\n\ti += 2;\n#elif FF_STRF_ENCODE == 2\t/* Write a character in UTF-16BE */\n\tif (hs != 0) {\n\t\tpb->buf[i++] = (BYTE)(hs >> 8);\n\t\tpb->buf[i++] = (BYTE)hs;\n\t\tnc++;\n\t}\n\tpb->buf[i++] = (BYTE)(wc >> 8);\n\tpb->buf[i++] = (BYTE)wc;\n#elif FF_STRF_ENCODE == 3\t/* Write it in UTF-8 */\n\tif (hs != 0) {\t\t\t\t/* 4-byte */\n\t\tnc += 3;\n\t\ths = (hs & 0x3FF) + 0x40;\n\t\tpb->buf[i++] = (BYTE)(0xF0 | hs >> 8);\n\t\tpb->buf[i++] = (BYTE)(0x80 | (hs >> 2 & 0x3F));\n\t\tpb->buf[i++] = (BYTE)(0x80 | (hs & 3) << 4 | (wc >> 6 & 0x0F));\n\t\tpb->buf[i++] = (BYTE)(0x80 | (wc & 0x3F));\n\t} else {\n\t\tif (wc < 0x80) {\t\t/* 1-byte */\n\t\t\tpb->buf[i++] = (BYTE)wc;\n\t\t} else {\n\t\t\tif (wc < 0x800) {\t/* 2-byte */\n\t\t\t\tnc += 1;\n\t\t\t\tpb->buf[i++] = (BYTE)(0xC0 | wc >> 6);\n\t\t\t} else {\t\t\t/* 3-byte */\n\t\t\t\tnc += 2;\n\t\t\t\tpb->buf[i++] = (BYTE)(0xE0 | wc >> 12);\n\t\t\t\tpb->buf[i++] = (BYTE)(0x80 | (wc >> 6 & 0x3F));\n\t\t\t}\n\t\t\tpb->buf[i++] = (BYTE)(0x80 | (wc & 0x3F));\n\t\t}\n\t}\n#else\t\t\t\t\t\t/* Write it in ANSI/OEM */\n\tif (hs != 0) return;\n\twc = ff_uni2oem(wc, CODEPAGE);\t/* UTF-16 ==> ANSI/OEM */\n\tif (wc == 0) return;\n\tif (wc >= 0x100) {\n\t\tpb->buf[i++] = (BYTE)(wc >> 8); nc++;\n\t}\n\tpb->buf[i++] = (BYTE)wc;\n#endif\n\n#else\t\t\t\t\t\t\t\t\t/* ANSI/OEM input (without re-encode) */\n\tpb->buf[i++] = (BYTE)c;\n#endif\n\n\tif (i >= (int)(sizeof pb->buf) - 4) {\t/* Write buffered characters to the file */\n\t\tf_write(pb->fp, pb->buf, (UINT)i, &n);\n\t\ti = (n == (UINT)i) ? 0 : -1;\n\t}\n\tpb->idx = i;\n\tpb->nchr = nc + 1;\n}\n\n\nstatic int putc_flush (\t\t/* Flush left characters in the buffer */\n\tputbuff* pb\n)\n{\n\tUINT nw;\n\n\tif (   pb->idx >= 0\t/* Flush buffered characters to the file */\n\t\t&& f_write(pb->fp, pb->buf, (UINT)pb->idx, &nw) == FR_OK\n\t\t&& (UINT)pb->idx == nw) return pb->nchr;\n\treturn EOF;\n}\n\n\nstatic void putc_init (\t\t/* Initialize write buffer */\n\tputbuff* pb,\n\tFIL* fp\n)\n{\n\tmem_set(pb, 0, sizeof (putbuff));\n\tpb->fp = fp;\n}\n\n\n\nint f_putc (\n\tTCHAR c,\t/* A character to be output */\n\tFIL* fp\t\t/* Pointer to the file object */\n)\n{\n\tputbuff pb;\n\n\n\tputc_init(&pb, fp);\n\tputc_bfd(&pb, c);\t/* Put the character */\n\treturn putc_flush(&pb);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Put a String to the File                                              */\n/*-----------------------------------------------------------------------*/\n\nint f_puts (\n\tconst TCHAR* str,\t/* Pointer to the string to be output */\n\tFIL* fp\t\t\t\t/* Pointer to the file object */\n)\n{\n\tputbuff pb;\n\n\n\tputc_init(&pb, fp);\n\twhile (*str) putc_bfd(&pb, *str++);\t\t/* Put the string */\n\treturn putc_flush(&pb);\n}\n\n\n\n\n/*-----------------------------------------------------------------------*/\n/* Put a Formatted String to the File                                    */\n/*-----------------------------------------------------------------------*/\n\nint f_printf (\n\tFIL* fp,\t\t\t/* Pointer to the file object */\n\tconst TCHAR* fmt,\t/* Pointer to the format string */\n\t...\t\t\t\t\t/* Optional arguments... */\n)\n{\n\tva_list arp;\n\tputbuff pb;\n\tBYTE f, r;\n\tUINT i, j, w;\n\tDWORD v;\n\tTCHAR c, d, str[32], *p;\n\n\n\tputc_init(&pb, fp);\n\n\tva_start(arp, fmt);\n\n\tfor (;;) {\n\t\tc = *fmt++;\n\t\tif (c == 0) break;\t\t\t/* End of string */\n\t\tif (c != '%') {\t\t\t\t/* Non escape character */\n\t\t\tputc_bfd(&pb, c);\n\t\t\tcontinue;\n\t\t}\n\t\tw = f = 0;\n\t\tc = *fmt++;\n\t\tif (c == '0') {\t\t\t\t/* Flag: '0' padding */\n\t\t\tf = 1; c = *fmt++;\n\t\t} else {\n\t\t\tif (c == '-') {\t\t\t/* Flag: left justified */\n\t\t\t\tf = 2; c = *fmt++;\n\t\t\t}\n\t\t}\n\t\tif (c == '*') {\t\t\t\t/* Minimum width by argument */\n\t\t\tw = va_arg(arp, int);\n\t\t\tc = *fmt++;\n\t\t} else {\n\t\t\twhile (IsDigit(c)) {\t/* Minimum width */\n\t\t\t\tw = w * 10 + c - '0';\n\t\t\t\tc = *fmt++;\n\t\t\t}\n\t\t}\n\t\tif (c == 'l' || c == 'L') {\t/* Type prefix: Size is long int */\n\t\t\tf |= 4; c = *fmt++;\n\t\t}\n\t\tif (c == 0) break;\n\t\td = c;\n\t\tif (IsLower(d)) d -= 0x20;\n\t\tswitch (d) {\t\t\t\t/* Atgument type is... */\n\t\tcase 'S' :\t\t\t\t\t/* String */\n\t\t\tp = va_arg(arp, TCHAR*);\n\t\t\tfor (j = 0; p[j]; j++) ;\n\t\t\tif (!(f & 2)) {\t\t\t\t\t\t/* Right padded */\n\t\t\t\twhile (j++ < w) putc_bfd(&pb, ' ') ;\n\t\t\t}\n\t\t\twhile (*p) putc_bfd(&pb, *p++) ;\t\t/* String body */\n\t\t\twhile (j++ < w) putc_bfd(&pb, ' ') ;\t/* Left padded */\n\t\t\tcontinue;\n\n\t\tcase 'C' :\t\t\t\t\t/* Character */\n\t\t\tputc_bfd(&pb, (TCHAR)va_arg(arp, int)); continue;\n\n\t\tcase 'B' :\t\t\t\t\t/* Unsigned binary */\n\t\t\tr = 2; break;\n\n\t\tcase 'O' :\t\t\t\t\t/* Unsigned octal */\n\t\t\tr = 8; break;\n\n\t\tcase 'D' :\t\t\t\t\t/* Signed decimal */\n\t\tcase 'U' :\t\t\t\t\t/* Unsigned decimal */\n\t\t\tr = 10; break;\n\n\t\tcase 'X' :\t\t\t\t\t/* Unsigned hexdecimal */\n\t\t\tr = 16; break;\n\n\t\tdefault:\t\t\t\t\t/* Unknown type (pass-through) */\n\t\t\tputc_bfd(&pb, c); continue;\n\t\t}\n\n\t\t/* Get an argument and put it in numeral */\n\t\tv = (f & 4) ? (DWORD)va_arg(arp, long) : ((d == 'D') ? (DWORD)(long)va_arg(arp, int) : (DWORD)va_arg(arp, unsigned int));\n\t\tif (d == 'D' && (v & 0x80000000)) {\n\t\t\tv = 0 - v;\n\t\t\tf |= 8;\n\t\t}\n\t\ti = 0;\n\t\tdo {\n\t\t\td = (TCHAR)(v % r); v /= r;\n\t\t\tif (d > 9) d += (c == 'x') ? 0x27 : 0x07;\n\t\t\tstr[i++] = d + '0';\n\t\t} while (v && i < sizeof str / sizeof *str);\n\t\tif (f & 8) str[i++] = '-';\n\t\tj = i; d = (f & 1) ? '0' : ' ';\n\t\tif (!(f & 2)) {\n\t\t\twhile (j++ < w) putc_bfd(&pb, d);\t/* Right pad */\n\t\t}\n\t\tdo {\n\t\t\tputc_bfd(&pb, str[--i]);\t\t\t/* Number body */\n\t\t} while (i);\n\t\twhile (j++ < w) putc_bfd(&pb, d);\t\t/* Left pad */\n\t}\n\n\tva_end(arp);\n\n\treturn putc_flush(&pb);\n}\n\n#endif /* !FF_FS_READONLY */\n#endif /* FF_USE_STRFUNC */\n\n\n\n#if FF_CODE_PAGE == 0\n/*-----------------------------------------------------------------------*/\n/* Set Active Codepage for the Path Name                                 */\n/*-----------------------------------------------------------------------*/\n\nFRESULT f_setcp (\n\tWORD cp\t\t/* Value to be set as active code page */\n)\n{\n\tstatic const WORD       validcp[] = {  437,   720,   737,   771,   775,   850,   852,   857,   860,   861,   862,   863,   864,   865,   866,   869,   932,   936,   949,   950, 0};\n\tstatic const BYTE* const tables[] = {Ct437, Ct720, Ct737, Ct771, Ct775, Ct850, Ct852, Ct857, Ct860, Ct861, Ct862, Ct863, Ct864, Ct865, Ct866, Ct869, Dc932, Dc936, Dc949, Dc950, 0};\n\tUINT i;\n\n\n\tfor (i = 0; validcp[i] != 0 && validcp[i] != cp; i++) ;\t/* Find the code page */\n\tif (validcp[i] != cp) return FR_INVALID_PARAMETER;\t/* Not found? */\n\n\tCodePage = cp;\n\tif (cp >= 900) {\t/* DBCS */\n\t\tExCvt = 0;\n\t\tDbcTbl = tables[i];\n\t} else {\t\t\t/* SBCS */\n\t\tExCvt = tables[i];\n\t\tDbcTbl = 0;\n\t}\n\treturn FR_OK;\n}\n#endif\t/* FF_CODE_PAGE == 0 */\n\n#pragma GCC pop_options\n"
  },
  {
    "path": "argon-nx-gui/src/libs/fatfs/ffsystem.c",
    "content": "/*------------------------------------------------------------------------*/\n/* Sample Code of OS Dependent Functions for FatFs                        */\n/* (C) ChaN, 2018                                                          */\n/* (C) CTCaer, 2018                                                       */\n/*------------------------------------------------------------------------*/\n\n\n#include \"libs/fatfs/ff.h\"\n#include \"mem/heap.h\"\n\n\n\n#if FF_USE_LFN == 3\t/* Dynamic memory allocation */\n\n/*------------------------------------------------------------------------*/\n/* Allocate a memory block                                                */\n/*------------------------------------------------------------------------*/\n\nvoid* ff_memalloc (\t/* Returns pointer to the allocated memory block (null if not enough core) */\n\tUINT msize\t\t/* Number of bytes to allocate */\n)\n{\n\treturn malloc(msize);\t/* Allocate a new memory block with POSIX API */\n}\n\n\n/*------------------------------------------------------------------------*/\n/* Free a memory block                                                    */\n/*------------------------------------------------------------------------*/\n\nvoid ff_memfree (\n\tvoid* mblock\t/* Pointer to the memory block to free (nothing to do if null) */\n)\n{\n\tfree(mblock);\t/* Free the memory block with POSIX API */\n}\n\n#endif\n\n"
  },
  {
    "path": "argon-nx-gui/src/libs/fatfs/ffunicode.c",
    "content": "/*------------------------------------------------------------------------*/\n/* Unicode handling functions for FatFs R0.13c                            */\n/*------------------------------------------------------------------------*/\n/* This module will occupy a huge memory in the .const section when the    /\n/  FatFs is configured for LFN with DBCS. If the system has any Unicode    /\n/  utilitiy for the code conversion, this module should be modified to use /\n/  that function to avoid silly memory consumption.                        /\n/-------------------------------------------------------------------------*/\n/*\n/ Copyright (C) 2018, ChaN, all right reserved.\n/\n/ FatFs module is an open source software. Redistribution and use of FatFs in\n/ source and binary forms, with or without modification, are permitted provided\n/ that the following condition is met:\n/\n/ 1. Redistributions of source code must retain the above copyright notice,\n/    this condition and the following disclaimer.\n/\n/ This software is provided by the copyright holder and contributors \"AS IS\"\n/ and any warranties related to this software are DISCLAIMED.\n/ The copyright owner or contributors be NOT LIABLE for any damages caused\n/ by use of this software.\n*/\n\n\n#include \"libs/fatfs/ff.h\"\n\n#if FF_USE_LFN\t/* This module will be blanked at non-LFN configuration */\n\n#if FF_DEFINED != 86604\t/* Revision ID */\n#error Wrong include file (ff.h).\n#endif\n\n#define MERGE2(a, b) a ## b\n#define CVTBL(tbl, cp) MERGE2(tbl, cp)\n\n#pragma GCC push_options\n#pragma GCC target (\"thumb\")\n\n\n/*------------------------------------------------------------------------*/\n/* Code Conversion Tables                                                 */\n/*------------------------------------------------------------------------*/\n\n#if FF_CODE_PAGE == 437 || FF_CODE_PAGE == 0\nstatic const WCHAR uc437[] = {\t/*  CP437(U.S.) to Unicode conversion table */\n\t0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,\n\t0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,\n\t0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,\n\t0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 720 || FF_CODE_PAGE == 0\nstatic const WCHAR uc720[] = {\t/*  CP720(Arabic) to Unicode conversion table */\n\t0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,\n\t0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,\n\t0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,\n\t0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 737 || FF_CODE_PAGE == 0\nstatic const WCHAR uc737[] = {\t/*  CP737(Greek) to Unicode conversion table */\n\t0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,\n\t0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,\n\t0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,\n\t0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 771 || FF_CODE_PAGE == 0\nstatic const WCHAR uc771[] = {\t/*  CP771(KBL) to Unicode conversion table */\n\t0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,\n\t0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,\n\t0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x0104, 0x0105, 0x010C, 0x010D,\n\t0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,\n\t0x0118, 0x0119, 0x0116, 0x0117, 0x012E, 0x012F, 0x0160, 0x0161, 0x0172, 0x0173, 0x016A, 0x016B, 0x017D, 0x017E, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 775 || FF_CODE_PAGE == 0\nstatic const WCHAR uc775[] = {\t/*  CP775(Baltic) to Unicode conversion table */\n\t0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,\n\t0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,\n\t0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,\n\t0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,\n\t0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 850 || FF_CODE_PAGE == 0\nstatic const WCHAR uc850[] = {\t/*  CP850(Latin 1) to Unicode conversion table */\n\t0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,\n\t0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,\n\t0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,\n\t0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,\n\t0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,\n\t0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 852 || FF_CODE_PAGE == 0\nstatic const WCHAR uc852[] = {\t/*  CP852(Latin 2) to Unicode conversion table */\n\t0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,\n\t0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,\n\t0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,\n\t0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,\n\t0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,\n\t0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 855 || FF_CODE_PAGE == 0\nstatic const WCHAR uc855[] = {\t/*  CP855(Cyrillic) to Unicode conversion table */\n\t0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,\n\t0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,\n\t0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,\n\t0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,\n\t0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,\n\t0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 857 || FF_CODE_PAGE == 0\nstatic const WCHAR uc857[] = {\t/*  CP857(Turkish) to Unicode conversion table */\n\t0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,\n\t0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,\n\t0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,\n\t0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,\n\t0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,\n\t0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 860 || FF_CODE_PAGE == 0\nstatic const WCHAR uc860[] = {\t/*  CP860(Portuguese) to Unicode conversion table */\n\t0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2,\n\t0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3,\n\t0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,\n\t0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 861 || FF_CODE_PAGE == 0\nstatic const WCHAR uc861[] = {\t/*  CP861(Icelandic) to Unicode conversion table */\n\t0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5,\n\t0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,\n\t0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,\n\t0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 862 || FF_CODE_PAGE == 0\nstatic const WCHAR uc862[] = {\t/*  CP862(Hebrew) to Unicode conversion table */\n\t0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,\n\t0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,\n\t0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,\n\t0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 863 || FF_CODE_PAGE == 0\nstatic const WCHAR uc863[] = {\t/*  CP863(Canadian French) to Unicode conversion table */\n\t0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0,\n\t0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192,\n\t0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2219,\n\t0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 864 || FF_CODE_PAGE == 0\nstatic const WCHAR uc864[] = {\t/*  CP864(Arabic) to Unicode conversion table */\n\t0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518,\n\t0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000,\n\t0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5,\n\t0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669, 0xFED1, 0x061B, 0xFEB1, 0xFEB5, 0xFEB9, 0x061F,\n\t0x00A2, 0xFE80, 0xFE81, 0xFE83, 0xFE85, 0xFECA, 0xFE8B, 0xFE8D, 0xFE91, 0xFE93, 0xFE97, 0xFE9B, 0xFE9F, 0xFEA3, 0xFEA7, 0xFEA9,\n\t0xFEAB, 0xFEAD, 0xFEAF, 0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, 0xFEC1, 0xFEC5, 0xFECB, 0xFECF, 0x00A6, 0x00AC, 0x00F7, 0x00D7, 0xFEC9,\n\t0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1,\n\t0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, 0x0000\n};\n#endif\n#if FF_CODE_PAGE == 865 || FF_CODE_PAGE == 0\nstatic const WCHAR uc865[] = {\t/*  CP865(Nordic) to Unicode conversion table */\n\t0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,\n\t0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,\n\t0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,\n\t0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 866 || FF_CODE_PAGE == 0\nstatic const WCHAR uc866[] = {\t/*  CP866(Russian) to Unicode conversion table */\n\t0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,\n\t0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,\n\t0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,\n\t0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,\n\t0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,\n\t0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0\n};\n#endif\n#if FF_CODE_PAGE == 869 || FF_CODE_PAGE == 0\nstatic const WCHAR uc869[] = {\t/*  CP869(Greek 2) to Unicode conversion table */\n\t0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389,\n\t0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF,\n\t0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB,\n\t0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039A, 0x039B, 0x039C, 0x039D, 0x2563, 0x2551, 0x2557, 0x255D, 0x039E, 0x039F, 0x2510,\n\t0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0A30, 0x03A1, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x03A3,\n\t0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x2518, 0x250C, 0x2588, 0x2584, 0x03B4, 0x03B5, 0x2580,\n\t0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384,\n\t0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0\n};\n#endif\n\n\n\n\n/*------------------------------------------------------------------------*/\n/* OEM <==> Unicode conversions for static code page configuration        */\n/* SBCS fixed code page                                                   */\n/*------------------------------------------------------------------------*/\n\n#if FF_CODE_PAGE != 0 && FF_CODE_PAGE < 900\nWCHAR ff_uni2oem (\t/* Returns OEM code character, zero on error */\n\tDWORD\tuni,\t/* UTF-16 encoded character to be converted */\n\tWORD\tcp\t\t/* Code page for the conversion */\n)\n{\n\tWCHAR c = 0;\n\tconst WCHAR *p = CVTBL(uc, FF_CODE_PAGE);\n\n\n\tif (uni < 0x80) {\t/* ASCII? */\n\t\tc = (WCHAR)uni;\n\n\t} else {\t\t\t/* Non-ASCII */\n\t\tif (uni < 0x10000 && cp == FF_CODE_PAGE) {\t/* Is it in BMP and valid code page? */\n\t\t\tfor (c = 0; c < 0x80 && uni != p[c]; c++) ;\n\t\t\tc = (c + 0x80) & 0xFF;\n\t\t}\n\t}\n\n\treturn c;\n}\n\nWCHAR ff_oem2uni (\t/* Returns Unicode character, zero on error */\n\tWCHAR\toem,\t/* OEM code to be converted */\n\tWORD\tcp\t\t/* Code page for the conversion */\n)\n{\n\tWCHAR c = 0;\n\tconst WCHAR *p = CVTBL(uc, FF_CODE_PAGE);\n\n\n\tif (oem < 0x80) {\t/* ASCII? */\n\t\tc = oem;\n\n\t} else {\t\t\t/* Extended char */\n\t\tif (cp == FF_CODE_PAGE) {\t/* Is it a valid code page? */\n\t\t\tif (oem < 0x100) c = p[oem - 0x80];\n\t\t}\n\t}\n\n\treturn c;\n}\n\n#endif\n\n\n\n/*------------------------------------------------------------------------*/\n/* OEM <==> Unicode conversions for static code page configuration        */\n/* DBCS fixed code page                                                   */\n/*------------------------------------------------------------------------*/\n\n#if FF_CODE_PAGE >= 900\nWCHAR ff_uni2oem (\t/* Returns OEM code character, zero on error */\n\tDWORD\tuni,\t/* UTF-16 encoded character to be converted */\n\tWORD\tcp\t\t/* Code page for the conversion */\n)\n{\n\tconst WCHAR *p;\n\tWCHAR c = 0, uc;\n\tUINT i = 0, n, li, hi;\n\n\n\tif (uni < 0x80) {\t/* ASCII? */\n\t\tc = (WCHAR)uni;\n\n\t} else {\t\t\t/* Non-ASCII */\n\t\tif (uni < 0x10000 && cp == FF_CODE_PAGE) {\t/* Is it in BMP and valid code page? */\n\t\t\tuc = (WCHAR)uni;\n\t\t\tp = CVTBL(uni2oem, FF_CODE_PAGE);\n\t\t\thi = sizeof CVTBL(uni2oem, FF_CODE_PAGE) / 4 - 1;\n\t\t\tli = 0;\n\t\t\tfor (n = 16; n; n--) {\n\t\t\t\ti = li + (hi - li) / 2;\n\t\t\t\tif (uc == p[i * 2]) break;\n\t\t\t\tif (uc > p[i * 2]) {\n\t\t\t\t\tli = i;\n\t\t\t\t} else {\n\t\t\t\t\thi = i;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (n != 0) c = p[i * 2 + 1];\n\t\t}\n\t}\n\n\treturn c;\n}\n\n\nWCHAR ff_oem2uni (\t/* Returns Unicode character, zero on error */\n\tWCHAR\toem,\t/* OEM code to be converted */\n\tWORD\tcp\t\t/* Code page for the conversion */\n)\n{\n\tconst WCHAR *p;\n\tWCHAR c = 0;\n\tUINT i = 0, n, li, hi;\n\n\n\tif (oem < 0x80) {\t/* ASCII? */\n\t\tc = oem;\n\n\t} else {\t\t\t/* Extended char */\n\t\tif (cp == FF_CODE_PAGE) {\t/* Is it valid code page? */\n\t\t\tp = CVTBL(oem2uni, FF_CODE_PAGE);\n\t\t\thi = sizeof CVTBL(oem2uni, FF_CODE_PAGE) / 4 - 1;\n\t\t\tli = 0;\n\t\t\tfor (n = 16; n; n--) {\n\t\t\t\ti = li + (hi - li) / 2;\n\t\t\t\tif (oem == p[i * 2]) break;\n\t\t\t\tif (oem > p[i * 2]) {\n\t\t\t\t\tli = i;\n\t\t\t\t} else {\n\t\t\t\t\thi = i;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (n != 0) c = p[i * 2 + 1];\n\t\t}\n\t}\n\n\treturn c;\n}\n#endif\n\n\n\n/*------------------------------------------------------------------------*/\n/* OEM <==> Unicode conversions for dynamic code page configuration       */\n/*------------------------------------------------------------------------*/\n\n#if FF_CODE_PAGE == 0\n\nstatic const WORD cp_code[]          = {  437,   720,   737,   771,   775,   850,   852,   855,   857,   860,   861,   862,   863,   864,   865,   866,   869, 0};\nstatic const WCHAR* const cp_table[] = {uc437, uc720, uc737, uc771, uc775, uc850, uc852, uc855, uc857, uc860, uc861, uc862, uc863, uc864, uc865, uc866, uc869, 0};\n\n\nWCHAR ff_uni2oem (\t/* Returns OEM code character, zero on error */\n\tDWORD\tuni,\t/* UTF-16 encoded character to be converted */\n\tWORD\tcp\t\t/* Code page for the conversion */\n)\n{\n\tconst WCHAR *p;\n\tWCHAR c = 0, uc;\n\tUINT i, n, li, hi;\n\n\n\tif (uni < 0x80) {\t/* ASCII? */\n\t\tc = (WCHAR)uni;\n\n\t} else {\t\t\t/* Non-ASCII */\n\t\tif (uni < 0x10000) { /* Is it in BMP? */\n\t\t\tuc = (WCHAR)uni;\n\t\t\tp = 0;\n\t\t\tif (cp < 900) {\t/* SBCS */\n\t\t\t\tfor (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ;\t\t/* Get conversion table */\n\t\t\t\tp = cp_table[i];\n\t\t\t\tif (p) {\t/* Is it valid code page ? */\n\t\t\t\t\tfor (c = 0; c < 0x80 && uc != p[c]; c++) ;\t/* Find OEM code in the table */\n\t\t\t\t\tc = (c + 0x80) & 0xFF;\n\t\t\t\t}\n\t\t\t} else {\t/* DBCS */\n\t\t\t\tswitch (cp) {\t/* Get conversion table */\n\t\t\t\tcase 932 : p = uni2oem932; hi = sizeof uni2oem932 / 4 - 1; break;\n\t\t\t\tcase 936 : p = uni2oem936; hi = sizeof uni2oem936 / 4 - 1; break;\n\t\t\t\tcase 949 : p = uni2oem949; hi = sizeof uni2oem949 / 4 - 1; break;\n\t\t\t\tcase 950 : p = uni2oem950; hi = sizeof uni2oem950 / 4 - 1; break;\n\t\t\t\t}\n\t\t\t\tif (p) {\t/* Is it valid code page? */\n\t\t\t\t\tli = 0;\n\t\t\t\t\tfor (n = 16; n; n--) {\t/* Find OEM code */\n\t\t\t\t\t\ti = li + (hi - li) / 2;\n\t\t\t\t\t\tif (uc == p[i * 2]) break;\n\t\t\t\t\t\tif (uc > p[i * 2]) {\n\t\t\t\t\t\t\tli = i;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\thi = i;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (n != 0) c = p[i * 2 + 1];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn c;\n}\n\n\nWCHAR ff_oem2uni (\t/* Returns Unicode character, zero on error */\n\tWCHAR\toem,\t/* OEM code to be converted (DBC if >=0x100) */\n\tWORD\tcp\t\t/* Code page for the conversion */\n)\n{\n\tconst WCHAR *p;\n\tWCHAR c = 0;\n\tUINT i, n, li, hi;\n\n\n\tif (oem < 0x80) {\t/* ASCII? */\n\t\tc = oem;\n\n\t} else {\t\t\t/* Extended char */\n\t\tp = 0;\n\t\tif (cp < 900) {\t/* SBCS */\n\t\t\tfor (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ;\t\t/* Get table */\n\t\t\tp = cp_table[i];\n\t\t\tif (p) {\t/* Is it a valid CP ? */\n\t\t\t\tif (oem < 0x100) c = p[oem - 0x80];\n\t\t\t}\n\t\t} else {\t/* DBCS */\n\t\t\tswitch (cp) {\n\t\t\tcase 932 : p = oem2uni932; hi = sizeof oem2uni932 / 4 - 1; break;\n\t\t\tcase 936 : p = oem2uni936; hi = sizeof oem2uni936 / 4 - 1; break;\n\t\t\tcase 949 : p = oem2uni949; hi = sizeof oem2uni949 / 4 - 1; break;\n\t\t\tcase 950 : p = oem2uni950; hi = sizeof oem2uni950 / 4 - 1; break;\n\t\t\t}\n\t\t\tif (p) {\n\t\t\t\tli = 0;\n\t\t\t\tfor (n = 16; n; n--) {\n\t\t\t\t\ti = li + (hi - li) / 2;\n\t\t\t\t\tif (oem == p[i * 2]) break;\n\t\t\t\t\tif (oem > p[i * 2]) {\n\t\t\t\t\t\tli = i;\n\t\t\t\t\t} else {\n\t\t\t\t\t\thi = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (n != 0) c = p[i * 2 + 1];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn c;\n}\n#endif\n\n\n\n/*------------------------------------------------------------------------*/\n/* Unicode up-case conversion                                             */\n/*------------------------------------------------------------------------*/\n\nDWORD ff_wtoupper (\t/* Returns up-converted code point */\n\tDWORD uni\t\t/* Unicode code point to be up-converted */\n)\n{\n\tconst WORD *p;\n\tWORD uc, bc, nc, cmd;\n\tstatic const WORD cvt1[] = {\t/* Compressed up conversion table for U+0000 - U+0FFF */\n\t\t/* Basic Latin */\n\t\t0x0061,0x031A,\n\t\t/* Latin-1 Supplement */\n\t\t0x00E0,0x0317,\n\t\t0x00F8,0x0307,\n\t\t0x00FF,0x0001,0x0178,\n\t\t/* Latin Extended-A */\n\t\t0x0100,0x0130,\n\t\t0x0132,0x0106,\n\t\t0x0139,0x0110,\n\t\t0x014A,0x012E,\n\t\t0x0179,0x0106,\n\t\t/* Latin Extended-B */\n\t\t0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA,\n\t\t0x01CD,0x0110,\n\t\t0x01DD,0x0001,0x018E,\n\t\t0x01DE,0x0112,\n\t\t0x01F3,0x0003,0x01F1,0x01F4,0x01F4,\n\t\t0x01F8,0x0128,\n\t\t0x0222,0x0112,\n\t\t0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241,\n\t\t0x0246,0x010A,\n\t\t/* IPA Extensions */\n\t\t0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7,\n\t\t/* Greek, Coptic */\n\t\t0x037B,0x0003,0x03FD,0x03FE,0x03FF,\n\t\t0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A,\n\t\t0x03B1,0x0311,\n\t\t0x03C2,0x0002,0x03A3,0x03A3,\n\t\t0x03C4,0x0308,\n\t\t0x03CC,0x0003,0x038C,0x038E,0x038F,\n\t\t0x03D8,0x0118,\n\t\t0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA,\n\t\t/* Cyrillic */\n\t\t0x0430,0x0320,\n\t\t0x0450,0x0710,\n\t\t0x0460,0x0122,\n\t\t0x048A,0x0136,\n\t\t0x04C1,0x010E,\n\t\t0x04CF,0x0001,0x04C0,\n\t\t0x04D0,0x0144,\n\t\t/* Armenian */\n\t\t0x0561,0x0426,\n\n\t\t0x0000\t/* EOT */\n\t};\n\tstatic const WORD cvt2[] = {\t/* Compressed up conversion table for U+1000 - U+FFFF */\n\t\t/* Phonetic Extensions */\n\t\t0x1D7D,0x0001,0x2C63,\n\t\t/* Latin Extended Additional */\n\t\t0x1E00,0x0196,\n\t\t0x1EA0,0x015A,\n\t\t/* Greek Extended */\n\t\t0x1F00,0x0608,\n\t\t0x1F10,0x0606,\n\t\t0x1F20,0x0608,\n\t\t0x1F30,0x0608,\n\t\t0x1F40,0x0606,\n\t\t0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F,\n\t\t0x1F60,0x0608,\n\t\t0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB,\n\t\t0x1F80,0x0608,\n\t\t0x1F90,0x0608,\n\t\t0x1FA0,0x0608,\n\t\t0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,\n\t\t0x1FCC,0x0001,0x1FC3,\n\t\t0x1FD0,0x0602,\n\t\t0x1FE0,0x0602,\n\t\t0x1FE5,0x0001,0x1FEC,\n\t\t0x1FF3,0x0001,0x1FFC,\n\t\t/* Letterlike Symbols */\n\t\t0x214E,0x0001,0x2132,\n\t\t/* Number forms */\n\t\t0x2170,0x0210,\n\t\t0x2184,0x0001,0x2183,\n\t\t/* Enclosed Alphanumerics */\n\t\t0x24D0,0x051A,\n\t\t0x2C30,0x042F,\n\t\t/* Latin Extended-C */\n\t\t0x2C60,0x0102,\n\t\t0x2C67,0x0106, 0x2C75,0x0102,\n\t\t/* Coptic */\n\t\t0x2C80,0x0164,\n\t\t/* Georgian Supplement */\n\t\t0x2D00,0x0826,\n\t\t/* Full-width */\n\t\t0xFF41,0x031A,\n\n\t\t0x0000\t/* EOT */\n\t};\n\n\n\tif (uni < 0x10000) {\t/* Is it in BMP? */\n\t\tuc = (WORD)uni;\n\t\tp = uc < 0x1000 ? cvt1 : cvt2;\n\t\tfor (;;) {\n\t\t\tbc = *p++;\t\t\t\t\t\t\t\t/* Get the block base */\n\t\t\tif (bc == 0 || uc < bc) break;\t\t\t/* Not matched? */\n\t\t\tnc = *p++; cmd = nc >> 8; nc &= 0xFF;\t/* Get processing command and block size */\n\t\t\tif (uc < bc + nc) {\t/* In the block? */\n\t\t\t\tswitch (cmd) {\n\t\t\t\tcase 0:\tuc = p[uc - bc]; break;\t\t/* Table conversion */\n\t\t\t\tcase 1:\tuc -= (uc - bc) & 1; break;\t/* Case pairs */\n\t\t\t\tcase 2: uc -= 16; break;\t\t\t/* Shift -16 */\n\t\t\t\tcase 3:\tuc -= 32; break;\t\t\t/* Shift -32 */\n\t\t\t\tcase 4:\tuc -= 48; break;\t\t\t/* Shift -48 */\n\t\t\t\tcase 5:\tuc -= 26; break;\t\t\t/* Shift -26 */\n\t\t\t\tcase 6:\tuc += 8; break;\t\t\t\t/* Shift +8 */\n\t\t\t\tcase 7: uc -= 80; break;\t\t\t/* Shift -80 */\n\t\t\t\tcase 8:\tuc -= 0x1C60; break;\t\t/* Shift -0x1C60 */\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (cmd == 0) p += nc;\t/* Skip table if needed */\n\t\t}\n\t\tuni = uc;\n\t}\n\n\treturn uni;\n}\n\n#pragma GCC pop_options\n\n\n#endif /* #if FF_USE_LFN */\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_core/lv_core.mk",
    "content": "CSRCS += lv_group.c\nCSRCS += lv_indev.c\nCSRCS += lv_disp.c\nCSRCS += lv_obj.c\nCSRCS += lv_refr.c\nCSRCS += lv_style.c\n\nDEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_core\nVPATH += :$(LVGL_DIR)/lvgl/src/lv_core\n\nCFLAGS += \"-I$(LVGL_DIR)/lvgl/src/lv_core\"\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_core/lv_disp.c",
    "content": "/**\n * @file lv_disp.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_core/lv_disp.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Return with a pointer to the active screen\n * @param disp pointer to display which active screen should be get. (NULL to use the default\n * screen)\n * @return pointer to the active screen object (loaded by 'lv_scr_load()')\n */\nlv_obj_t * lv_disp_get_scr_act(lv_disp_t * disp)\n{\n    if(!disp) disp = lv_disp_get_default();\n    if(!disp) {\n        LV_LOG_WARN(\"lv_scr_act: no display registered to get its top layer\");\n        return NULL;\n    }\n\n    return disp->act_scr;\n}\n\n/**\n * Make a screen active\n * @param scr pointer to a screen\n */\nvoid lv_disp_load_scr(lv_obj_t * scr)\n{\n    lv_disp_t * d = lv_obj_get_disp(scr);\n\n    d->act_scr = scr;\n\n    lv_obj_invalidate(scr);\n}\n\n/**\n * Return with the top layer. (Same on every screen and it is above the normal screen layer)\n * @param disp pointer to display which top layer should be get. (NULL to use the default screen)\n * @return pointer to the top layer object  (transparent screen sized lv_obj)\n */\nlv_obj_t * lv_disp_get_layer_top(lv_disp_t * disp)\n{\n    if(!disp) disp = lv_disp_get_default();\n    if(!disp) {\n        LV_LOG_WARN(\"lv_layer_top: no display registered to get its top layer\");\n        return NULL;\n    }\n\n    return disp->top_layer;\n}\n\n/**\n * Return with the sys. layer. (Same on every screen and it is above the normal screen and the top\n * layer)\n * @param disp pointer to display which sys. layer  should be get. (NULL to use the default screen)\n * @return pointer to the sys layer object  (transparent screen sized lv_obj)\n */\nlv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp)\n{\n    if(!disp) disp = lv_disp_get_default();\n    if(!disp) {\n        LV_LOG_WARN(\"lv_layer_sys: no display registered to get its top layer\");\n        return NULL;\n    }\n\n    return disp->sys_layer;\n}\n\n/**\n * Assign a screen to a display.\n * @param disp pointer to a display where to assign the screen\n * @param scr pointer to a screen object to assign\n */\nvoid lv_disp_assign_screen(lv_disp_t * disp, lv_obj_t * scr)\n{\n    if(lv_obj_get_parent(scr) != NULL) {\n        LV_LOG_WARN(\"lv_disp_assign_screen: try to assign a non-screen object\");\n        return;\n    }\n\n    lv_disp_t * old_disp = lv_obj_get_disp(scr);\n\n    if(old_disp == disp) return;\n\n    lv_ll_chg_list(&old_disp->scr_ll, &disp->scr_ll, scr, true);\n}\n\n/**\n * Get a pointer to the screen refresher task to\n * modify its parameters with `lv_task_...` functions.\n * @param disp pointer to a display\n * @return pointer to the display refresher task. (NULL on error)\n */\nlv_task_t * lv_disp_get_refr_task(lv_disp_t * disp)\n{\n    if(!disp) disp = lv_disp_get_default();\n    if(!disp) {\n        LV_LOG_WARN(\"lv_disp_get_refr_task: no display registered\");\n        return NULL;\n    }\n\n    return disp->refr_task;\n}\n\n/**\n * Get elapsed time since last user activity on a display (e.g. click)\n * @param disp pointer to an display (NULL to get the overall smallest inactivity)\n * @return elapsed ticks (milliseconds) since the last activity\n */\nuint32_t lv_disp_get_inactive_time(const lv_disp_t * disp)\n{\n    if(!disp) disp = lv_disp_get_default();\n    if(!disp) {\n        LV_LOG_WARN(\"lv_disp_get_inactive_time: no display registered\");\n        return 0;\n    }\n\n    if(disp) return lv_tick_elaps(disp->last_activity_time);\n\n    lv_disp_t * d;\n    uint32_t t = UINT32_MAX;\n    d          = lv_disp_get_next(NULL);\n    while(d) {\n        t = LV_MATH_MIN(t, lv_tick_elaps(d->last_activity_time));\n        d = lv_disp_get_next(d);\n    }\n\n    return t;\n}\n\n/**\n * Manually trigger an activity on a display\n * @param disp pointer to an display (NULL to use the default display)\n */\nvoid lv_disp_trig_activity(lv_disp_t * disp)\n{\n    if(!disp) disp = lv_disp_get_default();\n    if(!disp) {\n        LV_LOG_WARN(\"lv_disp_trig_activity: no display registered\");\n        return;\n    }\n\n    disp->last_activity_time = lv_tick_get();\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_core/lv_group.c",
    "content": "/**\n * @file lv_group.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_core/lv_group.h\"\n#if LV_USE_GROUP != 0\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include <stddef.h>\n#include \"libs/lvgl/lv_misc/lv_gc.h\"\n\n#if defined(LV_GC_INCLUDE)\n#include LV_GC_INCLUDE\n#endif /* LV_ENABLE_GC */\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic void style_mod_def(lv_group_t * group, lv_style_t * style);\nstatic void style_mod_edit_def(lv_group_t * group, lv_style_t * style);\nstatic void refresh_theme(lv_group_t * g, lv_theme_t * th);\nstatic void focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *),\n                            void * (*move)(const lv_ll_t *, const void *));\nstatic void lv_group_refocus(lv_group_t * g);\nstatic void obj_to_foreground(lv_obj_t * obj);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Init. the group module\n */\nvoid lv_group_init(void)\n{\n    lv_ll_init(&LV_GC_ROOT(_lv_group_ll), sizeof(lv_group_t));\n}\n\n/**\n * Create a new object group\n * @return pointer to the new object group\n */\nlv_group_t * lv_group_create(void)\n{\n    lv_group_t * group = lv_ll_ins_head(&LV_GC_ROOT(_lv_group_ll));\n    lv_mem_assert(group);\n    if(group == NULL) return NULL;\n    lv_ll_init(&group->obj_ll, sizeof(lv_obj_t *));\n\n    group->obj_focus      = NULL;\n    group->frozen         = 0;\n    group->focus_cb       = NULL;\n    group->click_focus    = 1;\n    group->editing        = 0;\n    group->refocus_policy = LV_GROUP_REFOCUS_POLICY_PREV;\n    group->wrap           = 1;\n\n#if LV_USE_USER_DATA\n    memset(&group->user_data, 0, sizeof(lv_group_user_data_t));\n#endif\n\n    /*Initialize style modification callbacks from current theme*/\n    refresh_theme(group, lv_theme_get_current());\n\n    return group;\n}\n\n/**\n * Delete a group object\n * @param group pointer to a group\n */\nvoid lv_group_del(lv_group_t * group)\n{\n    /*Defocus the the currently focused object*/\n    if(group->obj_focus != NULL) {\n        (*group->obj_focus)->signal_cb(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);\n        lv_obj_invalidate(*group->obj_focus);\n    }\n\n    /*Remove the objects from the group*/\n    lv_obj_t ** obj;\n    LV_LL_READ(group->obj_ll, obj)\n    {\n        (*obj)->group_p = NULL;\n    }\n\n    lv_ll_clear(&(group->obj_ll));\n    lv_ll_rem(&LV_GC_ROOT(_lv_group_ll), group);\n    lv_mem_free(group);\n}\n\n/**\n * Add an object to a group\n * @param group pointer to a group\n * @param obj pointer to an object to add\n */\nvoid lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)\n{\n    if(group == NULL) return;\n\n    /*Do not add the object twice*/\n    lv_obj_t ** obj_i;\n    LV_LL_READ(group->obj_ll, obj_i)\n    {\n        if((*obj_i) == obj) {\n            LV_LOG_INFO(\"lv_group_add_obj: the object is already added to this group\");\n            return;\n        }\n    }\n\n    /*If the object is already in a group and focused then defocus it*/\n    if(obj->group_p) {\n        if(lv_obj_is_focused(obj)) {\n            lv_group_refocus(obj->group_p);\n\n            LV_LOG_INFO(\"lv_group_add_obj: assign object to an other group\");\n        }\n    }\n\n    obj->group_p     = group;\n    lv_obj_t ** next = lv_ll_ins_tail(&group->obj_ll);\n    lv_mem_assert(next);\n    if(next == NULL) return;\n    *next = obj;\n\n    /* If the head and the tail is equal then there is only one object in the linked list.\n     * In this case automatically activate it*/\n    if(lv_ll_get_head(&group->obj_ll) == next) {\n        lv_group_refocus(group);\n    }\n}\n\n/**\n * Remove an object from its group\n * @param obj pointer to an object to remove\n */\nvoid lv_group_remove_obj(lv_obj_t * obj)\n{\n    lv_group_t * g = obj->group_p;\n    if(g == NULL) return;\n    if(g->obj_focus == NULL) return; /*Just to be sure (Not possible if there is at least one object in the group)*/\n\n    /*Focus on the next object*/\n    if(*g->obj_focus == obj) {\n        /*If this is the only object in the group then focus to nothing.*/\n        if(lv_ll_get_head(&g->obj_ll) == g->obj_focus && lv_ll_get_tail(&g->obj_ll) == g->obj_focus) {\n            (*g->obj_focus)->signal_cb(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL);\n        }\n        /*If there more objects in the group then focus to the next/prev object*/\n        else {\n            lv_group_refocus(g);\n        }\n    }\n\n    /* If the focuses object is still the same then it was the only object in the group but it will\n     * be deleted. Set the `obj_focus` to NULL to get back to the initial state of the group with\n     * zero objects*/\n    if(*g->obj_focus == obj) {\n        g->obj_focus = NULL;\n    }\n\n    /*Search the object and remove it from its group */\n    lv_obj_t ** i;\n    LV_LL_READ(g->obj_ll, i)\n    {\n        if(*i == obj) {\n            lv_ll_rem(&g->obj_ll, i);\n            lv_mem_free(i);\n            obj->group_p = NULL;\n            break;\n        }\n    }\n}\n\n/**\n * Remove all objects from a group\n * @param group pointer to a group\n */\nvoid lv_group_remove_all_objs(lv_group_t * group)\n{\n    /*Defocus the the currently focused object*/\n    if(group->obj_focus != NULL) {\n        (*group->obj_focus)->signal_cb(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);\n        lv_obj_invalidate(*group->obj_focus);\n        group->obj_focus = NULL;\n    }\n\n    /*Remove the objects from the group*/\n    lv_obj_t ** obj;\n    LV_LL_READ(group->obj_ll, obj)\n    {\n        (*obj)->group_p = NULL;\n    }\n\n    lv_ll_clear(&(group->obj_ll));\n}\n\n/**\n * Focus on an object (defocus the current)\n * @param obj pointer to an object to focus on\n */\nvoid lv_group_focus_obj(lv_obj_t * obj)\n{\n    if(obj == NULL) return;\n    lv_group_t * g = obj->group_p;\n    if(g == NULL) return;\n\n    if(g->frozen != 0) return;\n\n    /*On defocus edit mode must be leaved*/\n    lv_group_set_editing(g, false);\n\n    lv_obj_t ** i;\n    LV_LL_READ(g->obj_ll, i)\n    {\n        if(*i == obj) {\n            if(g->obj_focus != NULL) {\n                (*g->obj_focus)->signal_cb(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL);\n                lv_res_t res = lv_event_send(*g->obj_focus, LV_EVENT_DEFOCUSED, NULL);\n                if(res != LV_RES_OK) return;\n                lv_obj_invalidate(*g->obj_focus);\n            }\n\n            g->obj_focus = i;\n\n            if(g->obj_focus != NULL) {\n                (*g->obj_focus)->signal_cb(*g->obj_focus, LV_SIGNAL_FOCUS, NULL);\n                if(g->focus_cb) g->focus_cb(g);\n                lv_res_t res = lv_event_send(*g->obj_focus, LV_EVENT_FOCUSED, NULL);\n                if(res != LV_RES_OK) return;\n                lv_obj_invalidate(*g->obj_focus);\n\n                /*If the object or its parent has `top == true` bring it to the foregorund*/\n                obj_to_foreground(*g->obj_focus);\n            }\n            break;\n        }\n    }\n}\n\n/**\n * Focus the next object in a group (defocus the current)\n * @param group pointer to a group\n */\nvoid lv_group_focus_next(lv_group_t * group)\n{\n    focus_next_core(group, lv_ll_get_head, lv_ll_get_next);\n}\n\n/**\n * Focus the previous object in a group (defocus the current)\n * @param group pointer to a group\n */\nvoid lv_group_focus_prev(lv_group_t * group)\n{\n    focus_next_core(group, lv_ll_get_tail, lv_ll_get_prev);\n}\n\n/**\n * Do not let to change the focus from the current object\n * @param group pointer to a group\n * @param en true: freeze, false: release freezing (normal mode)\n */\nvoid lv_group_focus_freeze(lv_group_t * group, bool en)\n{\n    if(en == false)\n        group->frozen = 0;\n    else\n        group->frozen = 1;\n}\n\n/**\n * Send a control character to the focuses object of a group\n * @param group pointer to a group\n * @param c a character (use LV_KEY_.. to navigate)\n * @return result of focused object in group.\n */\nlv_res_t lv_group_send_data(lv_group_t * group, uint32_t c)\n{\n    lv_obj_t * act = lv_group_get_focused(group);\n    if(act == NULL) return LV_RES_OK;\n\n    lv_res_t res;\n\n    res = act->signal_cb(act, LV_SIGNAL_CONTROL, &c);\n    if(res != LV_RES_OK) return res;\n\n    res = lv_event_send(act, LV_EVENT_KEY, &c);\n    if(res != LV_RES_OK) return res;\n\n    return res;\n}\n\n/**\n * Set a function for a group which will modify the object's style if it is in focus\n * @param group pointer to a group\n * @param style_mod_cb the style modifier function pointer\n */\nvoid lv_group_set_style_mod_cb(lv_group_t * group, lv_group_style_mod_cb_t style_mod_cb)\n{\n    group->style_mod_cb = style_mod_cb;\n    if(group->obj_focus != NULL) lv_obj_invalidate(*group->obj_focus);\n}\n\n/**\n * Set a function for a group which will modify the object's style if it is in focus in edit mode\n * @param group pointer to a group\n * @param style_mod_func the style modifier function pointer\n */\nvoid lv_group_set_style_mod_edit_cb(lv_group_t * group, lv_group_style_mod_cb_t style_mod_edit_cb)\n{\n    group->style_mod_edit_cb = style_mod_edit_cb;\n    if(group->obj_focus != NULL) lv_obj_invalidate(*group->obj_focus);\n}\n\n/**\n * Set a function for a group which will be called when a new object is focused\n * @param group pointer to a group\n * @param focus_cb the call back function or NULL if unused\n */\nvoid lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb)\n{\n    group->focus_cb = focus_cb;\n}\n\n/**\n * Manually set the current mode (edit or navigate).\n * @param group pointer to group\n * @param edit: true: edit mode; false: navigate mode\n */\nvoid lv_group_set_editing(lv_group_t * group, bool edit)\n{\n    uint8_t en_val = edit ? 1 : 0;\n\n    if(en_val == group->editing) return; /*Do not set the same mode again*/\n\n    group->editing     = en_val;\n    lv_obj_t * focused = lv_group_get_focused(group);\n\n    if(focused) {\n        focused->signal_cb(focused, LV_SIGNAL_FOCUS, NULL); /*Focus again to properly leave/open edit/navigate mode*/\n        lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_FOCUSED, NULL);\n        if(res != LV_RES_OK) return;\n    }\n\n    lv_obj_invalidate(focused);\n}\n\n/**\n * Set the `click_focus` attribute. If enabled then the object will be focused then it is clicked.\n * @param group pointer to group\n * @param en: true: enable `click_focus`\n */\nvoid lv_group_set_click_focus(lv_group_t * group, bool en)\n{\n    group->click_focus = en ? 1 : 0;\n}\n\nvoid lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t policy)\n{\n    group->refocus_policy = policy & 0x01;\n}\n\n/**\n * Set whether focus next/prev will allow wrapping from first->last or last->first.\n * @param group pointer to group\n * @param en: true: enable `wrap`\n */\nvoid lv_group_set_wrap(lv_group_t * group, bool en)\n{\n    group->wrap = en ? 1 : 0;\n}\n\n/**\n * Modify a style with the set 'style_mod' function. The input style remains unchanged.\n * @param group pointer to group\n * @param style pointer to a style to modify\n * @return a copy of the input style but modified with the 'style_mod' function\n */\nlv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style)\n{\n    /*Load the current style. It will be modified by the callback*/\n    lv_style_copy(&group->style_tmp, style);\n\n    if(group->editing) {\n        if(group->style_mod_edit_cb) group->style_mod_edit_cb(group, &group->style_tmp);\n    } else {\n        if(group->style_mod_cb) group->style_mod_cb(group, &group->style_tmp);\n    }\n    return &group->style_tmp;\n}\n\n/**\n * Get the focused object or NULL if there isn't one\n * @param group pointer to a group\n * @return pointer to the focused object\n */\nlv_obj_t * lv_group_get_focused(const lv_group_t * group)\n{\n    if(!group) return NULL;\n    if(group->obj_focus == NULL) return NULL;\n\n    return *group->obj_focus;\n}\n\n#if LV_USE_USER_DATA\n/**\n * Get a pointer to the group's user data\n * @param group pointer to an group\n * @return pointer to the user data\n */\nlv_group_user_data_t * lv_group_get_user_data(lv_group_t * group)\n{\n    return &group->user_data;\n}\n#endif\n\n/**\n * Get a the style modifier function of a group\n * @param group pointer to a group\n * @return pointer to the style modifier function\n */\nlv_group_style_mod_cb_t lv_group_get_style_mod_cb(const lv_group_t * group)\n{\n    if(!group) return false;\n    return group->style_mod_cb;\n}\n\n/**\n * Get a the style modifier function of a group in edit mode\n * @param group pointer to a group\n * @return pointer to the style modifier function\n */\nlv_group_style_mod_cb_t lv_group_get_style_mod_edit_cb(const lv_group_t * group)\n{\n    if(!group) return false;\n    return group->style_mod_edit_cb;\n}\n\n/**\n * Get the focus callback function of a group\n * @param group pointer to a group\n * @return the call back function or NULL if not set\n */\nlv_group_focus_cb_t lv_group_get_focus_cb(const lv_group_t * group)\n{\n    if(!group) return false;\n    return group->focus_cb;\n}\n\n/**\n * Get the current mode (edit or navigate).\n * @param group pointer to group\n * @return true: edit mode; false: navigate mode\n */\nbool lv_group_get_editing(const lv_group_t * group)\n{\n    if(!group) return false;\n    return group->editing ? true : false;\n}\n\n/**\n * Get the `click_focus` attribute.\n * @param group pointer to group\n * @return true: `click_focus` is enabled; false: disabled\n */\nbool lv_group_get_click_focus(const lv_group_t * group)\n{\n    if(!group) return false;\n    return group->click_focus ? true : false;\n}\n\n/**\n * Get whether focus next/prev will allow wrapping from first->last or last->first object.\n * @param group pointer to group\n * @param en: true: wrapping enabled; false: wrapping disabled\n */\nbool lv_group_get_wrap(lv_group_t * group)\n{\n    if(!group) return false;\n    return group->wrap ? true : false;\n}\n\n/**\n * Notify the group that current theme changed and style modification callbacks need to be\n * refreshed.\n * @param group pointer to group. If NULL then all groups are notified.\n */\nvoid lv_group_report_style_mod(lv_group_t * group)\n{\n    lv_theme_t * th = lv_theme_get_current();\n\n    if(group != NULL) {\n        refresh_theme(group, th);\n        return;\n    }\n\n    lv_group_t * i;\n    LV_LL_READ(LV_GC_ROOT(_lv_group_ll), i)\n    {\n        refresh_theme(i, th);\n    }\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\nstatic void lv_group_refocus(lv_group_t * g)\n{\n    /*Refocus must temporarily allow wrapping to work correctly*/\n    uint8_t temp_wrap = g->wrap;\n    g->wrap           = 1;\n\n    if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_NEXT)\n        lv_group_focus_next(g);\n    else if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_PREV)\n        lv_group_focus_prev(g);\n    /*Restore wrap property*/\n    g->wrap = temp_wrap;\n}\n\n/**\n * Default style modifier function\n * @param group pointer to the caller group\n * @param style pointer to a style to modify. (Typically group.style_tmp) It will be OVERWRITTEN.\n */\nstatic void style_mod_def(lv_group_t * group, lv_style_t * style)\n{\n    (void)group; /*Unused*/\n#if LV_COLOR_DEPTH != 1\n\n    /*Make the style to be a little bit orange*/\n    style->body.border.opa   = LV_OPA_COVER;\n    style->body.border.color = LV_COLOR_ORANGE;\n\n    /*If not transparent or has border then emphasis the border*/\n    if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20;\n\n    style->body.main_color   = lv_color_mix(style->body.main_color, LV_COLOR_ORANGE, LV_OPA_70);\n    style->body.grad_color   = lv_color_mix(style->body.grad_color, LV_COLOR_ORANGE, LV_OPA_70);\n    style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_ORANGE, LV_OPA_60);\n\n    style->text.color = lv_color_mix(style->text.color, LV_COLOR_ORANGE, LV_OPA_70);\n\n    /*Add some recolor to the images*/\n    if(style->image.intense < LV_OPA_MIN) {\n        style->image.color   = LV_COLOR_ORANGE;\n        style->image.intense = LV_OPA_40;\n    }\n#else\n    style->body.border.opa   = LV_OPA_COVER;\n    style->body.border.color = LV_COLOR_BLACK;\n    style->body.border.width = 2;\n\n#endif\n}\n\n/**\n * Default style modifier function\n * @param group pointer to the caller group\n * @param style pointer to a style to modify. (Typically group.style_tmp) It will be OVERWRITTEN.\n */\nstatic void style_mod_edit_def(lv_group_t * group, lv_style_t * style)\n{\n    (void)group; /*Unused*/\n#if LV_COLOR_DEPTH != 1\n\n    /*Make the style to be a little bit orange*/\n    style->body.border.opa   = LV_OPA_COVER;\n    style->body.border.color = LV_COLOR_GREEN;\n\n    /*If not empty or has border then emphasis the border*/\n    if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20;\n\n    style->body.main_color   = lv_color_mix(style->body.main_color, LV_COLOR_GREEN, LV_OPA_70);\n    style->body.grad_color   = lv_color_mix(style->body.grad_color, LV_COLOR_GREEN, LV_OPA_70);\n    style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_GREEN, LV_OPA_60);\n\n    style->text.color = lv_color_mix(style->text.color, LV_COLOR_GREEN, LV_OPA_70);\n\n    /*Add some recolor to the images*/\n    if(style->image.intense < LV_OPA_MIN) {\n        style->image.color   = LV_COLOR_GREEN;\n        style->image.intense = LV_OPA_40;\n    }\n\n#else\n    style->body.border.opa   = LV_OPA_COVER;\n    style->body.border.color = LV_COLOR_BLACK;\n    style->body.border.width = 3;\n\n#endif\n}\n\nstatic void refresh_theme(lv_group_t * g, lv_theme_t * th)\n{\n    g->style_mod_cb      = style_mod_def;\n    g->style_mod_edit_cb = style_mod_edit_def;\n    if(th) {\n        if(th->group.style_mod_xcb) g->style_mod_cb = th->group.style_mod_xcb;\n        if(th->group.style_mod_edit_xcb) g->style_mod_edit_cb = th->group.style_mod_edit_xcb;\n    }\n}\n\nstatic void focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *),\n                            void * (*move)(const lv_ll_t *, const void *))\n{\n    if(group->frozen) return;\n\n    lv_obj_t ** obj_next     = group->obj_focus;\n    lv_obj_t ** obj_sentinel = NULL;\n    bool can_move            = true;\n    bool can_begin           = true;\n\n    for(;;) {\n        if(obj_next == NULL) {\n            if(group->wrap || obj_sentinel == NULL) {\n                if(!can_begin) return;\n                obj_next  = begin(&group->obj_ll);\n                can_move  = false;\n                can_begin = false;\n            } else {\n                /*Currently focused object is the last/first in the group, keep it that way*/\n                return;\n            }\n        }\n\n        if(obj_sentinel == NULL) {\n            obj_sentinel = obj_next;\n            if(obj_sentinel == NULL) return; /*Group is empty*/\n        }\n\n        if(can_move) {\n            obj_next = move(&group->obj_ll, obj_next);\n\n            /*Give up if we walked the entire list and haven't found another visible object*/\n            if(obj_next == obj_sentinel) return;\n        }\n\n        can_move = true;\n\n        if(obj_next == NULL) continue;\n\n        /*Hidden objects don't receive focus*/\n        if(!lv_obj_get_hidden(*obj_next)) break;\n    }\n\n    if(obj_next == group->obj_focus) return; /*There's only one visible object and it's already focused*/\n\n    if(group->obj_focus) {\n        (*group->obj_focus)->signal_cb(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);\n        lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_DEFOCUSED, NULL);\n        if(res != LV_RES_OK) return;\n        lv_obj_invalidate(*group->obj_focus);\n    }\n\n    group->obj_focus = obj_next;\n\n    (*group->obj_focus)->signal_cb(*group->obj_focus, LV_SIGNAL_FOCUS, NULL);\n    lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_FOCUSED, NULL);\n    if(res != LV_RES_OK) return;\n\n    /*If the object or its parent has `top == true` bring it to the foregorund*/\n    obj_to_foreground(*group->obj_focus);\n\n    lv_obj_invalidate(*group->obj_focus);\n\n    if(group->focus_cb) group->focus_cb(group);\n}\n\nstatic void obj_to_foreground(lv_obj_t * obj)\n{\n    /*Search for 'top' attribute*/\n    lv_obj_t * i        = obj;\n    lv_obj_t * last_top = NULL;\n    while(i != NULL) {\n        if(i->top != 0) last_top = i;\n        i = lv_obj_get_parent(i);\n    }\n\n    if(last_top != NULL) {\n        /*Move the last_top object to the foreground*/\n        lv_obj_move_foreground(last_top);\n    }\n}\n\n#endif /*LV_USE_GROUP != 0*/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_core/lv_indev.c",
    "content": "/**\n * @file lv_indev.c\n *\n */\n\n/*********************\n *      INCLUDES\n ********************/\n#include \"libs/lvgl/lv_core/lv_indev.h\"\n#include \"libs/lvgl/lv_core/lv_disp.h\"\n#include \"libs/lvgl/lv_core/lv_obj.h\"\n\n#include \"libs/lvgl/lv_hal/lv_hal_tick.h\"\n#include \"libs/lvgl/lv_core/lv_group.h\"\n#include \"libs/lvgl/lv_core/lv_refr.h\"\n#include \"libs/lvgl/lv_misc/lv_task.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n#if LV_INDEV_DEF_DRAG_THROW <= 0\n#warning \"LV_INDEV_DRAG_THROW must be greater than 0\"\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\nstatic void indev_pointer_proc(lv_indev_t * i, lv_indev_data_t * data);\nstatic void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data);\nstatic void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data);\nstatic void indev_button_proc(lv_indev_t * i, lv_indev_data_t * data);\nstatic void indev_proc_press(lv_indev_proc_t * proc);\nstatic void indev_proc_release(lv_indev_proc_t * proc);\nstatic void indev_proc_reset_query_handler(lv_indev_t * indev);\nstatic lv_obj_t * indev_search_obj(const lv_indev_proc_t * proc, lv_obj_t * obj);\nstatic void indev_drag(lv_indev_proc_t * state);\nstatic void indev_drag_throw(lv_indev_proc_t * proc);\nstatic bool indev_reset_check(lv_indev_proc_t * proc);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_indev_t * indev_act;\nstatic lv_obj_t * indev_obj_act = NULL;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Initialize the display input device subsystem\n */\nvoid lv_indev_init(void)\n{\n    lv_indev_reset(NULL); /*Reset all input devices*/\n}\n\n/**\n * Called periodically to read the input devices\n * @param param pointer to and input device to read\n */\nvoid lv_indev_read_task(lv_task_t * task)\n{\n    LV_LOG_TRACE(\"indev read task started\");\n\n    lv_indev_data_t data;\n\n    indev_act = task->user_data;\n\n    /*Read and process all indevs*/\n    if(indev_act->driver.disp == NULL) return; /*Not assigned to any displays*/\n\n    /*Handle reset query before processing the point*/\n    indev_proc_reset_query_handler(indev_act);\n\n    if(indev_act->proc.disabled) return;\n    bool more_to_read;\n    do {\n        /*Read the data*/\n        more_to_read = lv_indev_read(indev_act, &data);\n\n        /*The active object might deleted even in the read function*/\n        indev_proc_reset_query_handler(indev_act);\n        indev_obj_act = NULL;\n\n        indev_act->proc.state = data.state;\n\n        /*Save the last activity time*/\n        if(indev_act->proc.state == LV_INDEV_STATE_PR) {\n            indev_act->driver.disp->last_activity_time = lv_tick_get();\n        } else if(indev_act->driver.type == LV_INDEV_TYPE_ENCODER && data.enc_diff) {\n            indev_act->driver.disp->last_activity_time = lv_tick_get();\n        }\n\n        if(indev_act->driver.type == LV_INDEV_TYPE_POINTER) {\n            indev_pointer_proc(indev_act, &data);\n        } else if(indev_act->driver.type == LV_INDEV_TYPE_KEYPAD) {\n            indev_keypad_proc(indev_act, &data);\n        } else if(indev_act->driver.type == LV_INDEV_TYPE_ENCODER) {\n            indev_encoder_proc(indev_act, &data);\n        } else if(indev_act->driver.type == LV_INDEV_TYPE_BUTTON) {\n            indev_button_proc(indev_act, &data);\n        }\n        /*Handle reset query if it happened in during processing*/\n        indev_proc_reset_query_handler(indev_act);\n    } while(more_to_read);\n\n    /*End of indev processing, so no act indev*/\n    indev_act     = NULL;\n    indev_obj_act = NULL;\n\n    LV_LOG_TRACE(\"indev read task finished\");\n}\n\n/**\n * Get the currently processed input device. Can be used in action functions too.\n * @return pointer to the currently processed input device or NULL if no input device processing\n * right now\n */\nlv_indev_t * lv_indev_get_act(void)\n{\n    return indev_act;\n}\n\n/**\n * Get the type of an input device\n * @param indev pointer to an input device\n * @return the type of the input device from `lv_hal_indev_type_t` (`LV_INDEV_TYPE_...`)\n */\nlv_indev_type_t lv_indev_get_type(const lv_indev_t * indev)\n{\n    if(indev == NULL) return LV_INDEV_TYPE_NONE;\n\n    return indev->driver.type;\n}\n/**\n * Reset one or all input devices\n * @param indev pointer to an input device to reset or NULL to reset all of them\n */\nvoid lv_indev_reset(lv_indev_t * indev)\n{\n    if(indev)\n        indev->proc.reset_query = 1;\n    else {\n        lv_indev_t * i = lv_indev_get_next(NULL);\n        while(i) {\n            i->proc.reset_query = 1;\n\n            i = lv_indev_get_next(i);\n        }\n    }\n}\n\n/**\n * Reset the long press state of an input device\n * @param indev pointer to an input device\n */\nvoid lv_indev_reset_long_press(lv_indev_t * indev)\n{\n    indev->proc.long_pr_sent         = 0;\n    indev->proc.longpr_rep_timestamp = lv_tick_get();\n    indev->proc.pr_timestamp         = lv_tick_get();\n}\n\n/**\n * Enable or disable an input devices\n * @param indev pointer to an input device\n * @param en true: enable; false: disable\n */\nvoid lv_indev_enable(lv_indev_t * indev, bool en)\n{\n    if(!indev) return;\n\n    indev->proc.disabled = en ? 1 : 0;\n}\n\n/**\n * Set a cursor for a pointer input device (for LV_INPUT_TYPE_POINTER and LV_INPUT_TYPE_BUTTON)\n * @param indev pointer to an input device\n * @param cur_obj pointer to an object to be used as cursor\n */\nvoid lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj)\n{\n    if(indev->driver.type != LV_INDEV_TYPE_POINTER) return;\n\n    indev->cursor = cur_obj;\n    lv_obj_set_parent(indev->cursor, lv_disp_get_layer_sys(indev->driver.disp));\n    lv_obj_set_pos(indev->cursor, indev->proc.types.pointer.act_point.x, indev->proc.types.pointer.act_point.y);\n}\n\n#if LV_USE_GROUP\n/**\n * Set a destination group for a keypad input device (for LV_INDEV_TYPE_KEYPAD)\n * @param indev pointer to an input device\n * @param group point to a group\n */\nvoid lv_indev_set_group(lv_indev_t * indev, lv_group_t * group)\n{\n    if(indev->driver.type == LV_INDEV_TYPE_KEYPAD || indev->driver.type == LV_INDEV_TYPE_ENCODER) {\n        indev->group = group;\n    }\n}\n#endif\n\n/**\n * Set the an array of points for LV_INDEV_TYPE_BUTTON.\n * These points will be assigned to the buttons to press a specific point on the screen\n * @param indev pointer to an input device\n * @param group point to a group\n */\nvoid lv_indev_set_button_points(lv_indev_t * indev, const lv_point_t * points)\n{\n    if(indev->driver.type == LV_INDEV_TYPE_BUTTON) {\n        indev->btn_points = points;\n    }\n}\n\n/**\n * Get the last point of an input device (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)\n * @param indev pointer to an input device\n * @param point pointer to a point to store the result\n */\nvoid lv_indev_get_point(const lv_indev_t * indev, lv_point_t * point)\n{\n    if(indev->driver.type != LV_INDEV_TYPE_POINTER && indev->driver.type != LV_INDEV_TYPE_BUTTON) {\n        point->x = -1;\n        point->y = -1;\n    } else {\n        point->x = indev->proc.types.pointer.act_point.x;\n        point->y = indev->proc.types.pointer.act_point.y;\n    }\n}\n\n/**\n * Get the last pressed key of an input device (for LV_INDEV_TYPE_KEYPAD)\n * @param indev pointer to an input device\n * @return the last pressed key (0 on error)\n */\nuint32_t lv_indev_get_key(const lv_indev_t * indev)\n{\n    if(indev->driver.type != LV_INDEV_TYPE_KEYPAD)\n        return 0;\n    else\n        return indev->proc.types.keypad.last_key;\n}\n\n/**\n * Check if there is dragging with an input device or not (for LV_INDEV_TYPE_POINTER and\n * LV_INDEV_TYPE_BUTTON)\n * @param indev pointer to an input device\n * @return true: drag is in progress\n */\nbool lv_indev_is_dragging(const lv_indev_t * indev)\n{\n    if(indev == NULL) return false;\n    if(indev->driver.type != LV_INDEV_TYPE_POINTER && indev->driver.type != LV_INDEV_TYPE_BUTTON) return false;\n    return indev->proc.types.pointer.drag_in_prog == 0 ? false : true;\n}\n\n/**\n * Get the types.pointer.vector of dragging of an input device (for LV_INDEV_TYPE_POINTER and\n * LV_INDEV_TYPE_BUTTON)\n * @param indev pointer to an input device\n * @param point pointer to a point to store the types.pointer.vector\n */\nvoid lv_indev_get_vect(const lv_indev_t * indev, lv_point_t * point)\n{\n    if(indev == NULL) {\n        point->x = 0;\n        point->y = 0;\n        return;\n    }\n\n    if(indev->driver.type != LV_INDEV_TYPE_POINTER && indev->driver.type != LV_INDEV_TYPE_BUTTON) {\n        point->x = 0;\n        point->y = 0;\n    } else {\n        point->x = indev->proc.types.pointer.vect.x;\n        point->y = indev->proc.types.pointer.vect.y;\n    }\n}\n\n/**\n * Do nothing until the next release\n * @param indev pointer to an input device\n */\nvoid lv_indev_wait_release(lv_indev_t * indev)\n{\n    indev->proc.wait_until_release = 1;\n}\n\n/**\n * Get a pointer to the indev read task to\n * modify its parameters with `lv_task_...` functions.\n * @param indev pointer to an input device\n * @return pointer to the indev read refresher task. (NULL on error)\n */\nlv_task_t * lv_indev_get_read_task(lv_disp_t * indev)\n{\n    if(!indev) {\n        LV_LOG_WARN(\"lv_indev_get_read_task: indev was NULL\");\n        return NULL;\n    }\n\n    return indev->refr_task;\n}\n\n/**\n * Gets a pointer to the currently active object in the currently processed input device.\n * @return pointer to currently active object or NULL if no active object\n */\nlv_obj_t * lv_indev_get_obj_act(void)\n{\n    return indev_obj_act;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Process a new point from LV_INDEV_TYPE_POINTER input device\n * @param i pointer to an input device\n * @param data pointer to the data read from the input device\n */\nstatic void indev_pointer_proc(lv_indev_t * i, lv_indev_data_t * data)\n{\n    /*Move the cursor if set and moved*/\n    if(i->cursor != NULL &&\n       (i->proc.types.pointer.last_point.x != data->point.x || i->proc.types.pointer.last_point.y != data->point.y)) {\n        lv_obj_set_pos(i->cursor, data->point.x, data->point.y);\n    }\n\n    i->proc.types.pointer.act_point.x = data->point.x;\n    i->proc.types.pointer.act_point.y = data->point.y;\n\n    if(i->proc.state == LV_INDEV_STATE_PR) {\n        indev_proc_press(&i->proc);\n    } else {\n        indev_proc_release(&i->proc);\n    }\n\n    i->proc.types.pointer.last_point.x = i->proc.types.pointer.act_point.x;\n    i->proc.types.pointer.last_point.y = i->proc.types.pointer.act_point.y;\n}\n\n/**\n * Process a new point from LV_INDEV_TYPE_KEYPAD input device\n * @param i pointer to an input device\n * @param data pointer to the data read from the input device\n */\nstatic void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data)\n{\n#if LV_USE_GROUP\n    if(data->state == LV_INDEV_STATE_PR && i->proc.wait_until_release) return;\n\n    if(i->proc.wait_until_release) {\n        i->proc.wait_until_release      = 0;\n        i->proc.pr_timestamp            = 0;\n        i->proc.long_pr_sent            = 0;\n        i->proc.types.keypad.last_state = LV_INDEV_STATE_REL; /*To skip the processing of release*/\n    }\n\n    lv_group_t * g = i->group;\n    if(g == NULL) return;\n\n    indev_obj_act = lv_group_get_focused(g);\n    if(indev_obj_act == NULL) return;\n\n    /*Save the last key to compare it with the current latter on RELEASE*/\n    uint32_t prev_key = i->proc.types.keypad.last_key;\n\n    /* Save the last key.\n     * It must be done here else `lv_indev_get_key` will return the last key in events and signals*/\n    i->proc.types.keypad.last_key = data->key;\n\n    /* Save the previous state so we can detect state changes below and also set the last state now\n     * so if any signal/event handler on the way returns `LV_RES_INV` the last state is remembered\n     * for the next time*/\n    uint32_t prev_state             = i->proc.types.keypad.last_state;\n    i->proc.types.keypad.last_state = data->state;\n\n    /*Key press happened*/\n    if(data->state == LV_INDEV_STATE_PR && prev_state == LV_INDEV_STATE_REL) {\n        i->proc.pr_timestamp = lv_tick_get();\n\n        /*Simulate a press on the object if ENTER was pressed*/\n        if(data->key == LV_KEY_ENTER) {\n            /*Send the ENTER as a normal KEY*/\n            lv_group_send_data(g, LV_KEY_ENTER);\n\n            indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_PRESSED, NULL);\n            if(indev_reset_check(&i->proc)) return;\n            lv_event_send(indev_obj_act, LV_EVENT_PRESSED, NULL);\n            if(indev_reset_check(&i->proc)) return;\n        } else if(data->key == LV_KEY_ESC) {\n            /*Send the ESC as a normal KEY*/\n            lv_group_send_data(g, LV_KEY_ESC);\n\n            lv_event_send(indev_obj_act, LV_EVENT_CANCEL, NULL);\n            if(indev_reset_check(&i->proc)) return;\n        }\n        /*Move the focus on NEXT*/\n        else if(data->key == LV_KEY_NEXT) {\n            lv_group_set_editing(g, false); /*Editing is not used by KEYPAD is be sure it is disabled*/\n            lv_group_focus_next(g);\n            if(indev_reset_check(&i->proc)) return;\n        }\n        /*Move the focus on PREV*/\n        else if(data->key == LV_KEY_PREV) {\n            lv_group_set_editing(g, false); /*Editing is not used by KEYPAD is be sure it is disabled*/\n            lv_group_focus_prev(g);\n            if(indev_reset_check(&i->proc)) return;\n        }\n        /*Just send other keys to the object (e.g. 'A' or `LV_GROUP_KEY_RIGHT`)*/\n        else {\n            lv_group_send_data(g, data->key);\n        }\n    }\n    /*Pressing*/\n    else if(data->state == LV_INDEV_STATE_PR && prev_state == LV_INDEV_STATE_PR) {\n        /*Long press time has elapsed?*/\n        if(i->proc.long_pr_sent == 0 && lv_tick_elaps(i->proc.pr_timestamp) > i->driver.long_press_time) {\n            i->proc.long_pr_sent = 1;\n            if(data->key == LV_KEY_ENTER) {\n                i->proc.longpr_rep_timestamp = lv_tick_get();\n                indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_LONG_PRESS, NULL);\n                if(indev_reset_check(&i->proc)) return;\n                lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED, NULL);\n                if(indev_reset_check(&i->proc)) return;\n            }\n        }\n        /*Long press repeated time has elapsed?*/\n        else if(i->proc.long_pr_sent != 0 &&\n                lv_tick_elaps(i->proc.longpr_rep_timestamp) > i->driver.long_press_rep_time) {\n\n            i->proc.longpr_rep_timestamp = lv_tick_get();\n\n            /*Send LONG_PRESS_REP on ENTER*/\n            if(data->key == LV_KEY_ENTER) {\n                indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_LONG_PRESS_REP, NULL);\n                if(indev_reset_check(&i->proc)) return;\n                lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED_REPEAT, NULL);\n                if(indev_reset_check(&i->proc)) return;\n            }\n            /*Move the focus on NEXT again*/\n            else if(data->key == LV_KEY_NEXT) {\n                lv_group_set_editing(g, false); /*Editing is not used by KEYPAD is be sure it is disabled*/\n                lv_group_focus_next(g);\n                if(indev_reset_check(&i->proc)) return;\n            }\n            /*Move the focus on PREV again*/\n            else if(data->key == LV_KEY_PREV) {\n                lv_group_set_editing(g, false); /*Editing is not used by KEYPAD is be sure it is disabled*/\n                lv_group_focus_prev(g);\n                if(indev_reset_check(&i->proc)) return;\n            }\n            /*Just send other keys again to the object (e.g. 'A' or `LV_GORUP_KEY_RIGHT)*/\n            else {\n                lv_group_send_data(g, data->key);\n                if(indev_reset_check(&i->proc)) return;\n            }\n        }\n    }\n    /*Release happened*/\n    else if(data->state == LV_INDEV_STATE_REL && prev_state == LV_INDEV_STATE_PR) {\n        /*The user might clear the key when it was released. Always release the pressed key*/\n        data->key = prev_key;\n        if(data->key == LV_KEY_ENTER) {\n\n            indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_RELEASED, NULL);\n            if(indev_reset_check(&i->proc)) return;\n\n            if(i->proc.long_pr_sent == 0) {\n                lv_event_send(indev_obj_act, LV_EVENT_SHORT_CLICKED, NULL);\n                if(indev_reset_check(&i->proc)) return;\n            }\n\n            lv_event_send(indev_obj_act, LV_EVENT_CLICKED, NULL);\n            if(indev_reset_check(&i->proc)) return;\n\n            lv_event_send(indev_obj_act, LV_EVENT_RELEASED, NULL);\n            if(indev_reset_check(&i->proc)) return;\n        }\n        i->proc.pr_timestamp = 0;\n        i->proc.long_pr_sent = 0;\n    }\n    indev_obj_act = NULL;\n#else\n    (void)data; /*Unused*/\n    (void)i;    /*Unused*/\n#endif\n}\n\n/**\n * Process a new point from LV_INDEV_TYPE_ENCODER input device\n * @param i pointer to an input device\n * @param data pointer to the data read from the input device\n */\nstatic void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)\n{\n#if LV_USE_GROUP\n\n    if(data->state == LV_INDEV_STATE_PR && i->proc.wait_until_release) return;\n\n    if(i->proc.wait_until_release) {\n        i->proc.wait_until_release      = 0;\n        i->proc.pr_timestamp            = 0;\n        i->proc.long_pr_sent            = 0;\n        i->proc.types.keypad.last_state = LV_INDEV_STATE_REL; /*To skip the processing of release*/\n    }\n\n    /* Save the last keys before anything else.\n     * They need to be already saved if the the function returns for any reason*/\n    lv_indev_state_t last_state     = i->proc.types.keypad.last_state;\n    i->proc.types.keypad.last_state = data->state;\n    i->proc.types.keypad.last_key   = data->key;\n\n    lv_group_t * g = i->group;\n    if(g == NULL) return;\n\n    indev_obj_act = lv_group_get_focused(g);\n    if(indev_obj_act == NULL) return;\n\n    /*Process the steps first. They are valid only with released button*/\n    if(data->state == LV_INDEV_STATE_REL) {\n        /*In edit mode send LEFT/RIGHT keys*/\n        if(lv_group_get_editing(g)) {\n            int32_t s;\n            if(data->enc_diff < 0) {\n                for(s = 0; s < -data->enc_diff; s++) lv_group_send_data(g, LV_KEY_LEFT);\n            } else if(data->enc_diff > 0) {\n                for(s = 0; s < data->enc_diff; s++) lv_group_send_data(g, LV_KEY_RIGHT);\n            }\n        }\n        /*In navigate mode focus on the next/prev objects*/\n        else {\n            int32_t s;\n            if(data->enc_diff < 0) {\n                for(s = 0; s < -data->enc_diff; s++) lv_group_focus_prev(g);\n            } else if(data->enc_diff > 0) {\n                for(s = 0; s < data->enc_diff; s++) lv_group_focus_next(g);\n            }\n        }\n    }\n\n    /*Refresh the focused object. It might change due to lv_group_focus_prev/next*/\n    indev_obj_act = lv_group_get_focused(g);\n    if(indev_obj_act == NULL) return;\n\n    /*Button press happened*/\n    if(data->state == LV_INDEV_STATE_PR && last_state == LV_INDEV_STATE_REL) {\n        bool editable = false;\n        indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_GET_EDITABLE, &editable);\n\n        i->proc.pr_timestamp = lv_tick_get();\n        if(lv_group_get_editing(g) == true || editable == false) {\n            indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_PRESSED, NULL);\n            if(indev_reset_check(&i->proc)) return;\n\n            lv_event_send(indev_obj_act, LV_EVENT_PRESSED, NULL);\n            if(indev_reset_check(&i->proc)) return;\n        }\n    }\n    /*Pressing*/\n    else if(data->state == LV_INDEV_STATE_PR && last_state == LV_INDEV_STATE_PR) {\n        if(i->proc.long_pr_sent == 0 && lv_tick_elaps(i->proc.pr_timestamp) > i->driver.long_press_time) {\n            bool editable = false;\n            indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_GET_EDITABLE, &editable);\n\n            /*On enter long press toggle edit mode.*/\n            if(editable) {\n                /*Don't leave edit mode if there is only one object (nowhere to navigate)*/\n                if(lv_ll_is_empty(&g->obj_ll) == false) {\n                    lv_group_set_editing(g, lv_group_get_editing(g) ? false : true); /*Toggle edit mode on long press*/\n                }\n            }\n            /*If not editable then just send a long press signal*/\n            else {\n                indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_LONG_PRESS, NULL);\n                if(indev_reset_check(&i->proc)) return;\n                lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED, NULL);\n                if(indev_reset_check(&i->proc)) return;\n            }\n            i->proc.long_pr_sent = 1;\n        }\n    }\n    /*Release happened*/\n    else if(data->state == LV_INDEV_STATE_REL && last_state == LV_INDEV_STATE_PR) {\n\n        bool editable = false;\n        indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_GET_EDITABLE, &editable);\n\n        /*The button was released on a non-editable object. Just send enter*/\n        if(editable == false) {\n            indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_RELEASED, NULL);\n            if(indev_reset_check(&i->proc)) return;\n\n            if(i->proc.long_pr_sent == 0) lv_event_send(indev_obj_act, LV_EVENT_SHORT_CLICKED, NULL);\n            if(indev_reset_check(&i->proc)) return;\n\n            lv_event_send(indev_obj_act, LV_EVENT_CLICKED, NULL);\n            if(indev_reset_check(&i->proc)) return;\n\n            lv_event_send(indev_obj_act, LV_EVENT_RELEASED, NULL);\n            if(indev_reset_check(&i->proc)) return;\n        }\n        /*An object is being edited and the button is released. */\n        else if(g->editing) {\n            /*Ignore long pressed enter release because it comes from mode switch*/\n            if(!i->proc.long_pr_sent || lv_ll_is_empty(&g->obj_ll)) {\n                indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_RELEASED, NULL);\n                if(indev_reset_check(&i->proc)) return;\n\n                lv_event_send(indev_obj_act, LV_EVENT_SHORT_CLICKED, NULL);\n                if(indev_reset_check(&i->proc)) return;\n\n                lv_event_send(indev_obj_act, LV_EVENT_CLICKED, NULL);\n                if(indev_reset_check(&i->proc)) return;\n\n                lv_event_send(indev_obj_act, LV_EVENT_RELEASED, NULL);\n                if(indev_reset_check(&i->proc)) return;\n\n                lv_group_send_data(g, LV_KEY_ENTER);\n            }\n        }\n        /*If the focused object is editable and now in navigate mode then on enter switch edit\n           mode*/\n        else if(editable && !g->editing && !i->proc.long_pr_sent) {\n            lv_group_set_editing(g, true); /*Set edit mode*/\n        }\n\n        i->proc.pr_timestamp = 0;\n        i->proc.long_pr_sent = 0;\n    }\n    indev_obj_act = NULL;\n#else\n    (void)data; /*Unused*/\n    (void)i;    /*Unused*/\n#endif\n}\n\n/**\n * Process new points from a input device. indev->state.pressed has to be set\n * @param indev pointer to an input device state\n * @param x x coordinate of the next point\n * @param y y coordinate of the next point\n */\nstatic void indev_button_proc(lv_indev_t * i, lv_indev_data_t * data)\n{\n    i->proc.types.pointer.act_point.x = i->btn_points[data->btn_id].x;\n    i->proc.types.pointer.act_point.y = i->btn_points[data->btn_id].y;\n\n    /*Still the same point is pressed*/\n    if(i->proc.types.pointer.last_point.x == i->proc.types.pointer.act_point.x &&\n       i->proc.types.pointer.last_point.y == i->proc.types.pointer.act_point.y && data->state == LV_INDEV_STATE_PR) {\n        indev_proc_press(&i->proc);\n    } else {\n        /*If a new point comes always make a release*/\n        indev_proc_release(&i->proc);\n    }\n\n    i->proc.types.pointer.last_point.x = i->proc.types.pointer.act_point.x;\n    i->proc.types.pointer.last_point.y = i->proc.types.pointer.act_point.y;\n}\n\n/**\n * Process the pressed state of LV_INDEV_TYPE_POINER input devices\n * @param indev pointer to an input device 'proc'\n * @return LV_RES_OK: no indev reset required; LV_RES_INV: indev reset is required\n */\nstatic void indev_proc_press(lv_indev_proc_t * proc)\n{\n    indev_obj_act = proc->types.pointer.act_obj;\n\n    if(proc->wait_until_release != 0) return;\n\n    lv_disp_t * disp = indev_act->driver.disp;\n\n    /*If there is no last object then search*/\n    if(indev_obj_act == NULL) {\n        indev_obj_act = indev_search_obj(proc, lv_disp_get_layer_sys(disp));\n        if(indev_obj_act == NULL) indev_obj_act = indev_search_obj(proc, lv_disp_get_layer_top(disp));\n        if(indev_obj_act == NULL) indev_obj_act = indev_search_obj(proc, lv_disp_get_scr_act(disp));\n    }\n    /*If there is last object but it is not dragged and not protected also search*/\n    else if(proc->types.pointer.drag_in_prog == 0 &&\n            lv_obj_is_protected(indev_obj_act, LV_PROTECT_PRESS_LOST) == false) {\n        indev_obj_act = indev_search_obj(proc, lv_disp_get_layer_sys(disp));\n        if(indev_obj_act == NULL) indev_obj_act = indev_search_obj(proc, lv_disp_get_layer_top(disp));\n        if(indev_obj_act == NULL) indev_obj_act = indev_search_obj(proc, lv_disp_get_scr_act(disp));\n    }\n    /*If a dragable or a protected object was the last then keep it*/\n    else {\n    }\n\n    /*If a new object was found reset some variables and send a pressed signal*/\n    if(indev_obj_act != proc->types.pointer.act_obj) {\n\n        proc->types.pointer.last_point.x = proc->types.pointer.act_point.x;\n        proc->types.pointer.last_point.y = proc->types.pointer.act_point.y;\n\n        /*If a new object found the previous was lost, so send a signal*/\n        if(proc->types.pointer.act_obj != NULL) {\n            /*Save the obj because in special cases `act_obj` can change in the signal function*/\n            lv_obj_t * last_obj = proc->types.pointer.act_obj;\n\n            last_obj->signal_cb(last_obj, LV_SIGNAL_PRESS_LOST, indev_act);\n            if(indev_reset_check(proc)) return;\n            lv_event_send(last_obj, LV_EVENT_PRESS_LOST, NULL);\n            if(indev_reset_check(proc)) return;\n        }\n\n        proc->types.pointer.act_obj  = indev_obj_act; /*Save the pressed object*/\n        proc->types.pointer.last_obj = indev_obj_act;\n\n        if(indev_obj_act != NULL) {\n            /* Save the time when the obj pressed.\n             * It is necessary to count the long press time.*/\n            proc->pr_timestamp                 = lv_tick_get();\n            proc->long_pr_sent                 = 0;\n            proc->types.pointer.drag_limit_out = 0;\n            proc->types.pointer.drag_in_prog   = 0;\n            proc->types.pointer.drag_sum.x     = 0;\n            proc->types.pointer.drag_sum.y     = 0;\n            proc->types.pointer.vect.x         = 0;\n            proc->types.pointer.vect.y         = 0;\n\n            /*Search for 'top' attribute*/\n            lv_obj_t * i        = indev_obj_act;\n            lv_obj_t * last_top = NULL;\n            while(i != NULL) {\n                if(i->top) last_top = i;\n                i = lv_obj_get_parent(i);\n            }\n\n            if(last_top != NULL) {\n                /*Move the last_top object to the foreground*/\n                lv_obj_move_foreground(last_top);\n            }\n\n            /*Send a signal about the press*/\n            indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_PRESSED, indev_act);\n            if(indev_reset_check(proc)) return;\n\n            lv_event_send(indev_obj_act, LV_EVENT_PRESSED, NULL);\n            if(indev_reset_check(proc)) return;\n        }\n    }\n\n    /*Calculate the types.pointer.vector*/\n    proc->types.pointer.vect.x = proc->types.pointer.act_point.x - proc->types.pointer.last_point.x;\n    proc->types.pointer.vect.y = proc->types.pointer.act_point.y - proc->types.pointer.last_point.y;\n\n    proc->types.pointer.drag_throw_vect.x = (proc->types.pointer.drag_throw_vect.x * 5) >> 3;\n    proc->types.pointer.drag_throw_vect.y = (proc->types.pointer.drag_throw_vect.y * 5) >> 3;\n\n    if(proc->types.pointer.drag_throw_vect.x < 0)\n        proc->types.pointer.drag_throw_vect.x++;\n    else if(proc->types.pointer.drag_throw_vect.x > 0)\n        proc->types.pointer.drag_throw_vect.x--;\n\n    if(proc->types.pointer.drag_throw_vect.y < 0)\n        proc->types.pointer.drag_throw_vect.y++;\n    else if(proc->types.pointer.drag_throw_vect.y > 0)\n        proc->types.pointer.drag_throw_vect.y--;\n\n    proc->types.pointer.drag_throw_vect.x += (proc->types.pointer.vect.x * 4) >> 3;\n    proc->types.pointer.drag_throw_vect.y += (proc->types.pointer.vect.y * 4) >> 3;\n\n    /*If there is active object and it can be dragged run the drag*/\n    if(indev_obj_act != NULL) {\n        indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_PRESSING, indev_act);\n        if(indev_reset_check(proc)) return;\n        lv_event_send(indev_obj_act, LV_EVENT_PRESSING, NULL);\n        if(indev_reset_check(proc)) return;\n\n        indev_drag(proc);\n        if(indev_reset_check(proc)) return;\n\n        /*If there is no drag then check for long press time*/\n        if(proc->types.pointer.drag_in_prog == 0 && proc->long_pr_sent == 0) {\n            /*Send a signal about the long press if enough time elapsed*/\n            if(lv_tick_elaps(proc->pr_timestamp) > indev_act->driver.long_press_time) {\n                indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_LONG_PRESS, indev_act);\n                if(indev_reset_check(proc)) return;\n                lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED, NULL);\n                if(indev_reset_check(proc)) return;\n\n                /*Mark the signal sending to do not send it again*/\n                proc->long_pr_sent = 1;\n\n                /*Save the long press time stamp for the long press repeat handler*/\n                proc->longpr_rep_timestamp = lv_tick_get();\n            }\n        }\n        /*Send long press repeated signal*/\n        if(proc->types.pointer.drag_in_prog == 0 && proc->long_pr_sent == 1) {\n            /*Send a signal about the long press repeat if enough time elapsed*/\n            if(lv_tick_elaps(proc->longpr_rep_timestamp) > indev_act->driver.long_press_rep_time) {\n                indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_LONG_PRESS_REP, indev_act);\n                if(indev_reset_check(proc)) return;\n                lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED_REPEAT, NULL);\n                if(indev_reset_check(proc)) return;\n                proc->longpr_rep_timestamp = lv_tick_get();\n            }\n        }\n    }\n}\n\n/**\n * Process the released state of LV_INDEV_TYPE_POINER input devices\n * @param proc pointer to an input device 'proc'\n */\nstatic void indev_proc_release(lv_indev_proc_t * proc)\n{\n    if(proc->wait_until_release != 0) {\n        proc->types.pointer.act_obj  = NULL;\n        proc->types.pointer.last_obj = NULL;\n        proc->pr_timestamp           = 0;\n        proc->longpr_rep_timestamp   = 0;\n        proc->wait_until_release     = 0;\n    }\n    indev_obj_act = proc->types.pointer.act_obj;\n\n    /*Forget the act obj and send a released signal */\n    if(indev_obj_act) {\n        /* If the object was protected against press lost then it possible that\n         * the object is already not pressed but still it is the `act_obj`.\n         * In this case send the `LV_SIGNAL_RELEASED/CLICKED` instead of `LV_SIGNAL_PRESS_LOST` if\n         * the indev is ON the `types.pointer.act_obj` */\n        if(lv_obj_is_protected(indev_obj_act, LV_PROTECT_PRESS_LOST)) {\n            indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_RELEASED, indev_act);\n            if(indev_reset_check(proc)) return;\n\n            if(proc->types.pointer.drag_in_prog == 0) {\n                if(proc->long_pr_sent == 0) {\n                    lv_event_send(indev_obj_act, LV_EVENT_SHORT_CLICKED, NULL);\n                    if(indev_reset_check(proc)) return;\n                }\n\n                lv_event_send(indev_obj_act, LV_EVENT_CLICKED, NULL);\n                if(indev_reset_check(proc)) return;\n            }\n\n            lv_event_send(indev_obj_act, LV_EVENT_RELEASED, NULL);\n            if(indev_reset_check(proc)) return;\n        }\n        /* The simple case: `act_obj` was not protected against press lost.\n         * If it is already not pressed then `indev_proc_press` would set `indev_obj_act = NULL`*/\n        else {\n            indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_RELEASED, indev_act);\n            if(indev_reset_check(proc)) return;\n\n            if(proc->long_pr_sent == 0 && proc->types.pointer.drag_in_prog == 0) {\n                lv_event_send(indev_obj_act, LV_EVENT_SHORT_CLICKED, NULL);\n                if(indev_reset_check(proc)) return;\n            }\n\n            if(proc->types.pointer.drag_in_prog == 0) {\n                lv_event_send(indev_obj_act, LV_EVENT_CLICKED, NULL);\n                if(indev_reset_check(proc)) return;\n            }\n\n            lv_event_send(indev_obj_act, LV_EVENT_RELEASED, NULL);\n            if(indev_reset_check(proc)) return;\n        }\n\n        if(indev_reset_check(proc)) return;\n\n        /*Handle click focus*/\n        bool click_focus_sent = false;\n#if LV_USE_GROUP\n        lv_group_t * g = lv_obj_get_group(indev_obj_act);\n\n        /*Check, if the parent is in a group and focus on it.*/\n        /*Respect the click focus protection*/\n        if(lv_obj_is_protected(indev_obj_act, LV_PROTECT_CLICK_FOCUS) == false) {\n            lv_obj_t * parent = indev_obj_act;\n\n            while(g == NULL) {\n                parent = lv_obj_get_parent(parent);\n                if(parent == NULL) break;\n\n                /*Ignore is the protected against click focus*/\n                if(lv_obj_is_protected(parent, LV_PROTECT_CLICK_FOCUS)) {\n                    parent = NULL;\n                    break;\n                }\n                g = lv_obj_get_group(parent);\n            }\n\n            /* If a parent is in a group make it focused.\n             * `LV_EVENT_FOCUSED/DEFOCUSED` will be sent by `lv_group_focus_obj`*/\n            if(g && parent) {\n                if(lv_group_get_click_focus(g)) {\n                    click_focus_sent = true;\n                    lv_group_focus_obj(parent);\n                }\n            }\n        }\n#endif\n\n        /* Send defocus to the lastly \"active\" object and foucus to the new one.\n         * DO not sent the events if they was sent by the click focus*/\n        if(proc->types.pointer.last_pressed != indev_obj_act && click_focus_sent == false) {\n            lv_event_send(proc->types.pointer.last_pressed, LV_EVENT_DEFOCUSED, NULL);\n            if(indev_reset_check(proc)) return;\n\n            lv_event_send(proc->types.pointer.act_obj, LV_EVENT_FOCUSED, NULL);\n            if(indev_reset_check(proc)) return;\n\n            proc->types.pointer.last_pressed = indev_obj_act;\n        }\n\n        if(indev_reset_check(proc)) return;\n\n        /*Send LV_EVENT_DRAG_THROW_BEGIN if required */\n        /*If drag parent is active check recursively the drag_parent attribute*/\n        lv_obj_t * drag_obj = indev_obj_act;\n        while(lv_obj_get_drag_parent(drag_obj) != false && drag_obj != NULL) {\n            drag_obj = lv_obj_get_parent(drag_obj);\n        }\n\n        if(drag_obj) {\n            if(lv_obj_get_drag_throw(drag_obj) && proc->types.pointer.drag_in_prog) {\n                lv_event_send(drag_obj, LV_EVENT_DRAG_THROW_BEGIN, NULL);\n                if(indev_reset_check(proc)) return;\n            }\n        }\n\n        proc->types.pointer.act_obj = NULL;\n        proc->pr_timestamp          = 0;\n        proc->longpr_rep_timestamp  = 0;\n    }\n\n    /*The reset can be set in the signal function.\n     * In case of reset query ignore the remaining parts.*/\n    if(proc->types.pointer.last_obj != NULL && proc->reset_query == 0) {\n        indev_drag_throw(proc);\n        if(indev_reset_check(proc)) return;\n    }\n}\n\n/**\n * Process a new point from LV_INDEV_TYPE_BUTTON input device\n * @param i pointer to an input device\n * @param data pointer to the data read from the input device\n * Reset input device if a reset query has been sent to it\n * @param indev pointer to an input device\n */\nstatic void indev_proc_reset_query_handler(lv_indev_t * indev)\n{\n    if(indev->proc.reset_query) {\n        indev->proc.types.pointer.act_obj           = NULL;\n        indev->proc.types.pointer.last_obj          = NULL;\n        indev->proc.types.pointer.last_pressed      = NULL;\n        indev->proc.types.pointer.drag_limit_out    = 0;\n        indev->proc.types.pointer.drag_in_prog      = 0;\n        indev->proc.long_pr_sent                    = 0;\n        indev->proc.pr_timestamp                    = 0;\n        indev->proc.longpr_rep_timestamp            = 0;\n        indev->proc.types.pointer.drag_sum.x        = 0;\n        indev->proc.types.pointer.drag_sum.y        = 0;\n        indev->proc.types.pointer.drag_throw_vect.x = 0;\n        indev->proc.types.pointer.drag_throw_vect.y = 0;\n        indev->proc.reset_query                     = 0;\n        indev_obj_act                               = NULL;\n    }\n}\n/**\n * Search the most top, clickable object on the last point of an input device\n * @param proc pointer to  the `lv_indev_proc_t` part of the input device\n * @param obj pointer to a start object, typically the screen\n * @return pointer to the found object or NULL if there was no suitable object\n */\nstatic lv_obj_t * indev_search_obj(const lv_indev_proc_t * proc, lv_obj_t * obj)\n{\n    lv_obj_t * found_p = NULL;\n\n    /*If the point is on this object check its children too*/\n#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY\n    lv_area_t ext_area;\n    ext_area.x1 = obj->coords.x1 - obj->ext_click_pad_hor;\n    ext_area.x2 = obj->coords.x2 + obj->ext_click_pad_hor;\n    ext_area.y1 = obj->coords.y1 - obj->ext_click_pad_ver;\n    ext_area.y2 = obj->coords.y2 + obj->ext_click_pad_ver;\n\n    if(lv_area_is_point_on(&ext_area, &proc->types.pointer.act_point)) {\n#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL\n    lv_area_t ext_area;\n    ext_area.x1 = obj->coords.x1 - obj->ext_click_pad.x1;\n    ext_area.x2 = obj->coords.x2 + obj->ext_click_pad.x2;\n    ext_area.y1 = obj->coords.y1 - obj->ext_click_pad.y1;\n    ext_area.y2 = obj->coords.y2 + obj->ext_click_pad.y2;\n\n    if(lv_area_is_point_on(&ext_area, &proc->types.pointer.act_point)) {\n#else\n    if(lv_area_is_point_on(&obj->coords, &proc->types.pointer.act_point)) {\n#endif\n        lv_obj_t * i;\n\n        LV_LL_READ(obj->child_ll, i)\n        {\n            found_p = indev_search_obj(proc, i);\n\n            /*If a child was found then break*/\n            if(found_p != NULL) {\n                break;\n            }\n        }\n\n        /*If then the children was not ok, and this obj is clickable\n         * and it or its parent is not hidden then save this object*/\n        if(found_p == NULL && lv_obj_get_click(obj) != false) {\n            lv_obj_t * hidden_i = obj;\n            while(hidden_i != NULL) {\n                if(lv_obj_get_hidden(hidden_i) == true) break;\n                hidden_i = lv_obj_get_parent(hidden_i);\n            }\n            /*No parent found with hidden == true*/\n            if(hidden_i == NULL) found_p = obj;\n        }\n    }\n\n    return found_p;\n}\n\n/**\n * Handle the dragging of indev_proc_p->types.pointer.act_obj\n * @param indev pointer to a input device state\n */\nstatic void indev_drag(lv_indev_proc_t * state)\n{\n    lv_obj_t * drag_obj    = state->types.pointer.act_obj;\n    bool drag_just_started = false;\n\n    /*If drag parent is active check recursively the drag_parent attribute*/\n    while(lv_obj_get_drag_parent(drag_obj) != false && drag_obj != NULL) {\n        drag_obj = lv_obj_get_parent(drag_obj);\n    }\n\n    if(drag_obj == NULL) return;\n\n    if(lv_obj_get_drag(drag_obj) == false) return;\n\n    lv_drag_dir_t allowed_dirs = lv_obj_get_drag_dir(drag_obj);\n\n    /*Count the movement by drag*/\n    state->types.pointer.drag_sum.x += state->types.pointer.vect.x;\n    state->types.pointer.drag_sum.y += state->types.pointer.vect.y;\n\n    /*Enough move?*/\n    if(state->types.pointer.drag_limit_out == 0) {\n        /*If a move is greater then LV_DRAG_LIMIT then begin the drag*/\n        if(((allowed_dirs & LV_DRAG_DIR_HOR) &&\n            LV_MATH_ABS(state->types.pointer.drag_sum.x) >= indev_act->driver.drag_limit) ||\n           ((allowed_dirs & LV_DRAG_DIR_VER) &&\n            LV_MATH_ABS(state->types.pointer.drag_sum.y) >= indev_act->driver.drag_limit)) {\n            state->types.pointer.drag_limit_out = 1;\n            drag_just_started                   = true;\n        }\n    }\n\n    /*If the drag limit is exceeded handle the dragging*/\n    if(state->types.pointer.drag_limit_out != 0) {\n        /*Set new position if the vector is not zero*/\n        if(state->types.pointer.vect.x != 0 || state->types.pointer.vect.y != 0) {\n\n            uint16_t inv_buf_size =\n                lv_disp_get_inv_buf_size(indev_act->driver.disp); /*Get the number of currently invalidated areas*/\n\n            lv_coord_t prev_x     = drag_obj->coords.x1;\n            lv_coord_t prev_y     = drag_obj->coords.y1;\n            lv_coord_t prev_par_w = lv_obj_get_width(lv_obj_get_parent(drag_obj));\n            lv_coord_t prev_par_h = lv_obj_get_height(lv_obj_get_parent(drag_obj));\n\n            /*Get the coordinates of the object and modify them*/\n            lv_coord_t act_x = lv_obj_get_x(drag_obj);\n            lv_coord_t act_y = lv_obj_get_y(drag_obj);\n\n            if(allowed_dirs == LV_DRAG_DIR_ALL) {\n                if(drag_just_started) {\n                    act_x += state->types.pointer.drag_sum.x;\n                    act_y += state->types.pointer.drag_sum.y;\n                }\n                lv_obj_set_pos(drag_obj, act_x + state->types.pointer.vect.x, act_y + state->types.pointer.vect.y);\n            } else if(allowed_dirs & LV_DRAG_DIR_HOR) {\n                if(drag_just_started) {\n                    act_x += state->types.pointer.drag_sum.x;\n                }\n                lv_obj_set_x(drag_obj, act_x + state->types.pointer.vect.x);\n            } else if(allowed_dirs & LV_DRAG_DIR_VER) {\n                if(drag_just_started) {\n                    act_y += state->types.pointer.drag_sum.y;\n                }\n                lv_obj_set_y(drag_obj, act_y + state->types.pointer.vect.y);\n            }\n\n\n\n\n            /*If the object didn't moved then clear the invalidated areas*/\n            if(drag_obj->coords.x1 == prev_x && drag_obj->coords.y1 == prev_y) {\n//                state->types.pointer.drag_in_prog = 0;\n                /*In a special case if the object is moved on a page and\n                 * the scrollable has fit == true and the object is dragged of the page then\n                 * while its coordinate is not changing only the parent's size is reduced */\n                lv_coord_t act_par_w = lv_obj_get_width(lv_obj_get_parent(drag_obj));\n                lv_coord_t act_par_h = lv_obj_get_height(lv_obj_get_parent(drag_obj));\n                if(act_par_w == prev_par_w && act_par_h == prev_par_h) {\n                    uint16_t new_inv_buf_size = lv_disp_get_inv_buf_size(indev_act->driver.disp);\n                    lv_disp_pop_from_inv_buf(indev_act->driver.disp, new_inv_buf_size - inv_buf_size);\n                }\n            } else {\n                state->types.pointer.drag_in_prog = 1;\n                /*Set the drag in progress flag*/\n                /*Send the drag begin signal on first move*/\n                if(drag_just_started) {\n                    drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_BEGIN, indev_act);\n                    if(indev_reset_check(state)) return;\n                    lv_event_send(drag_obj, LV_EVENT_DRAG_BEGIN, NULL);\n                    if(indev_reset_check(state)) return;\n                }\n            }\n        }\n    }\n}\n\n/**\n * Handle throwing by drag if the drag is ended\n * @param indev pointer to an input device state\n */\nstatic void indev_drag_throw(lv_indev_proc_t * proc)\n{\n    if(proc->types.pointer.drag_in_prog == 0) return;\n\n    lv_obj_t * drag_obj = proc->types.pointer.last_obj;\n\n    /*If drag parent is active check recursively the drag_parent attribute*/\n    while(lv_obj_get_drag_parent(drag_obj) != false && drag_obj != NULL) {\n        drag_obj = lv_obj_get_parent(drag_obj);\n    }\n\n    if(drag_obj == NULL) {\n        return;\n    }\n\n    /*Return if the drag throw is not enabled*/\n    if(lv_obj_get_drag_throw(drag_obj) == false) {\n        proc->types.pointer.drag_in_prog = 0;\n        drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act);\n        lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL);\n        if(indev_reset_check(proc)) return;\n\n        lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL);\n        return;\n    }\n\n    lv_drag_dir_t allowed_dirs = lv_obj_get_drag_dir(drag_obj);\n\n    /*Reduce the vectors*/\n    proc->types.pointer.drag_throw_vect.x =\n        proc->types.pointer.drag_throw_vect.x * (100 - indev_act->driver.drag_throw) / 100;\n    proc->types.pointer.drag_throw_vect.y =\n        proc->types.pointer.drag_throw_vect.y * (100 - indev_act->driver.drag_throw) / 100;\n\n    if(proc->types.pointer.drag_throw_vect.x != 0 || proc->types.pointer.drag_throw_vect.y != 0) {\n        /*Get the coordinates and modify them*/\n        lv_area_t coords_ori;\n        lv_obj_get_coords(drag_obj, &coords_ori);\n        lv_coord_t act_x = lv_obj_get_x(drag_obj) + proc->types.pointer.drag_throw_vect.x;\n        lv_coord_t act_y = lv_obj_get_y(drag_obj) + proc->types.pointer.drag_throw_vect.y;\n\n        if(allowed_dirs == LV_DRAG_DIR_ALL)\n            lv_obj_set_pos(drag_obj, act_x, act_y);\n        else if(allowed_dirs & LV_DRAG_DIR_HOR)\n            lv_obj_set_x(drag_obj, act_x);\n        else if(allowed_dirs & LV_DRAG_DIR_VER)\n            lv_obj_set_y(drag_obj, act_y);\n\n        lv_area_t coord_new;\n        lv_obj_get_coords(drag_obj, &coord_new);\n\n        /*If non of the coordinates are changed then do not continue throwing*/\n        if((coords_ori.x1 == coord_new.x1 || proc->types.pointer.drag_throw_vect.x == 0) &&\n           (coords_ori.y1 == coord_new.y1 || proc->types.pointer.drag_throw_vect.y == 0)) {\n            proc->types.pointer.drag_in_prog      = 0;\n            proc->types.pointer.vect.x            = 0;\n            proc->types.pointer.vect.y            = 0;\n            proc->types.pointer.drag_throw_vect.x = 0;\n            proc->types.pointer.drag_throw_vect.y = 0;\n            drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act);\n            if(indev_reset_check(proc)) return;\n            lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL);\n            if(indev_reset_check(proc)) return;\n        }\n    }\n    /*If the types.pointer.vectors become 0 -> types.pointer.drag_in_prog = 0 and send a drag end\n       signal*/\n    else {\n        proc->types.pointer.drag_in_prog = 0;\n        drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act);\n        if(indev_reset_check(proc)) return;\n        lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL);\n        if(indev_reset_check(proc)) return;\n    }\n}\n\n/**\n * Checks if the reset_query flag has been set. If so, perform necessary global indev cleanup actions\n * @param proc pointer to an input device 'proc'\n * return true if indev query should be immediately truncated.\n */\nstatic bool indev_reset_check(lv_indev_proc_t * proc)\n{\n    if(proc->reset_query) {\n        indev_obj_act = NULL;\n    }\n\n    return proc->reset_query ? true : false;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_core/lv_obj.c",
    "content": "/**\n * @file lv_base_obj.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_core/lv_obj.h\"\n#include \"libs/lvgl/lv_core/lv_indev.h\"\n#include \"libs/lvgl/lv_core/lv_refr.h\"\n#include \"libs/lvgl/lv_core/lv_group.h\"\n#include \"libs/lvgl/lv_core/lv_disp.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_misc/lv_anim.h\"\n#include \"libs/lvgl/lv_misc/lv_task.h\"\n#include \"libs/lvgl/lv_misc/lv_async.h\"\n#include \"libs/lvgl/lv_misc/lv_fs.h\"\n#include \"libs/lvgl/lv_hal/lv_hal.h\"\n#include <stdint.h>\n#include <string.h>\n#include \"libs/lvgl/lv_misc/lv_gc.h\"\n\n#if defined(LV_GC_INCLUDE)\n#include LV_GC_INCLUDE\n#endif /* LV_ENABLE_GC */\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_OBJ_DEF_WIDTH (LV_DPI)\n#define LV_OBJ_DEF_HEIGHT (2 * LV_DPI / 3)\n\n/**********************\n *      TYPEDEFS\n **********************/\ntypedef struct _lv_event_temp_data\n{\n    lv_obj_t * obj;\n    bool deleted;\n    struct _lv_event_temp_data * prev;\n} lv_event_temp_data_t;\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic void refresh_children_position(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff);\nstatic void report_style_mod_core(void * style_p, lv_obj_t * obj);\nstatic void refresh_children_style(lv_obj_t * obj);\nstatic void delete_children(lv_obj_t * obj);\nstatic void lv_event_mark_deleted(lv_obj_t * obj);\nstatic void lv_obj_del_async_cb(void * obj);\nstatic bool lv_obj_design(lv_obj_t * obj, const lv_area_t * mask_p, lv_design_mode_t mode);\nstatic lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic bool lv_initialized = false;\nstatic lv_event_temp_data_t * event_temp_data_head;\nstatic const void * event_act_data;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Init. the 'lv' library.\n */\nvoid lv_init(void)\n{\n    /* Do nothing if already initialized */\n    if(lv_initialized) {\n        LV_LOG_WARN(\"lv_init: already inited\");\n        return;\n    }\n\n    LV_LOG_TRACE(\"lv_init started\");\n\n    /*Initialize the lv_misc modules*/\n    lv_mem_init();\n    lv_task_core_init();\n\n#if LV_USE_FILESYSTEM\n    lv_fs_init();\n#endif\n\n#if LV_USE_ANIMATION\n    lv_anim_core_init();\n#endif\n\n#if LV_USE_GROUP\n    lv_group_init();\n#endif\n\n    /*Init. the sstyles*/\n    lv_style_init();\n\n    /*Initialize the screen refresh system*/\n    lv_refr_init();\n\n    lv_ll_init(&LV_GC_ROOT(_lv_disp_ll), sizeof(lv_disp_t));\n    lv_ll_init(&LV_GC_ROOT(_lv_indev_ll), sizeof(lv_indev_t));\n\n    /*Init the input device handling*/\n    lv_indev_init();\n\n    lv_img_decoder_init();\n    lv_img_cache_set_size(LV_IMG_CACHE_DEF_SIZE);\n\n    lv_initialized = true;\n    LV_LOG_INFO(\"lv_init ready\");\n}\n\n/*--------------------\n * Create and delete\n *-------------------*/\n\n/**\n * Create a basic object\n * @param parent pointer to a parent object.\n *                  If NULL then a screen will be created\n * @param copy pointer to a base object, if not NULL then the new object will be copied from it\n * @return pointer to the new object\n */\nlv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)\n{\n\n    lv_obj_t * new_obj = NULL;\n    /*Create a screen if the parent is NULL*/\n    if(parent == NULL) {\n        LV_LOG_TRACE(\"Screen create started\");\n        lv_disp_t * disp = lv_disp_get_default();\n        if(!disp) {\n            LV_LOG_WARN(\"lv_obj_create: not display created to so far. No place to assign the new screen\");\n            return NULL;\n        }\n\n        new_obj = lv_ll_ins_head(&disp->scr_ll);\n        lv_mem_assert(new_obj);\n        if(new_obj == NULL) return NULL;\n\n        new_obj->par = NULL; /*Screens has no a parent*/\n        lv_ll_init(&(new_obj->child_ll), sizeof(lv_obj_t));\n\n        /*Set coordinates to full screen size*/\n        new_obj->coords.x1    = 0;\n        new_obj->coords.y1    = 0;\n        new_obj->coords.x2    = lv_disp_get_hor_res(NULL) - 1;\n        new_obj->coords.y2    = lv_disp_get_ver_res(NULL) - 1;\n        new_obj->ext_draw_pad = 0;\n\n#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL\n        memset(&new_obj->ext_click_pad, 0, sizeof(new_obj->ext_click_pad));\n#endif\n\n#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY\n        new_obj->ext_click_pad_hor = 0;\n        new_obj->ext_click_pad_ver = 0;\n#endif\n\n        /*Init realign*/\n#if LV_USE_OBJ_REALIGN\n        new_obj->realign.align        = LV_ALIGN_CENTER;\n        new_obj->realign.xofs         = 0;\n        new_obj->realign.yofs         = 0;\n        new_obj->realign.base         = NULL;\n        new_obj->realign.auto_realign = 0;\n#endif\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            new_obj->style_p = th->style.scr;\n        } else {\n            new_obj->style_p = &lv_style_scr;\n        }\n        /*Set the callbacks*/\n        lv_obj_set_signal_cb(new_obj, lv_obj_signal);\n        lv_obj_set_design_cb(new_obj, lv_obj_design);\n        new_obj->event_cb = NULL;\n\n        /*Init. user date*/\n#if LV_USE_USER_DATA\n        memset(&new_obj->user_data, 0, sizeof(lv_obj_user_data_t));\n#endif\n\n#if LV_USE_GROUP\n        new_obj->group_p = NULL;\n#endif\n        /*Set attributes*/\n        new_obj->click        = 0;\n        new_obj->drag         = 0;\n        new_obj->drag_throw   = 0;\n        new_obj->drag_parent  = 0;\n        new_obj->hidden       = 0;\n        new_obj->top          = 0;\n        new_obj->protect      = LV_PROTECT_NONE;\n        new_obj->opa_scale_en = 0;\n        new_obj->opa_scale    = LV_OPA_COVER;\n        new_obj->parent_event = 0;\n        new_obj->reserved     = 0;\n\n        new_obj->ext_attr = NULL;\n\n        LV_LOG_INFO(\"Screen create ready\");\n    }\n    /*parent != NULL create normal obj. on a parent*/\n    else {\n        LV_LOG_TRACE(\"Object create started\");\n\n        new_obj = lv_ll_ins_head(&parent->child_ll);\n        lv_mem_assert(new_obj);\n        if(new_obj == NULL) return NULL;\n\n        new_obj->par = parent; /*Set the parent*/\n        lv_ll_init(&(new_obj->child_ll), sizeof(lv_obj_t));\n\n        /*Set coordinates left top corner of parent*/\n        new_obj->coords.x1    = parent->coords.x1;\n        new_obj->coords.y1    = parent->coords.y1;\n        new_obj->coords.x2    = parent->coords.x1 + LV_OBJ_DEF_WIDTH;\n        new_obj->coords.y2    = parent->coords.y1 + LV_OBJ_DEF_HEIGHT;\n        new_obj->ext_draw_pad = 0;\n\n#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL\n        memset(&new_obj->ext_click_pad, 0, sizeof(new_obj->ext_click_pad));\n#endif\n\n#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY\n        new_obj->ext_click_pad_hor = 0;\n        new_obj->ext_click_pad_ver = 0;\n#endif\n\n        /*Init realign*/\n#if LV_USE_OBJ_REALIGN\n        new_obj->realign.align        = LV_ALIGN_CENTER;\n        new_obj->realign.xofs         = 0;\n        new_obj->realign.yofs         = 0;\n        new_obj->realign.base         = NULL;\n        new_obj->realign.auto_realign = 0;\n#endif\n        /*Set appearance*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            new_obj->style_p = th->style.panel;\n        } else {\n            new_obj->style_p = &lv_style_plain_color;\n        }\n\n        /*Set the callbacks*/\n        lv_obj_set_signal_cb(new_obj, lv_obj_signal);\n        lv_obj_set_design_cb(new_obj, lv_obj_design);\n        new_obj->event_cb = NULL;\n\n#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL\n        memset(&new_obj->ext_click_pad, 0, sizeof(new_obj->ext_click_pad));\n#endif\n\n#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY\n        new_obj->ext_click_pad_hor = 0;\n        new_obj->ext_click_pad_ver = 0;\n#endif\n\n        /*Init. user date*/\n#if LV_USE_USER_DATA\n        memset(&new_obj->user_data, 0, sizeof(lv_obj_user_data_t));\n#endif\n\n#if LV_USE_GROUP\n        new_obj->group_p = NULL;\n#endif\n\n        /*Set attributes*/\n        new_obj->click        = 1;\n        new_obj->drag         = 0;\n        new_obj->drag_dir     = LV_DRAG_DIR_ALL;\n        new_obj->drag_throw   = 0;\n        new_obj->drag_parent  = 0;\n        new_obj->hidden       = 0;\n        new_obj->top          = 0;\n        new_obj->protect      = LV_PROTECT_NONE;\n        new_obj->opa_scale    = LV_OPA_COVER;\n        new_obj->opa_scale_en = 0;\n        new_obj->parent_event = 0;\n\n        new_obj->ext_attr = NULL;\n    }\n\n    /*Copy the attributes if required*/\n    if(copy != NULL) {\n        lv_area_copy(&new_obj->coords, &copy->coords);\n        new_obj->ext_draw_pad = copy->ext_draw_pad;\n\n#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL\n        lv_area_copy(&new_obj->ext_click_pad, &copy->ext_click_pad);\n#endif\n\n#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY\n        new_obj->ext_click_pad_hor = copy->ext_click_pad_hor;\n        new_obj->ext_click_pad_ver = copy->ext_click_pad_ver;\n#endif\n\n        /*Set free data*/\n#if LV_USE_USER_DATA\n        memcpy(&new_obj->user_data, &copy->user_data, sizeof(lv_obj_user_data_t));\n#endif\n        /*Copy realign*/\n#if LV_USE_OBJ_REALIGN\n        new_obj->realign.align        = copy->realign.align;\n        new_obj->realign.xofs         = copy->realign.xofs;\n        new_obj->realign.yofs         = copy->realign.yofs;\n        new_obj->realign.base         = copy->realign.base;\n        new_obj->realign.auto_realign = copy->realign.auto_realign;\n#endif\n\n        /*Only copy the `event_cb`. `signal_cb` and `design_cb` will be copied the the derived\n         * object type (e.g. `lv_btn`)*/\n        new_obj->event_cb = copy->event_cb;\n\n        /*Copy attributes*/\n        new_obj->click        = copy->click;\n        new_obj->drag         = copy->drag;\n        new_obj->drag_dir     = copy->drag_dir;\n        new_obj->drag_throw   = copy->drag_throw;\n        new_obj->drag_parent  = copy->drag_parent;\n        new_obj->hidden       = copy->hidden;\n        new_obj->top          = copy->top;\n        new_obj->parent_event = copy->parent_event;\n\n        new_obj->opa_scale_en = copy->opa_scale_en;\n        new_obj->protect      = copy->protect;\n        new_obj->opa_scale    = copy->opa_scale;\n\n        new_obj->style_p = copy->style_p;\n\n#if LV_USE_GROUP\n        /*Add to the same group*/\n        if(copy->group_p != NULL) {\n            lv_group_add_obj(copy->group_p, new_obj);\n        }\n#endif\n\n        /*Set the same coordinates for non screen objects*/\n        if(lv_obj_get_parent(copy) != NULL && parent != NULL) {\n            lv_obj_set_pos(new_obj, lv_obj_get_x(copy), lv_obj_get_y(copy));\n        } else {\n            lv_obj_set_pos(new_obj, 0, 0);\n        }\n\n        LV_LOG_INFO(\"Object create ready\");\n    }\n\n    /*Send a signal to the parent to notify it about the new child*/\n    if(parent != NULL) {\n        parent->signal_cb(parent, LV_SIGNAL_CHILD_CHG, new_obj);\n\n        /*Invalidate the area if not screen created*/\n        lv_obj_invalidate(new_obj);\n    }\n\n    return new_obj;\n}\n\n/**\n * Delete 'obj' and all of its children\n * @param obj pointer to an object to delete\n * @return LV_RES_INV because the object is deleted\n */\nlv_res_t lv_obj_del(lv_obj_t * obj)\n{\n    lv_obj_invalidate(obj);\n\n    /*Delete from the group*/\n#if LV_USE_GROUP\n    lv_group_t * group = lv_obj_get_group(obj);\n    if(group) lv_group_remove_obj(obj);\n#endif\n\n        /*Remove the animations from this object*/\n#if LV_USE_ANIMATION\n    lv_anim_del(obj, NULL);\n#endif\n\n    /*Recursively delete the children*/\n    lv_obj_t * i;\n    lv_obj_t * i_next;\n    i = lv_ll_get_head(&(obj->child_ll));\n    while(i != NULL) {\n        /*Get the next object before delete this*/\n        i_next = lv_ll_get_next(&(obj->child_ll), i);\n\n        /*Call the recursive del to the child too*/\n        delete_children(i);\n\n        /*Set i to the next node*/\n        i = i_next;\n    }\n\n    /*Let the user free the resources used in `LV_EVENT_DELETE`*/\n    lv_event_send(obj, LV_EVENT_DELETE, NULL);\n\n    lv_event_mark_deleted(obj);\n\n    /*Remove the object from parent's children list*/\n    lv_obj_t * par = lv_obj_get_parent(obj);\n    if(par == NULL) { /*It is a screen*/\n        lv_disp_t * d = lv_obj_get_disp(obj);\n        lv_ll_rem(&d->scr_ll, obj);\n    } else {\n        lv_ll_rem(&(par->child_ll), obj);\n    }\n\n    /* Reset all input devices if the object to delete is used*/\n    lv_indev_t * indev = lv_indev_get_next(NULL);\n    while(indev) {\n        if(indev->proc.types.pointer.act_obj == obj || indev->proc.types.pointer.last_obj == obj) {\n            lv_indev_reset(indev);\n        }\n        if(indev->proc.types.pointer.last_pressed == obj) {\n            indev->proc.types.pointer.last_pressed = NULL;\n        }\n\n#if LV_USE_GROUP\n        if(indev->group == group && obj == lv_indev_get_obj_act()) {\n            lv_indev_reset(indev);\n        }\n#endif\n        indev = lv_indev_get_next(indev);\n    }\n\n    /* All children deleted.\n     * Now clean up the object specific data*/\n    obj->signal_cb(obj, LV_SIGNAL_CLEANUP, NULL);\n\n    /*Delete the base objects*/\n    if(obj->ext_attr != NULL) lv_mem_free(obj->ext_attr);\n    lv_mem_free(obj); /*Free the object itself*/\n\n    /*Send a signal to the parent to notify it about the child delete*/\n    if(par != NULL) {\n        par->signal_cb(par, LV_SIGNAL_CHILD_CHG, NULL);\n    }\n\n    return LV_RES_INV;\n}\n\n/**\n * Helper function for asynchronously deleting objects.\n * Useful for cases where you can't delete an object directly in an `LV_EVENT_DELETE` handler (i.e. parent).\n * @param obj object to delete\n * @see lv_async_call\n */\nvoid lv_obj_del_async(lv_obj_t * obj)\n{\n    lv_async_call(lv_obj_del_async_cb, obj);\n}\n\n/**\n * Delete all children of an object\n * @param obj pointer to an object\n */\nvoid lv_obj_clean(lv_obj_t * obj)\n{\n    lv_obj_t * child = lv_obj_get_child(obj, NULL);\n    lv_obj_t * child_next;\n    while(child) {\n        /* Read the next child before deleting the current\n         * because the next couldn't be read from a deleted (invalid) node*/\n        child_next = lv_obj_get_child(obj, child);\n        lv_obj_del(child);\n        child = child_next;\n    }\n}\n\n/**\n * Mark the object as invalid therefore its current position will be redrawn by 'lv_refr_task'\n * @param obj pointer to an object\n */\nvoid lv_obj_invalidate(const lv_obj_t * obj)\n{\n    if(lv_obj_get_hidden(obj)) return;\n\n    /*Invalidate the object only if it belongs to the 'LV_GC_ROOT(_lv_act_scr)'*/\n    lv_obj_t * obj_scr = lv_obj_get_screen(obj);\n    lv_disp_t * disp   = lv_obj_get_disp(obj_scr);\n    if(obj_scr == lv_disp_get_scr_act(disp) || obj_scr == lv_disp_get_layer_top(disp) ||\n       obj_scr == lv_disp_get_layer_sys(disp)) {\n        /*Truncate recursively to the parents*/\n        lv_area_t area_trunc;\n        lv_obj_t * par = lv_obj_get_parent(obj);\n        bool union_ok  = true;\n        /*Start with the original coordinates*/\n        lv_coord_t ext_size = obj->ext_draw_pad;\n        lv_area_copy(&area_trunc, &obj->coords);\n        area_trunc.x1 -= ext_size;\n        area_trunc.y1 -= ext_size;\n        area_trunc.x2 += ext_size;\n        area_trunc.y2 += ext_size;\n\n        /*Check through all parents*/\n        while(par != NULL) {\n            union_ok = lv_area_intersect(&area_trunc, &area_trunc, &par->coords);\n            if(union_ok == false) break;       /*If no common parts with parent break;*/\n            if(lv_obj_get_hidden(par)) return; /*If the parent is hidden then the child is hidden and won't be drawn*/\n\n            par = lv_obj_get_parent(par);\n        }\n\n        if(union_ok) lv_inv_area(disp, &area_trunc);\n    }\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/*--------------------\n * Parent/children set\n *--------------------*/\n\n/**\n * Set a new parent for an object. Its relative position will be the same.\n * @param obj pointer to an object. Can't be a screen.\n * @param parent pointer to the new parent object. (Can't be NULL)\n */\nvoid lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent)\n{\n    if(obj->par == NULL) {\n        LV_LOG_WARN(\"Can't set the parent of a screen\");\n        return;\n    }\n\n    if(parent == NULL) {\n        LV_LOG_WARN(\"Can't set parent == NULL to an object\");\n        return;\n    }\n\n    lv_obj_invalidate(obj);\n\n    lv_point_t old_pos;\n    old_pos.x = lv_obj_get_x(obj);\n    old_pos.y = lv_obj_get_y(obj);\n\n    lv_obj_t * old_par = obj->par;\n\n    lv_ll_chg_list(&obj->par->child_ll, &parent->child_ll, obj, true);\n    obj->par = parent;\n    lv_obj_set_pos(obj, old_pos.x, old_pos.y);\n\n    /*Notify the original parent because one of its children is lost*/\n    old_par->signal_cb(old_par, LV_SIGNAL_CHILD_CHG, NULL);\n\n    /*Notify the new parent about the child*/\n    parent->signal_cb(parent, LV_SIGNAL_CHILD_CHG, obj);\n\n    lv_obj_invalidate(obj);\n}\n\n/**\n * Move and object to the foreground\n * @param obj pointer to an object\n */\nvoid lv_obj_move_foreground(lv_obj_t * obj)\n{\n    lv_obj_t * parent = lv_obj_get_parent(obj);\n\n    /*Do nothing of already in the foreground*/\n    if(lv_ll_get_head(&parent->child_ll) == obj) return;\n\n    lv_obj_invalidate(parent);\n\n    lv_ll_chg_list(&parent->child_ll, &parent->child_ll, obj, true);\n\n    /*Notify the new parent about the child*/\n    parent->signal_cb(parent, LV_SIGNAL_CHILD_CHG, obj);\n\n    lv_obj_invalidate(parent);\n}\n\n/**\n * Move and object to the background\n * @param obj pointer to an object\n */\nvoid lv_obj_move_background(lv_obj_t * obj)\n{\n    lv_obj_t * parent = lv_obj_get_parent(obj);\n\n    /*Do nothing of already in the background*/\n    if(lv_ll_get_tail(&parent->child_ll) == obj) return;\n\n    lv_obj_invalidate(parent);\n\n    lv_ll_chg_list(&parent->child_ll, &parent->child_ll, obj, false);\n\n    /*Notify the new parent about the child*/\n    parent->signal_cb(parent, LV_SIGNAL_CHILD_CHG, obj);\n\n    lv_obj_invalidate(parent);\n}\n\n/*--------------------\n * Coordinate set\n * ------------------*/\n\n/**\n * Set relative the position of an object (relative to the parent)\n * @param obj pointer to an object\n * @param x new distance from the left side of the parent\n * @param y new distance from the top of the parent\n */\nvoid lv_obj_set_pos(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)\n{\n    /*Convert x and y to absolute coordinates*/\n    lv_obj_t * par = obj->par;\n\n    x = x + par->coords.x1;\n    y = y + par->coords.y1;\n\n    /*Calculate and set the movement*/\n    lv_point_t diff;\n    diff.x = x - obj->coords.x1;\n    diff.y = y - obj->coords.y1;\n\n    /* Do nothing if the position is not changed */\n    /* It is very important else recursive positioning can\n     * occur without position change*/\n    if(diff.x == 0 && diff.y == 0) return;\n\n    /*Invalidate the original area*/\n    lv_obj_invalidate(obj);\n\n    /*Save the original coordinates*/\n    lv_area_t ori;\n    lv_obj_get_coords(obj, &ori);\n\n    obj->coords.x1 += diff.x;\n    obj->coords.y1 += diff.y;\n    obj->coords.x2 += diff.x;\n    obj->coords.y2 += diff.y;\n\n    refresh_children_position(obj, diff.x, diff.y);\n\n    /*Inform the object about its new coordinates*/\n    obj->signal_cb(obj, LV_SIGNAL_CORD_CHG, &ori);\n\n    /*Send a signal to the parent too*/\n    par->signal_cb(par, LV_SIGNAL_CHILD_CHG, obj);\n\n    /*Invalidate the new area*/\n    lv_obj_invalidate(obj);\n}\n\n/**\n * Set the x coordinate of a object\n * @param obj pointer to an object\n * @param x new distance from the left side from the parent\n */\nvoid lv_obj_set_x(lv_obj_t * obj, lv_coord_t x)\n{\n    lv_obj_set_pos(obj, x, lv_obj_get_y(obj));\n}\n\n/**\n * Set the y coordinate of a object\n * @param obj pointer to an object\n * @param y new distance from the top of the parent\n */\nvoid lv_obj_set_y(lv_obj_t * obj, lv_coord_t y)\n{\n    lv_obj_set_pos(obj, lv_obj_get_x(obj), y);\n}\n\n/**\n * Set the size of an object\n * @param obj pointer to an object\n * @param w new width\n * @param h new height\n */\nvoid lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h)\n{\n\n    /* Do nothing if the size is not changed */\n    /* It is very important else recursive resizing can\n     * occur without size change*/\n    if(lv_obj_get_width(obj) == w && lv_obj_get_height(obj) == h) {\n        return;\n    }\n\n    /*Invalidate the original area*/\n    lv_obj_invalidate(obj);\n\n    /*Save the original coordinates*/\n    lv_area_t ori;\n    lv_obj_get_coords(obj, &ori);\n\n    /*Set the length and height*/\n    obj->coords.x2 = obj->coords.x1 + w - 1;\n    obj->coords.y2 = obj->coords.y1 + h - 1;\n\n    /*Send a signal to the object with its new coordinates*/\n    obj->signal_cb(obj, LV_SIGNAL_CORD_CHG, &ori);\n\n    /*Send a signal to the parent too*/\n    lv_obj_t * par = lv_obj_get_parent(obj);\n    if(par != NULL) par->signal_cb(par, LV_SIGNAL_CHILD_CHG, obj);\n\n    /*Tell the children the parent's size has changed*/\n    lv_obj_t * i;\n    LV_LL_READ(obj->child_ll, i)\n    {\n        i->signal_cb(i, LV_SIGNAL_PARENT_SIZE_CHG, NULL);\n    }\n\n    /*Invalidate the new area*/\n    lv_obj_invalidate(obj);\n\n    /*Automatically realign the object if required*/\n#if LV_USE_OBJ_REALIGN\n    if(obj->realign.auto_realign) lv_obj_realign(obj);\n#endif\n}\n\n/**\n * Set the width of an object\n * @param obj pointer to an object\n * @param w new width\n */\nvoid lv_obj_set_width(lv_obj_t * obj, lv_coord_t w)\n{\n    lv_obj_set_size(obj, w, lv_obj_get_height(obj));\n}\n\n/**\n * Set the height of an object\n * @param obj pointer to an object\n * @param h new height\n */\nvoid lv_obj_set_height(lv_obj_t * obj, lv_coord_t h)\n{\n    lv_obj_set_size(obj, lv_obj_get_width(obj), h);\n}\n\n/**\n * Align an object to an other object.\n * @param obj pointer to an object to align\n * @param base pointer to an object (if NULL the parent is used). 'obj' will be aligned to it.\n * @param align type of alignment (see 'lv_align_t' enum)\n * @param x_mod x coordinate shift after alignment\n * @param y_mod y coordinate shift after alignment\n */\nvoid lv_obj_align(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_mod, lv_coord_t y_mod)\n{\n    lv_coord_t new_x = lv_obj_get_x(obj);\n    lv_coord_t new_y = lv_obj_get_y(obj);\n\n    if(base == NULL) {\n        base = lv_obj_get_parent(obj);\n    }\n\n    switch(align) {\n        case LV_ALIGN_CENTER:\n            new_x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2;\n            new_y = lv_obj_get_height(base) / 2 - lv_obj_get_height(obj) / 2;\n            break;\n\n        case LV_ALIGN_IN_TOP_LEFT:\n            new_x = 0;\n            new_y = 0;\n            break;\n        case LV_ALIGN_IN_TOP_MID:\n            new_x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2;\n            new_y = 0;\n            break;\n\n        case LV_ALIGN_IN_TOP_RIGHT:\n            new_x = lv_obj_get_width(base) - lv_obj_get_width(obj);\n            new_y = 0;\n            break;\n\n        case LV_ALIGN_IN_BOTTOM_LEFT:\n            new_x = 0;\n            new_y = lv_obj_get_height(base) - lv_obj_get_height(obj);\n            break;\n        case LV_ALIGN_IN_BOTTOM_MID:\n            new_x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2;\n            new_y = lv_obj_get_height(base) - lv_obj_get_height(obj);\n            break;\n\n        case LV_ALIGN_IN_BOTTOM_RIGHT:\n            new_x = lv_obj_get_width(base) - lv_obj_get_width(obj);\n            new_y = lv_obj_get_height(base) - lv_obj_get_height(obj);\n            break;\n\n        case LV_ALIGN_IN_LEFT_MID:\n            new_x = 0;\n            new_y = lv_obj_get_height(base) / 2 - lv_obj_get_height(obj) / 2;\n            break;\n\n        case LV_ALIGN_IN_RIGHT_MID:\n            new_x = lv_obj_get_width(base) - lv_obj_get_width(obj);\n            new_y = lv_obj_get_height(base) / 2 - lv_obj_get_height(obj) / 2;\n            break;\n\n        case LV_ALIGN_OUT_TOP_LEFT:\n            new_x = 0;\n            new_y = -lv_obj_get_height(obj);\n            break;\n\n        case LV_ALIGN_OUT_TOP_MID:\n            new_x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2;\n            new_y = -lv_obj_get_height(obj);\n            break;\n\n        case LV_ALIGN_OUT_TOP_RIGHT:\n            new_x = lv_obj_get_width(base) - lv_obj_get_width(obj);\n            new_y = -lv_obj_get_height(obj);\n            break;\n\n        case LV_ALIGN_OUT_BOTTOM_LEFT:\n            new_x = 0;\n            new_y = lv_obj_get_height(base);\n            break;\n\n        case LV_ALIGN_OUT_BOTTOM_MID:\n            new_x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2;\n            new_y = lv_obj_get_height(base);\n            break;\n\n        case LV_ALIGN_OUT_BOTTOM_RIGHT:\n            new_x = lv_obj_get_width(base) - lv_obj_get_width(obj);\n            new_y = lv_obj_get_height(base);\n            break;\n\n        case LV_ALIGN_OUT_LEFT_TOP:\n            new_x = -lv_obj_get_width(obj);\n            new_y = 0;\n            break;\n\n        case LV_ALIGN_OUT_LEFT_MID:\n            new_x = -lv_obj_get_width(obj);\n            new_y = lv_obj_get_height(base) / 2 - lv_obj_get_height(obj) / 2;\n            break;\n\n        case LV_ALIGN_OUT_LEFT_BOTTOM:\n            new_x = -lv_obj_get_width(obj);\n            new_y = lv_obj_get_height(base) - lv_obj_get_height(obj);\n            break;\n\n        case LV_ALIGN_OUT_RIGHT_TOP:\n            new_x = lv_obj_get_width(base);\n            new_y = 0;\n            break;\n\n        case LV_ALIGN_OUT_RIGHT_MID:\n            new_x = lv_obj_get_width(base);\n            new_y = lv_obj_get_height(base) / 2 - lv_obj_get_height(obj) / 2;\n            break;\n\n        case LV_ALIGN_OUT_RIGHT_BOTTOM:\n            new_x = lv_obj_get_width(base);\n            new_y = lv_obj_get_height(base) - lv_obj_get_height(obj);\n            break;\n    }\n\n    /*Bring together the coordination system of base and obj*/\n    lv_obj_t * par        = lv_obj_get_parent(obj);\n    lv_coord_t base_abs_x = base->coords.x1;\n    lv_coord_t base_abs_y = base->coords.y1;\n    lv_coord_t par_abs_x  = par->coords.x1;\n    lv_coord_t par_abs_y  = par->coords.y1;\n    new_x += x_mod + base_abs_x;\n    new_y += y_mod + base_abs_y;\n    new_x -= par_abs_x;\n    new_y -= par_abs_y;\n\n    lv_obj_set_pos(obj, new_x, new_y);\n\n#if LV_USE_OBJ_REALIGN\n    /*Save the last align parameters to use them in `lv_obj_realign`*/\n    obj->realign.align       = align;\n    obj->realign.xofs        = x_mod;\n    obj->realign.yofs        = y_mod;\n    obj->realign.base        = base;\n    obj->realign.origo_align = 0;\n#endif\n}\n\n/**\n * Align an object's middle point to an other object.\n * @param obj pointer to an object to align\n * @param base pointer to an object (if NULL the parent is used). 'obj' will be aligned to it.\n * @param align type of alignment (see 'lv_align_t' enum)\n * @param x_mod x coordinate shift after alignment\n * @param y_mod y coordinate shift after alignment\n */\nvoid lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_mod, lv_coord_t y_mod)\n{\n    lv_coord_t new_x = lv_obj_get_x(obj);\n    lv_coord_t new_y = lv_obj_get_y(obj);\n\n    lv_coord_t obj_w_half = lv_obj_get_width(obj) / 2;\n    lv_coord_t obj_h_half = lv_obj_get_height(obj) / 2;\n\n    if(base == NULL) {\n        base = lv_obj_get_parent(obj);\n    }\n\n    switch(align) {\n        case LV_ALIGN_CENTER:\n            new_x = lv_obj_get_width(base) / 2 - obj_w_half;\n            new_y = lv_obj_get_height(base) / 2 - obj_h_half;\n            break;\n\n        case LV_ALIGN_IN_TOP_LEFT:\n            new_x = -obj_w_half;\n            new_y = -obj_h_half;\n            break;\n        case LV_ALIGN_IN_TOP_MID:\n            new_x = lv_obj_get_width(base) / 2 - obj_w_half;\n            new_y = -obj_h_half;\n            break;\n\n        case LV_ALIGN_IN_TOP_RIGHT:\n            new_x = lv_obj_get_width(base) - obj_w_half;\n            new_y = -obj_h_half;\n            break;\n\n        case LV_ALIGN_IN_BOTTOM_LEFT:\n            new_x = -obj_w_half;\n            new_y = lv_obj_get_height(base) - obj_h_half;\n            break;\n        case LV_ALIGN_IN_BOTTOM_MID:\n            new_x = lv_obj_get_width(base) / 2 - obj_w_half;\n            new_y = lv_obj_get_height(base) - obj_h_half;\n            break;\n\n        case LV_ALIGN_IN_BOTTOM_RIGHT:\n            new_x = lv_obj_get_width(base) - obj_w_half;\n            new_y = lv_obj_get_height(base) - obj_h_half;\n            break;\n\n        case LV_ALIGN_IN_LEFT_MID:\n            new_x = -obj_w_half;\n            new_y = lv_obj_get_height(base) / 2 - obj_h_half;\n            break;\n\n        case LV_ALIGN_IN_RIGHT_MID:\n            new_x = lv_obj_get_width(base) - obj_w_half;\n            new_y = lv_obj_get_height(base) / 2 - obj_h_half;\n            break;\n\n        case LV_ALIGN_OUT_TOP_LEFT:\n            new_x = -obj_w_half;\n            new_y = -obj_h_half;\n            break;\n\n        case LV_ALIGN_OUT_TOP_MID:\n            new_x = lv_obj_get_width(base) / 2 - obj_w_half;\n            new_y = -obj_h_half;\n            break;\n\n        case LV_ALIGN_OUT_TOP_RIGHT:\n            new_x = lv_obj_get_width(base) - obj_w_half;\n            new_y = -obj_h_half;\n            break;\n\n        case LV_ALIGN_OUT_BOTTOM_LEFT:\n            new_x = -obj_w_half;\n            new_y = lv_obj_get_height(base) - obj_h_half;\n            break;\n\n        case LV_ALIGN_OUT_BOTTOM_MID:\n            new_x = lv_obj_get_width(base) / 2 - obj_w_half;\n            new_y = lv_obj_get_height(base) - obj_h_half;\n            break;\n\n        case LV_ALIGN_OUT_BOTTOM_RIGHT:\n            new_x = lv_obj_get_width(base) - obj_w_half;\n            new_y = lv_obj_get_height(base) - obj_h_half;\n            break;\n\n        case LV_ALIGN_OUT_LEFT_TOP:\n            new_x = -obj_w_half;\n            new_y = -obj_h_half;\n            break;\n\n        case LV_ALIGN_OUT_LEFT_MID:\n            new_x = -obj_w_half;\n            new_y = lv_obj_get_height(base) / 2 - obj_h_half;\n            break;\n\n        case LV_ALIGN_OUT_LEFT_BOTTOM:\n            new_x = -obj_w_half;\n            new_y = lv_obj_get_height(base) - obj_h_half;\n            break;\n\n        case LV_ALIGN_OUT_RIGHT_TOP:\n            new_x = lv_obj_get_width(base) - obj_w_half;\n            new_y = -obj_h_half;\n            break;\n\n        case LV_ALIGN_OUT_RIGHT_MID:\n            new_x = lv_obj_get_width(base) - obj_w_half;\n            new_y = lv_obj_get_height(base) / 2 - obj_h_half;\n            break;\n\n        case LV_ALIGN_OUT_RIGHT_BOTTOM:\n            new_x = lv_obj_get_width(base) - obj_w_half;\n            new_y = lv_obj_get_height(base) - obj_h_half;\n            break;\n    }\n\n    /*Bring together the coordination system of base and obj*/\n    lv_obj_t * par        = lv_obj_get_parent(obj);\n    lv_coord_t base_abs_x = base->coords.x1;\n    lv_coord_t base_abs_y = base->coords.y1;\n    lv_coord_t par_abs_x  = par->coords.x1;\n    lv_coord_t par_abs_y  = par->coords.y1;\n    new_x += x_mod + base_abs_x;\n    new_y += y_mod + base_abs_y;\n    new_x -= par_abs_x;\n    new_y -= par_abs_y;\n\n    lv_obj_set_pos(obj, new_x, new_y);\n\n#if LV_USE_OBJ_REALIGN\n    /*Save the last align parameters to use them in `lv_obj_realign`*/\n    obj->realign.align       = align;\n    obj->realign.xofs        = x_mod;\n    obj->realign.yofs        = y_mod;\n    obj->realign.base        = base;\n    obj->realign.origo_align = 1;\n#endif\n}\n\n/**\n * Realign the object based on the last `lv_obj_align` parameters.\n * @param obj pointer to an object\n */\nvoid lv_obj_realign(lv_obj_t * obj)\n{\n#if LV_USE_OBJ_REALIGN\n    if(obj->realign.origo_align)\n        lv_obj_align_origo(obj, obj->realign.base, obj->realign.align, obj->realign.xofs, obj->realign.yofs);\n    else\n        lv_obj_align(obj, obj->realign.base, obj->realign.align, obj->realign.xofs, obj->realign.yofs);\n#else\n    (void)obj;\n    LV_LOG_WARN(\"lv_obj_realaign: no effect because LV_USE_OBJ_REALIGN = 0\");\n#endif\n}\n\n/**\n * Enable the automatic realign of the object when its size has changed based on the last\n * `lv_obj_align` parameters.\n * @param obj pointer to an object\n * @param en true: enable auto realign; false: disable auto realign\n */\nvoid lv_obj_set_auto_realign(lv_obj_t * obj, bool en)\n{\n#if LV_USE_OBJ_REALIGN\n    obj->realign.auto_realign = en ? 1 : 0;\n#else\n    (void)obj;\n    (void)en;\n    LV_LOG_WARN(\"lv_obj_set_auto_realign: no effect because LV_USE_OBJ_REALIGN = 0\");\n#endif\n}\n\n#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY\n/**\n * Set the size of an extended clickable area\n * @param obj pointer to an object\n * @param w extended width to both sides\n * @param h extended height to both sides\n */\nvoid lv_obj_set_ext_click_area(lv_obj_t * obj, uint8_t w, uint8_t h)\n{\n    obj->ext_click_pad_hor = w;\n    obj->ext_click_pad_ver = h;\n}\n#endif\n\n/**\n * Set the size of an extended clickable area\n * If TINY mode is used, only the largest of the horizontal and vertical padding\n * values are considered.\n * @param obj pointer to an object\n * @param left extended clickable are on the left [px]\n * @param right extended clickable are on the right [px]\n * @param top extended clickable are on the top [px]\n * @param bottom extended clickable are on the bottom [px]\n */\nvoid lv_obj_set_ext_click_area(lv_obj_t * obj, lv_coord_t left, lv_coord_t right, lv_coord_t top, lv_coord_t bottom)\n{\n#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL\n    obj->ext_click_pad.x1 = left;\n    obj->ext_click_pad.x2 = right;\n    obj->ext_click_pad.y1 = top;\n    obj->ext_click_pad.y2 = bottom;\n#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY\n    obj->ext_click_pad_hor = LV_MATH_MAX(left, right);\n    obj->ext_click_pad_ver = LV_MATH_MAX(top, bottom);\n#else\n    (void)obj;    /*Unused*/\n    (void)left;   /*Unused*/\n    (void)right;  /*Unused*/\n    (void)top;    /*Unused*/\n    (void)bottom; /*Unused*/\n#endif\n}\n\n/*---------------------\n * Appearance set\n *--------------------*/\n\n/**\n * Set a new style for an object\n * @param obj pointer to an object\n * @param style_p pointer to the new style\n */\nvoid lv_obj_set_style(lv_obj_t * obj, const lv_style_t * style)\n{\n    obj->style_p = style;\n\n    /*Send a signal about style change to every children with NULL style*/\n    refresh_children_style(obj);\n\n    /*Notify the object about the style change too*/\n    lv_obj_refresh_style(obj);\n}\n\n/**\n * Notify an object about its style is modified\n * @param obj pointer to an object\n */\nvoid lv_obj_refresh_style(lv_obj_t * obj)\n{\n    lv_obj_invalidate(obj);\n    obj->signal_cb(obj, LV_SIGNAL_STYLE_CHG, NULL);\n    lv_obj_invalidate(obj);\n}\n\n/**\n * Notify all object if a style is modified\n * @param style pointer to a style. Only the objects with this style will be notified\n *               (NULL to notify all objects)\n */\nvoid lv_obj_report_style_mod(lv_style_t * style)\n{\n    lv_disp_t * d = lv_disp_get_next(NULL);\n\n    while(d) {\n        lv_obj_t * i;\n        LV_LL_READ(d->scr_ll, i)\n        {\n            if(i->style_p == style || style == NULL) {\n                lv_obj_refresh_style(i);\n            }\n\n            report_style_mod_core(style, i);\n        }\n        d = lv_disp_get_next(d);\n    }\n}\n\n/*-----------------\n * Attribute set\n *----------------*/\n\n/**\n * Hide an object. It won't be visible and clickable.\n * @param obj pointer to an object\n * @param en true: hide the object\n */\nvoid lv_obj_set_hidden(lv_obj_t * obj, bool en)\n{\n    if(!obj->hidden) lv_obj_invalidate(obj); /*Invalidate when not hidden (hidden objects are ignored) */\n\n    obj->hidden = en == false ? 0 : 1;\n\n    if(!obj->hidden) lv_obj_invalidate(obj); /*Invalidate when not hidden (hidden objects are ignored) */\n\n    lv_obj_t * par = lv_obj_get_parent(obj);\n    par->signal_cb(par, LV_SIGNAL_CHILD_CHG, obj);\n}\n\n/**\n * Enable or disable the clicking of an object\n * @param obj pointer to an object\n * @param en true: make the object clickable\n */\nvoid lv_obj_set_click(lv_obj_t * obj, bool en)\n{\n    obj->click = (en == true ? 1 : 0);\n}\n\n/**\n * Enable to bring this object to the foreground if it\n * or any of its children is clicked\n * @param obj pointer to an object\n * @param en true: enable the auto top feature\n */\nvoid lv_obj_set_top(lv_obj_t * obj, bool en)\n{\n    obj->top = (en == true ? 1 : 0);\n}\n\n/**\n * Enable the dragging of an object\n * @param obj pointer to an object\n * @param en true: make the object dragable\n */\nvoid lv_obj_set_drag(lv_obj_t * obj, bool en)\n{\n    if(en == true) lv_obj_set_click(obj, true); /*Drag is useless without enabled clicking*/\n    obj->drag = (en == true ? 1 : 0);\n}\n\n/**\n * Set the directions an object can be dragged in\n * @param obj pointer to an object\n * @param drag_dir bitwise OR of allowed directions an object can be dragged in\n */\nvoid lv_obj_set_drag_dir(lv_obj_t * obj, lv_drag_dir_t drag_dir)\n{\n    obj->drag_dir = drag_dir;\n\n    if(obj->drag_dir != 0) lv_obj_set_drag(obj, true); /*Drag direction requires drag*/\n}\n\n/**\n * Enable the throwing of an object after is is dragged\n * @param obj pointer to an object\n * @param en true: enable the drag throw\n */\nvoid lv_obj_set_drag_throw(lv_obj_t * obj, bool en)\n{\n    obj->drag_throw = (en == true ? 1 : 0);\n}\n\n/**\n * Enable to use parent for drag related operations.\n * If trying to drag the object the parent will be moved instead\n * @param obj pointer to an object\n * @param en true: enable the 'drag parent' for the object\n */\nvoid lv_obj_set_drag_parent(lv_obj_t * obj, bool en)\n{\n    obj->drag_parent = (en == true ? 1 : 0);\n}\n\n/**\n * Propagate the events to the parent too\n * @param obj pointer to an object\n * @param en true: enable the event propagation\n */\nvoid lv_obj_set_parent_event(lv_obj_t * obj, bool en)\n{\n    obj->parent_event = (en == true ? 1 : 0);\n}\n\n/**\n * Set the opa scale enable parameter (required to set opa_scale with `lv_obj_set_opa_scale()`)\n * @param obj pointer to an object\n * @param en true: opa scaling is enabled for this object and all children; false: no opa scaling\n */\nvoid lv_obj_set_opa_scale_enable(lv_obj_t * obj, bool en)\n{\n    obj->opa_scale_en = en ? 1 : 0;\n}\n\n/**\n * Set the opa scale of an object.\n * The opacity of this object and all it's children will be scaled down with this factor.\n * `lv_obj_set_opa_scale_enable(obj, true)` needs to be called to enable it.\n * (not for all children just for the parent where to start the opa scaling)\n * @param obj pointer to an object\n * @param opa_scale a factor to scale down opacity [0..255]\n */\nvoid lv_obj_set_opa_scale(lv_obj_t * obj, lv_opa_t opa_scale)\n{\n    obj->opa_scale = opa_scale;\n    lv_obj_invalidate(obj);\n}\n\n/**\n * Set a bit or bits in the protect filed\n * @param obj pointer to an object\n * @param prot 'OR'-ed values from `lv_protect_t`\n */\nvoid lv_obj_set_protect(lv_obj_t * obj, uint8_t prot)\n{\n    obj->protect |= prot;\n}\n\n/**\n * Clear a bit or bits in the protect filed\n * @param obj pointer to an object\n * @param prot 'OR'-ed values from `lv_protect_t`\n */\nvoid lv_obj_clear_protect(lv_obj_t * obj, uint8_t prot)\n{\n    prot = (~prot) & 0xFF;\n    obj->protect &= prot;\n}\n\n/**\n * Set a an event handler function for an object.\n * Used by the user to react on event which happens with the object.\n * @param obj pointer to an object\n * @param event_cb the new event function\n */\nvoid lv_obj_set_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb)\n{\n    obj->event_cb = event_cb;\n}\n\n/**\n * Send an event to the object\n * @param obj pointer to an object\n * @param event the type of the event from `lv_event_t`\n * @param data arbitrary data depending on the object type and the event. (Usually `NULL`)\n * @return LV_RES_OK: `obj` was not deleted in the event; LV_RES_INV: `obj` was deleted in the event\n */\nlv_res_t lv_event_send(lv_obj_t * obj, lv_event_t event, const void * data)\n{\n    if(obj == NULL) return LV_RES_OK;\n\n    lv_res_t res;\n    res = lv_event_send_func(obj->event_cb, obj, event, data);\n    return res;\n}\n\n/**\n * Call an event function with an object, event, and data.\n * @param event_xcb an event callback function. If `NULL` `LV_RES_OK` will return without any actions.\n *        (the 'x' in the argument name indicates that its not a fully generic function because it not follows\n *         the `func_name(object, callback, ...)` convention)\n * @param obj pointer to an object to associate with the event (can be `NULL` to simply call the `event_cb`)\n * @param event an event\n * @param data pointer to a custom data\n * @return LV_RES_OK: `obj` was not deleted in the event; LV_RES_INV: `obj` was deleted in the event\n */\nlv_res_t lv_event_send_func(lv_event_cb_t event_xcb, lv_obj_t * obj, lv_event_t event, const void * data)\n{\n    /* Build a simple linked list from the objects used in the events\n     * It's important to know if an this object was deleted by a nested event\n     * called from this `even_cb`. */\n    lv_event_temp_data_t event_temp_data;\n    event_temp_data.obj     = obj;\n    event_temp_data.deleted = false;\n    event_temp_data.prev    = NULL;\n\n    if(event_temp_data_head) {\n        event_temp_data.prev = event_temp_data_head;\n    }\n    event_temp_data_head = &event_temp_data;\n\n    const void * event_act_data_save = event_act_data;\n    event_act_data                   = data;\n\n    /*Call the input device's feedback callback if set*/\n    lv_indev_t * indev_act = lv_indev_get_act();\n    if(indev_act) {\n        if(indev_act->driver.feedback_cb) indev_act->driver.feedback_cb(&indev_act->driver, event);\n    }\n\n    /*Call the event callback itself*/\n    if(event_xcb) event_xcb(obj, event);\n\n    /*Restore the event data*/\n    event_act_data = event_act_data_save;\n\n    /*Remove this element from the list*/\n    event_temp_data_head = event_temp_data_head->prev;\n\n    if(event_temp_data.deleted) {\n        return LV_RES_INV;\n    }\n\n    if(obj) {\n        if(obj->parent_event && obj->par) {\n            lv_res_t res = lv_event_send(obj->par, event, data);\n            if(res != LV_RES_OK) {\n                return LV_RES_INV;\n            }\n        }\n    }\n\n    return LV_RES_OK;\n}\n\n/**\n * Get the `data` parameter of the current event\n * @return the `data` parameter\n */\nconst void * lv_event_get_data(void)\n{\n    return event_act_data;\n}\n\n/**\n * Set the a signal function of an object. Used internally by the library.\n * Always call the previous signal function in the new.\n * @param obj pointer to an object\n * @param cb the new signal function\n */\nvoid lv_obj_set_signal_cb(lv_obj_t * obj, lv_signal_cb_t signal_cb)\n{\n    obj->signal_cb = signal_cb;\n}\n\n/**\n * Send an event to the object\n * @param obj pointer to an object\n * @param event the type of the event from `lv_event_t`.\n */\nvoid lv_signal_send(lv_obj_t * obj, lv_signal_t signal, void * param)\n{\n    if(obj->signal_cb) obj->signal_cb(obj, signal, param);\n}\n\n/**\n * Set a new design function for an object\n * @param obj pointer to an object\n * @param design_cb the new design function\n */\nvoid lv_obj_set_design_cb(lv_obj_t * obj, lv_design_cb_t design_cb)\n{\n    obj->design_cb = design_cb;\n}\n\n/*----------------\n * Other set\n *--------------*/\n\n/**\n * Allocate a new ext. data for an object\n * @param obj pointer to an object\n * @param ext_size the size of the new ext. data\n * @return Normal pointer to the allocated ext\n */\nvoid * lv_obj_allocate_ext_attr(lv_obj_t * obj, uint16_t ext_size)\n{\n    obj->ext_attr = lv_mem_realloc(obj->ext_attr, ext_size);\n\n    return (void *)obj->ext_attr;\n}\n\n/**\n * Send a 'LV_SIGNAL_REFR_EXT_SIZE' signal to the object\n * @param obj pointer to an object\n */\nvoid lv_obj_refresh_ext_draw_pad(lv_obj_t * obj)\n{\n    obj->ext_draw_pad = 0;\n    obj->signal_cb(obj, LV_SIGNAL_REFR_EXT_DRAW_PAD, NULL);\n\n    lv_obj_invalidate(obj);\n}\n\n/*=======================\n * Getter functions\n *======================*/\n\n/**\n * Return with the screen of an object\n * @param obj pointer to an object\n * @return pointer to a screen\n */\nlv_obj_t * lv_obj_get_screen(const lv_obj_t * obj)\n{\n    const lv_obj_t * par = obj;\n    const lv_obj_t * act_p;\n\n    do {\n        act_p = par;\n        par   = lv_obj_get_parent(act_p);\n    } while(par != NULL);\n\n    return (lv_obj_t *)act_p;\n}\n\n/**\n * Get the display of an object\n * @param scr pointer to an object\n * @return pointer the object's display\n */\nlv_disp_t * lv_obj_get_disp(const lv_obj_t * obj)\n{\n    const lv_obj_t * scr;\n\n    if(obj->par == NULL)\n        scr = obj; /*`obj` is a screen*/\n    else\n        scr = lv_obj_get_screen(obj); /*get the screen of `obj`*/\n\n    lv_disp_t * d;\n    LV_LL_READ(LV_GC_ROOT(_lv_disp_ll), d)\n    {\n        lv_obj_t * s;\n        LV_LL_READ(d->scr_ll, s)\n        {\n            if(s == scr) return d;\n        }\n    }\n\n    LV_LOG_WARN(\"lv_scr_get_disp: screen not found\")\n    return NULL;\n}\n\n/*---------------------\n * Parent/children get\n *--------------------*/\n\n/**\n * Returns with the parent of an object\n * @param obj pointer to an object\n * @return pointer to the parent of  'obj'\n */\nlv_obj_t * lv_obj_get_parent(const lv_obj_t * obj)\n{\n    return obj->par;\n}\n\n/**\n * Iterate through the children of an object (start from the \"youngest\")\n * @param obj pointer to an object\n * @param child NULL at first call to get the next children\n *                  and the previous return value later\n * @return the child after 'act_child' or NULL if no more child\n */\nlv_obj_t * lv_obj_get_child(const lv_obj_t * obj, const lv_obj_t * child)\n{\n    lv_obj_t * result = NULL;\n\n    if(child == NULL) {\n        result = lv_ll_get_head(&obj->child_ll);\n    } else {\n        result = lv_ll_get_next(&obj->child_ll, child);\n    }\n\n    return result;\n}\n\n/**\n * Iterate through the children of an object (start from the \"oldest\")\n * @param obj pointer to an object\n * @param child NULL at first call to get the next children\n *                  and the previous return value later\n * @return the child after 'act_child' or NULL if no more child\n */\nlv_obj_t * lv_obj_get_child_back(const lv_obj_t * obj, const lv_obj_t * child)\n{\n    lv_obj_t * result = NULL;\n\n    if(child == NULL) {\n        result = lv_ll_get_tail(&obj->child_ll);\n    } else {\n        result = lv_ll_get_prev(&obj->child_ll, child);\n    }\n\n    return result;\n}\n\n/**\n * Count the children of an object (only children directly on 'obj')\n * @param obj pointer to an object\n * @return children number of 'obj'\n */\nuint16_t lv_obj_count_children(const lv_obj_t * obj)\n{\n    lv_obj_t * i;\n    uint16_t cnt = 0;\n\n    LV_LL_READ(obj->child_ll, i) cnt++;\n\n    return cnt;\n}\n\n/** Recursively count the children of an object\n * @param obj pointer to an object\n * @return children number of 'obj'\n */\nuint16_t lv_obj_count_children_recursive(const lv_obj_t * obj)\n{\n    lv_obj_t * i;\n    uint16_t cnt = 0;\n\n    LV_LL_READ(obj->child_ll, i)\n    {\n        cnt++;                                     /*Count the child*/\n        cnt += lv_obj_count_children_recursive(i); /*recursively count children's children*/\n    }\n\n    return cnt;\n}\n\n/*---------------------\n * Coordinate get\n *--------------------*/\n\n/**\n * Copy the coordinates of an object to an area\n * @param obj pointer to an object\n * @param cords_p pointer to an area to store the coordinates\n */\nvoid lv_obj_get_coords(const lv_obj_t * obj, lv_area_t * cords_p)\n{\n    lv_area_copy(cords_p, &obj->coords);\n}\n\n/**\n * Reduce area retried by `lv_obj_get_coords()` the get graphically usable area of an object.\n * (Without the size of the border or other extra graphical elements)\n * @param coords_p store the result area here\n */\nvoid lv_obj_get_inner_coords(const lv_obj_t * obj, lv_area_t * coords_p)\n{\n    const lv_style_t * style = lv_obj_get_style(obj);\n    if(style->body.border.part & LV_BORDER_LEFT) coords_p->x1 += style->body.border.width;\n\n    if(style->body.border.part & LV_BORDER_RIGHT) coords_p->x2 -= style->body.border.width;\n\n    if(style->body.border.part & LV_BORDER_TOP) coords_p->y1 += style->body.border.width;\n\n    if(style->body.border.part & LV_BORDER_BOTTOM) coords_p->y2 -= style->body.border.width;\n}\n\n/**\n * Get the x coordinate of object\n * @param obj pointer to an object\n * @return distance of 'obj' from the left side of its parent\n */\nlv_coord_t lv_obj_get_x(const lv_obj_t * obj)\n{\n    lv_coord_t rel_x;\n    lv_obj_t * parent = lv_obj_get_parent(obj);\n    rel_x             = obj->coords.x1 - parent->coords.x1;\n\n    return rel_x;\n}\n\n/**\n * Get the y coordinate of object\n * @param obj pointer to an object\n * @return distance of 'obj' from the top of its parent\n */\nlv_coord_t lv_obj_get_y(const lv_obj_t * obj)\n{\n    lv_coord_t rel_y;\n    lv_obj_t * parent = lv_obj_get_parent(obj);\n    rel_y             = obj->coords.y1 - parent->coords.y1;\n\n    return rel_y;\n}\n\n/**\n * Get the width of an object\n * @param obj pointer to an object\n * @return the width\n */\nlv_coord_t lv_obj_get_width(const lv_obj_t * obj)\n{\n    return lv_area_get_width(&obj->coords);\n}\n\n/**\n * Get the height of an object\n * @param obj pointer to an object\n * @return the height\n */\nlv_coord_t lv_obj_get_height(const lv_obj_t * obj)\n{\n    return lv_area_get_height(&obj->coords);\n}\n\n/**\n * Get that width reduced by the left and right padding.\n * @param obj pointer to an object\n * @return the width which still fits into the container\n */\nlv_coord_t lv_obj_get_width_fit(lv_obj_t * obj)\n{\n    const lv_style_t * style = lv_obj_get_style(obj);\n\n    return lv_obj_get_width(obj) - style->body.padding.left - style->body.padding.right;\n}\n\n/**\n * Get that height reduced by the top an bottom padding.\n * @param obj pointer to an object\n * @return the height which still fits into the container\n */\nlv_coord_t lv_obj_get_height_fit(lv_obj_t * obj)\n{\n    const lv_style_t * style = lv_obj_get_style(obj);\n\n    return lv_obj_get_height(obj) - style->body.padding.top - style->body.padding.bottom;\n}\n\n/**\n * Get the automatic realign property of the object.\n * @param obj pointer to an object\n * @return  true: auto realign is enabled; false: auto realign is disabled\n */\nbool lv_obj_get_auto_realign(lv_obj_t * obj)\n{\n#if LV_USE_OBJ_REALIGN\n    return obj->realign.auto_realign ? true : false;\n#else\n    (void)obj;\n    return false;\n#endif\n}\n\n/**\n * Get the left padding of extended clickable area\n * @param obj pointer to an object\n * @return the extended left padding\n */\nlv_coord_t lv_obj_get_ext_click_pad_left(const lv_obj_t * obj)\n{\n#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY\n    return obj->ext_click_pad_hor;\n#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL\n    return obj->ext_click_pad.x1;\n#else\n    (void)obj;    /*Unused*/\n    return 0;\n#endif\n}\n\n/**\n * Get the right padding of extended clickable area\n * @param obj pointer to an object\n * @return the extended right padding\n */\nlv_coord_t lv_obj_get_ext_click_pad_right(const lv_obj_t * obj)\n{\n#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY\n    return obj->ext_click_pad_hor;\n#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL\n    return obj->ext_click_pad.x2;\n#else\n    (void)obj; /*Unused*/\n    return 0;\n#endif\n}\n\n/**\n * Get the top padding of extended clickable area\n * @param obj pointer to an object\n * @return the extended top padding\n */\nlv_coord_t lv_obj_get_ext_click_pad_top(const lv_obj_t * obj)\n{\n#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY\n    return obj->ext_click_pad_ver;\n#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL\n    return obj->ext_click_pad.y1;\n#else\n    (void)obj; /*Unused*/\n    return 0;\n#endif\n}\n\n/**\n * Get the bottom padding of extended clickable area\n * @param obj pointer to an object\n * @return the extended bottom padding\n */\nlv_coord_t lv_obj_get_ext_click_pad_bottom(const lv_obj_t * obj)\n{\n#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_TINY\n    return obj->ext_click_pad_ver\n#elif LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL\n    return obj->ext_click_pad.y2;\n#else\n    (void)obj; /*Unused*/\n    return 0;\n#endif\n}\n\n/**\n * Get the extended size attribute of an object\n * @param obj pointer to an object\n * @return the extended size attribute\n */\nlv_coord_t lv_obj_get_ext_draw_pad(const lv_obj_t * obj)\n{\n    return obj->ext_draw_pad;\n}\n\n/*-----------------\n * Appearance get\n *---------------*/\n\n/**\n * Get the style pointer of an object (if NULL get style of the parent)\n * @param obj pointer to an object\n * @return pointer to a style\n */\nconst lv_style_t * lv_obj_get_style(const lv_obj_t * obj)\n{\n    const lv_style_t * style_act = obj->style_p;\n    if(style_act == NULL) {\n        lv_obj_t * par = obj->par;\n\n        while(par) {\n            if(par->style_p) {\n                if(par->style_p->glass == 0) {\n#if LV_USE_GROUP == 0\n                    style_act = par->style_p;\n#else\n                    /*If a parent is focused then use then focused style*/\n                    lv_group_t * g = lv_obj_get_group(par);\n                    if(lv_group_get_focused(g) == par) {\n                        style_act = lv_group_mod_style(g, par->style_p);\n                    } else {\n                        style_act = par->style_p;\n                    }\n#endif\n                    break;\n                }\n            }\n            par = par->par;\n        }\n    }\n#if LV_USE_GROUP\n    if(obj->group_p) {\n        if(lv_group_get_focused(obj->group_p) == obj) {\n            style_act = lv_group_mod_style(obj->group_p, style_act);\n        }\n    }\n#endif\n\n    if(style_act == NULL) style_act = &lv_style_plain;\n\n    return style_act;\n}\n\n/*-----------------\n * Attribute get\n *----------------*/\n\n/**\n * Get the hidden attribute of an object\n * @param obj pointer to an object\n * @return true: the object is hidden\n */\nbool lv_obj_get_hidden(const lv_obj_t * obj)\n{\n    return obj->hidden == 0 ? false : true;\n}\n\n/**\n * Get the click enable attribute of an object\n * @param obj pointer to an object\n * @return true: the object is clickable\n */\nbool lv_obj_get_click(const lv_obj_t * obj)\n{\n    return obj->click == 0 ? false : true;\n}\n\n/**\n * Get the top enable attribute of an object\n * @param obj pointer to an object\n * @return true: the auto top feture is enabled\n */\nbool lv_obj_get_top(const lv_obj_t * obj)\n{\n    return obj->top == 0 ? false : true;\n}\n\n/**\n * Get the drag enable attribute of an object\n * @param obj pointer to an object\n * @return true: the object is dragable\n */\nbool lv_obj_get_drag(const lv_obj_t * obj)\n{\n    return obj->drag == 0 ? false : true;\n}\n\n/**\n * Get the directions an object can be dragged\n * @param obj pointer to an object\n * @return bitwise OR of allowed directions an object can be dragged in\n */\nlv_drag_dir_t lv_obj_get_drag_dir(const lv_obj_t * obj)\n{\n    return obj->drag_dir;\n}\n\n/**\n * Get the drag throw enable attribute of an object\n * @param obj pointer to an object\n * @return true: drag throw is enabled\n */\nbool lv_obj_get_drag_throw(const lv_obj_t * obj)\n{\n    return obj->drag_throw == 0 ? false : true;\n}\n\n/**\n * Get the drag parent attribute of an object\n * @param obj pointer to an object\n * @return true: drag parent is enabled\n */\nbool lv_obj_get_drag_parent(const lv_obj_t * obj)\n{\n    return obj->drag_parent == 0 ? false : true;\n}\n\n/**\n * Get the drag parent attribute of an object\n * @param obj pointer to an object\n * @return true: drag parent is enabled\n */\nbool lv_obj_get_parent_event(const lv_obj_t * obj)\n{\n    return obj->parent_event == 0 ? false : true;\n}\n\n/**\n * Get the opa scale enable parameter\n * @param obj pointer to an object\n * @return true: opa scaling is enabled for this object and all children; false: no opa scaling\n */\nlv_opa_t lv_obj_get_opa_scale_enable(const lv_obj_t * obj)\n{\n    return obj->opa_scale_en == 0 ? false : true;\n}\n\n/**\n * Get the opa scale parameter of an object\n * @param obj pointer to an object\n * @return opa scale [0..255]\n */\nlv_opa_t lv_obj_get_opa_scale(const lv_obj_t * obj)\n{\n    const lv_obj_t * parent = obj;\n\n    while(parent) {\n        if(parent->opa_scale_en) return parent->opa_scale;\n        parent = lv_obj_get_parent(parent);\n    }\n\n    return LV_OPA_COVER;\n}\n\n/**\n * Get the protect field of an object\n * @param obj pointer to an object\n * @return protect field ('OR'ed values of `lv_protect_t`)\n */\nuint8_t lv_obj_get_protect(const lv_obj_t * obj)\n{\n    return obj->protect;\n}\n\n/**\n * Check at least one bit of a given protect bitfield is set\n * @param obj pointer to an object\n * @param prot protect bits to test ('OR'ed values of `lv_protect_t`)\n * @return false: none of the given bits are set, true: at least one bit is set\n */\nbool lv_obj_is_protected(const lv_obj_t * obj, uint8_t prot)\n{\n    return (obj->protect & prot) == 0 ? false : true;\n}\n\n/**\n * Get the signal function of an object\n * @param obj pointer to an object\n * @return the signal function\n */\nlv_signal_cb_t lv_obj_get_signal_cb(const lv_obj_t * obj)\n{\n    return obj->signal_cb;\n}\n\n/**\n * Get the design function of an object\n * @param obj pointer to an object\n * @return the design function\n */\nlv_design_cb_t lv_obj_get_design_cb(const lv_obj_t * obj)\n{\n    return obj->design_cb;\n}\n\n/**\n * Get the event function of an object\n * @param obj pointer to an object\n * @return the event function\n */\nlv_event_cb_t lv_obj_get_event_cb(const lv_obj_t * obj)\n{\n    return obj->event_cb;\n}\n\n/*------------------\n * Other get\n *-----------------*/\n\n/**\n * Get the ext pointer\n * @param obj pointer to an object\n * @return the ext pointer but not the dynamic version\n *         Use it as ext->data1, and NOT da(ext)->data1\n */\nvoid * lv_obj_get_ext_attr(const lv_obj_t * obj)\n{\n    return obj->ext_attr;\n}\n\n/**\n * Get object's and its ancestors type. Put their name in `type_buf` starting with the current type.\n * E.g. buf.type[0]=\"lv_btn\", buf.type[1]=\"lv_cont\", buf.type[2]=\"lv_obj\"\n * @param obj pointer to an object which type should be get\n * @param buf pointer to an `lv_obj_type_t` buffer to store the types\n */\nvoid lv_obj_get_type(lv_obj_t * obj, lv_obj_type_t * buf)\n{\n    lv_obj_type_t tmp;\n\n    memset(buf, 0, sizeof(lv_obj_type_t));\n    memset(&tmp, 0, sizeof(lv_obj_type_t));\n\n    obj->signal_cb(obj, LV_SIGNAL_GET_TYPE, &tmp);\n\n    uint8_t cnt;\n    for(cnt = 0; cnt < LV_MAX_ANCESTOR_NUM; cnt++) {\n        if(tmp.type[cnt] == NULL) break;\n    }\n\n    /*Swap the order. The real type comes first*/\n    uint8_t i;\n    for(i = 0; i < cnt; i++) {\n        buf->type[i] = tmp.type[cnt - 1 - i];\n    }\n}\n\n#if LV_USE_USER_DATA\n\n/**\n * Get the object's user data\n * @param obj pointer to an object\n * @return user data\n */\nlv_obj_user_data_t lv_obj_get_user_data(lv_obj_t * obj)\n{\n    return obj->user_data;\n}\n\n/**\n * Get a pointer to the object's user data\n * @param obj pointer to an object\n * @return pointer to the user data\n */\nlv_obj_user_data_t * lv_obj_get_user_data_ptr(lv_obj_t * obj)\n{\n    return &obj->user_data;\n}\n\n/**\n * Set the object's user data. The data will be copied.\n * @param obj pointer to an object\n * @param data user data\n */\nvoid lv_obj_set_user_data(lv_obj_t * obj, lv_obj_user_data_t data)\n{\n    memcpy(&obj->user_data, &data, sizeof(lv_obj_user_data_t));\n}\n#endif\n\n#if LV_USE_GROUP\n/**\n * Get the group of the object\n * @param obj pointer to an object\n * @return the pointer to group of the object\n */\nvoid * lv_obj_get_group(const lv_obj_t * obj)\n{\n    return obj->group_p;\n}\n\n/**\n * Tell whether the object is the focused object of a group or not.\n * @param obj pointer to an object\n * @return true: the object is focused, false: the object is not focused or not in a group\n */\nbool lv_obj_is_focused(const lv_obj_t * obj)\n{\n    if(obj->group_p) {\n        if(lv_group_get_focused(obj->group_p) == obj) return true;\n    }\n\n    return false;\n}\n#endif\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\nstatic void lv_obj_del_async_cb(void * obj)\n{\n    lv_obj_del(obj);\n}\n\n/**\n * Handle the drawing related tasks of the base objects.\n * @param obj pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_obj_design(lv_obj_t * obj, const lv_area_t * mask_p, lv_design_mode_t mode)\n{\n    if(mode == LV_DESIGN_COVER_CHK) {\n\n        /*Most trivial test. Is the mask fully IN the object? If no it surely doesn't cover it*/\n        if(lv_area_is_in(mask_p, &obj->coords) == false) return false;\n\n        /*Can cover the area only if fully solid (no opacity)*/\n        const lv_style_t * style = lv_obj_get_style(obj);\n        if(style->body.opa < LV_OPA_MAX) return false;\n\n        /* Because of the radius it is not sure the area is covered\n         * Check the areas where there is no radius*/\n        lv_coord_t r = style->body.radius;\n\n        if(r == LV_RADIUS_CIRCLE) return false;\n\n        lv_area_t area_tmp;\n\n        /*Check horizontally without radius*/\n        lv_obj_get_coords(obj, &area_tmp);\n        area_tmp.x1 += r;\n        area_tmp.x2 -= r;\n        if(lv_area_is_in(mask_p, &area_tmp) == false) return false;\n\n        /*Check vertically without radius*/\n        lv_obj_get_coords(obj, &area_tmp);\n        area_tmp.y1 += r;\n        area_tmp.y2 -= r;\n        if(lv_area_is_in(mask_p, &area_tmp) == false) return false;\n\n    } else if(mode == LV_DESIGN_DRAW_MAIN) {\n        const lv_style_t * style = lv_obj_get_style(obj);\n        lv_draw_rect(&obj->coords, mask_p, style, lv_obj_get_opa_scale(obj));\n    }\n\n    return true;\n}\n\n/**\n * Signal function of the basic object\n * @param obj pointer to an object\n * @param sign signal type\n * @param param parameter for the signal (depends on signal type)\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)\n{\n    (void)param;\n\n    lv_res_t res = LV_RES_OK;\n\n    const lv_style_t * style = lv_obj_get_style(obj);\n\n    if(sign == LV_SIGNAL_CHILD_CHG) {\n        /*Return 'invalid' if the child change signal is not enabled*/\n        if(lv_obj_is_protected(obj, LV_PROTECT_CHILD_CHG) != false) res = LV_RES_INV;\n    } else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {\n        if(style->body.shadow.width > obj->ext_draw_pad) obj->ext_draw_pad = style->body.shadow.width;\n    } else if(sign == LV_SIGNAL_STYLE_CHG) {\n        lv_obj_refresh_ext_draw_pad(obj);\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        buf->type[0]        = \"lv_obj\";\n    }\n\n    return res;\n}\n\n/**\n * Reposition the children of an object. (Called recursively)\n * @param obj pointer to an object which children will be repositioned\n * @param x_diff x coordinate shift\n * @param y_diff y coordinate shift\n */\nstatic void refresh_children_position(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff)\n{\n    lv_obj_t * i;\n    LV_LL_READ(obj->child_ll, i)\n    {\n        i->coords.x1 += x_diff;\n        i->coords.y1 += y_diff;\n        i->coords.x2 += x_diff;\n        i->coords.y2 += y_diff;\n\n        refresh_children_position(i, x_diff, y_diff);\n    }\n}\n\n/**\n * Refresh the style of all children of an object. (Called recursively)\n * @param style_p refresh objects only with this style.\n * @param obj pointer to an object\n */\nstatic void report_style_mod_core(void * style_p, lv_obj_t * obj)\n{\n    lv_obj_t * i;\n    LV_LL_READ(obj->child_ll, i)\n    {\n        if(i->style_p == style_p || style_p == NULL) {\n            refresh_children_style(i);\n            lv_obj_refresh_style(i);\n        }\n\n        report_style_mod_core(style_p, i);\n    }\n}\n\n/**\n * Recursively refresh the style of the children. Go deeper until a not NULL style is found\n * because the NULL styles are inherited from the parent\n * @param obj pointer to an object\n */\nstatic void refresh_children_style(lv_obj_t * obj)\n{\n    lv_obj_t * child = lv_obj_get_child(obj, NULL);\n    while(child != NULL) {\n        if(child->style_p == NULL) {\n            refresh_children_style(child); /*Check children too*/\n            lv_obj_refresh_style(child);   /*Notify the child about the style change*/\n        } else if(child->style_p->glass) {\n            /*Children with 'glass' parent might be effected if their style == NULL*/\n            refresh_children_style(child);\n        }\n        child = lv_obj_get_child(obj, child);\n    }\n}\n\n/**\n * Called by 'lv_obj_del' to delete the children objects\n * @param obj pointer to an object (all of its children will be deleted)\n */\nstatic void delete_children(lv_obj_t * obj)\n{\n    lv_obj_t * i;\n    lv_obj_t * i_next;\n    i = lv_ll_get_head(&(obj->child_ll));\n\n    /*Remove from the group; remove before transversing children so that\n     * the object still has access to all children during the\n     * LV_SIGNAL_DEFOCUS call*/\n#if LV_USE_GROUP\n    lv_group_t * group = lv_obj_get_group(obj);\n    if(group) lv_group_remove_obj(obj);\n#endif\n\n    while(i != NULL) {\n        /*Get the next object before delete this*/\n        i_next = lv_ll_get_next(&(obj->child_ll), i);\n\n        /*Call the recursive del to the child too*/\n        delete_children(i);\n\n        /*Set i to the next node*/\n        i = i_next;\n    }\n\n    /*Let the suer free the resources used in `LV_EVENT_DELETE`*/\n    lv_event_send(obj, LV_EVENT_DELETE, NULL);\n\n    lv_event_mark_deleted(obj);\n\n    /*Remove the animations from this object*/\n#if LV_USE_ANIMATION\n    lv_anim_del(obj, NULL);\n#endif\n\n    /* Reset the input devices if\n     * the object to delete is used*/\n    lv_indev_t * indev = lv_indev_get_next(NULL);\n    while(indev) {\n        if(indev->proc.types.pointer.act_obj == obj || indev->proc.types.pointer.last_obj == obj) {\n            lv_indev_reset(indev);\n        }\n\n        if(indev->proc.types.pointer.last_pressed == obj) {\n            indev->proc.types.pointer.last_pressed = NULL;\n        }\n#if LV_USE_GROUP\n        if(indev->group == group && obj == lv_indev_get_obj_act()) {\n            lv_indev_reset(indev);\n        }\n#endif\n        indev = lv_indev_get_next(indev);\n    }\n\n    /*Remove the object from parent's children list*/\n    lv_obj_t * par = lv_obj_get_parent(obj);\n    lv_ll_rem(&(par->child_ll), obj);\n\n    /* Clean up the object specific data*/\n    obj->signal_cb(obj, LV_SIGNAL_CLEANUP, NULL);\n\n    /*Delete the base objects*/\n    if(obj->ext_attr != NULL) lv_mem_free(obj->ext_attr);\n    lv_mem_free(obj); /*Free the object itself*/\n}\n\nstatic void lv_event_mark_deleted(lv_obj_t * obj)\n{\n    lv_event_temp_data_t * t = event_temp_data_head;\n\n    while(t) {\n        if(t->obj == obj) t->deleted = true;\n        t = t->prev;\n    }\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_core/lv_refr.c",
    "content": "/**\n * @file lv_refr.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include <stddef.h>\n#include \"libs/lvgl/lv_core/lv_refr.h\"\n#include \"libs/lvgl/lv_core/lv_disp.h\"\n#include \"libs/lvgl/lv_hal/lv_hal_tick.h\"\n#include \"libs/lvgl/lv_hal/lv_hal_disp.h\"\n#include \"libs/lvgl/lv_misc/lv_task.h\"\n#include \"libs/lvgl/lv_misc/lv_mem.h\"\n#include \"libs/lvgl/lv_misc/lv_gc.h\"\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n\n#if defined(LV_GC_INCLUDE)\n#include LV_GC_INCLUDE\n#endif /* LV_ENABLE_GC */\n\n/*********************\n *      DEFINES\n *********************/\n/* Draw translucent random colored areas on the invalidated (redrawn) areas*/\n#define MASK_AREA_DEBUG 0\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic void lv_refr_join_area(void);\nstatic void lv_refr_areas(void);\nstatic void lv_refr_area(const lv_area_t * area_p);\nstatic void lv_refr_area_part(const lv_area_t * area_p);\nstatic lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj);\nstatic void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p);\nstatic void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p);\nstatic void lv_refr_vdb_flush(void);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic uint32_t px_num;\nstatic lv_disp_t * disp_refr; /*Display being refreshed*/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Initialize the screen refresh subsystem\n */\nvoid lv_refr_init(void)\n{\n    /*Nothing to do*/\n}\n\n/**\n * Redraw the invalidated areas now.\n * Normally the redrawing is periodically executed in `lv_task_handler` but a long blocking process\n * can prevent the call of `lv_task_handler`. In this case if the the GUI is updated in the process\n * (e.g. progress bar) this function can be called when the screen should be updated.\n * @param disp pointer to display to refresh. NULL to refresh all displays.\n */\nvoid lv_refr_now(lv_disp_t * disp)\n{\n    if(disp) {\n        lv_disp_refr_task(disp->refr_task);\n    } else {\n        lv_disp_t * d;\n        d = lv_disp_get_next(NULL);\n        while(d) {\n            lv_disp_refr_task(d->refr_task);\n            d = lv_disp_get_next(d);\n        }\n    }\n}\n\n/**\n * Invalidate an area on display to redraw it\n * @param area_p pointer to area which should be invalidated (NULL: delete the invalidated areas)\n * @param disp pointer to display where the area should be invalidated (NULL can be used if there is\n * only one display)\n */\nvoid lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p)\n{\n    if(!disp) disp = lv_disp_get_default();\n    if(!disp) return;\n\n    /*Clear the invalidate buffer if the parameter is NULL*/\n    if(area_p == NULL) {\n        disp->inv_p = 0;\n        return;\n    }\n\n    lv_area_t scr_area;\n    scr_area.x1 = 0;\n    scr_area.y1 = 0;\n    scr_area.x2 = lv_disp_get_hor_res(disp) - 1;\n    scr_area.y2 = lv_disp_get_ver_res(disp) - 1;\n\n    lv_area_t com_area;\n    bool suc;\n\n    suc = lv_area_intersect(&com_area, area_p, &scr_area);\n\n    /*The area is truncated to the screen*/\n    if(suc != false) {\n        if(disp->driver.rounder_cb) disp->driver.rounder_cb(&disp->driver, &com_area);\n\n        /*Save only if this area is not in one of the saved areas*/\n        uint16_t i;\n        for(i = 0; i < disp->inv_p; i++) {\n            if(lv_area_is_in(&com_area, &disp->inv_areas[i]) != false) return;\n        }\n\n        /*Save the area*/\n        if(disp->inv_p < LV_INV_BUF_SIZE) {\n            lv_area_copy(&disp->inv_areas[disp->inv_p], &com_area);\n        } else { /*If no place for the area add the screen*/\n            disp->inv_p = 0;\n            lv_area_copy(&disp->inv_areas[disp->inv_p], &scr_area);\n        }\n        disp->inv_p++;\n    }\n}\n\n/**\n * Get the display which is being refreshed\n * @return the display being refreshed\n */\nlv_disp_t * lv_refr_get_disp_refreshing(void)\n{\n    return disp_refr;\n}\n\n/**\n * Set the display which is being refreshed.\n * It shouldn1t be used directly by the user.\n * It can be used to trick the drawing functions about there is an active display.\n * @param the display being refreshed\n */\nvoid lv_refr_set_disp_refreshing(lv_disp_t * disp)\n{\n    disp_refr = disp;\n}\n\n/**\n * Called periodically to handle the refreshing\n * @param task pointer to the task itself\n */\nvoid lv_disp_refr_task(lv_task_t * task)\n{\n    LV_LOG_TRACE(\"lv_refr_task: started\");\n\n    uint32_t start = lv_tick_get();\n\n    disp_refr = task->user_data;\n\n    lv_refr_join_area();\n\n    lv_refr_areas();\n\n    /*If refresh happened ...*/\n    if(disp_refr->inv_p != 0) {\n        /*In true double buffered mode copy the refreshed areas to the new VDB to keep it up to\n         * date*/\n        if(lv_disp_is_true_double_buf(disp_refr)) {\n            lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);\n\n            /*Flush the content of the VDB*/\n            lv_refr_vdb_flush();\n\n            /* With true double buffering the flushing should be only the address change of the\n             * current frame buffer. Wait until the address change is ready and copy the changed\n             * content to the other frame buffer (new active VDB) to keep the buffers synchronized*/\n            while(vdb->flushing)\n                ;\n\n            uint8_t * buf_act = (uint8_t *)vdb->buf_act;\n            uint8_t * buf_ina = (uint8_t *)vdb->buf_act == vdb->buf1 ? vdb->buf2 : vdb->buf1;\n\n            lv_coord_t hres = lv_disp_get_hor_res(disp_refr);\n            uint16_t a;\n            for(a = 0; a < disp_refr->inv_p; a++) {\n                if(disp_refr->inv_area_joined[a] == 0) {\n                    lv_coord_t y;\n                    uint32_t start_offs =\n                        (hres * disp_refr->inv_areas[a].y1 + disp_refr->inv_areas[a].x1) * sizeof(lv_color_t);\n                    uint32_t line_length = lv_area_get_width(&disp_refr->inv_areas[a]) * sizeof(lv_color_t);\n\n                    for(y = disp_refr->inv_areas[a].y1; y <= disp_refr->inv_areas[a].y2; y++) {\n                        memcpy(buf_act + start_offs, buf_ina + start_offs, line_length);\n                        start_offs += hres * sizeof(lv_color_t);\n                    }\n                }\n            }\n        } /*End of true double buffer handling*/\n\n        /*Clean up*/\n        memset(disp_refr->inv_areas, 0, sizeof(disp_refr->inv_areas));\n        memset(disp_refr->inv_area_joined, 0, sizeof(disp_refr->inv_area_joined));\n        disp_refr->inv_p = 0;\n\n        /*Call monitor cb if present*/\n        if(disp_refr->driver.monitor_cb) {\n            disp_refr->driver.monitor_cb(&disp_refr->driver, lv_tick_elaps(start), px_num);\n        }\n    }\n\n    lv_draw_free_buf();\n\n    LV_LOG_TRACE(\"lv_refr_task: ready\");\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Join the areas which has got common parts\n */\nstatic void lv_refr_join_area(void)\n{\n    uint32_t join_from;\n    uint32_t join_in;\n    lv_area_t joined_area;\n    for(join_in = 0; join_in < disp_refr->inv_p; join_in++) {\n        if(disp_refr->inv_area_joined[join_in] != 0) continue;\n\n        /*Check all areas to join them in 'join_in'*/\n        for(join_from = 0; join_from < disp_refr->inv_p; join_from++) {\n            /*Handle only unjoined areas and ignore itself*/\n            if(disp_refr->inv_area_joined[join_from] != 0 || join_in == join_from) {\n                continue;\n            }\n\n            /*Check if the areas are on each other*/\n            if(lv_area_is_on(&disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]) == false) {\n                continue;\n            }\n\n            lv_area_join(&joined_area, &disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]);\n\n            /*Join two area only if the joined area size is smaller*/\n            if(lv_area_get_size(&joined_area) < (lv_area_get_size(&disp_refr->inv_areas[join_in]) +\n                                                 lv_area_get_size(&disp_refr->inv_areas[join_from]))) {\n                lv_area_copy(&disp_refr->inv_areas[join_in], &joined_area);\n\n                /*Mark 'join_form' is joined into 'join_in'*/\n                disp_refr->inv_area_joined[join_from] = 1;\n            }\n        }\n    }\n}\n\n/**\n * Refresh the joined areas\n */\nstatic void lv_refr_areas(void)\n{\n    px_num = 0;\n    uint32_t i;\n\n    for(i = 0; i < disp_refr->inv_p; i++) {\n        /*Refresh the unjoined areas*/\n        if(disp_refr->inv_area_joined[i] == 0) {\n\n            lv_refr_area(&disp_refr->inv_areas[i]);\n\n            if(disp_refr->driver.monitor_cb) px_num += lv_area_get_size(&disp_refr->inv_areas[i]);\n        }\n    }\n}\n\n/**\n * Refresh an area if there is Virtual Display Buffer\n * @param area_p  pointer to an area to refresh\n */\nstatic void lv_refr_area(const lv_area_t * area_p)\n{\n    /*True double buffering: there are two screen sized buffers. Just redraw directly into a\n     * buffer*/\n    if(lv_disp_is_true_double_buf(disp_refr)) {\n        lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);\n        vdb->area.x1        = 0;\n        vdb->area.x2        = lv_disp_get_hor_res(disp_refr) - 1;\n        vdb->area.y1        = 0;\n        vdb->area.y2        = lv_disp_get_ver_res(disp_refr) - 1;\n        lv_refr_area_part(area_p);\n    }\n    /*The buffer is smaller: refresh the area in parts*/\n    else {\n        lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);\n        /*Calculate the max row num*/\n        lv_coord_t w = lv_area_get_width(area_p);\n        lv_coord_t h = lv_area_get_height(area_p);\n        lv_coord_t y2 =\n            area_p->y2 >= lv_disp_get_ver_res(disp_refr) ? y2 = lv_disp_get_ver_res(disp_refr) - 1 : area_p->y2;\n\n        int32_t max_row = (uint32_t)vdb->size / w;\n\n        if(max_row > h) max_row = h;\n\n        /*Round down the lines of VDB if rounding is added*/\n        if(disp_refr->driver.rounder_cb) {\n            lv_area_t tmp;\n            tmp.x1 = 0;\n            tmp.x2 = 0;\n            tmp.y1 = 0;\n\n            lv_coord_t y_tmp = max_row - 1;\n            do {\n                tmp.y2 = y_tmp;\n                disp_refr->driver.rounder_cb(&disp_refr->driver, &tmp);\n\n                /*If this height fits into `max_row` then fine*/\n                if(lv_area_get_height(&tmp) <= max_row) break;\n\n                /*Decrement the height of the area until it fits into `max_row` after rounding*/\n                y_tmp--;\n            } while(y_tmp != 0);\n\n            if(y_tmp == 0) {\n                LV_LOG_WARN(\"Can't set VDB height using the round function. (Wrong round_cb or to \"\n                            \"small VDB)\");\n                return;\n            } else {\n                max_row = tmp.y2 + 1;\n            }\n        }\n\n        /*Always use the full row*/\n        lv_coord_t row;\n        lv_coord_t row_last = 0;\n        for(row = area_p->y1; row + max_row - 1 <= y2; row += max_row) {\n            /*Calc. the next y coordinates of VDB*/\n            vdb->area.x1 = area_p->x1;\n            vdb->area.x2 = area_p->x2;\n            vdb->area.y1 = row;\n            vdb->area.y2 = row + max_row - 1;\n            if(vdb->area.y2 > y2) vdb->area.y2 = y2;\n            row_last = vdb->area.y2;\n            lv_refr_area_part(area_p);\n        }\n\n        /*If the last y coordinates are not handled yet ...*/\n        if(y2 != row_last) {\n            /*Calc. the next y coordinates of VDB*/\n            vdb->area.x1 = area_p->x1;\n            vdb->area.x2 = area_p->x2;\n            vdb->area.y1 = row;\n            vdb->area.y2 = y2;\n\n            /*Refresh this part too*/\n            lv_refr_area_part(area_p);\n        }\n    }\n}\n\n/**\n * Refresh a part of an area which is on the actual Virtual Display Buffer\n * @param area_p pointer to an area to refresh\n */\nstatic void lv_refr_area_part(const lv_area_t * area_p)\n{\n\n    lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);\n\n    /*In non double buffered mode, before rendering the next part wait until the previous image is\n     * flushed*/\n    if(lv_disp_is_double_buf(disp_refr) == false) {\n        while(vdb->flushing)\n            ;\n    }\n\n    lv_obj_t * top_p;\n\n    /*Get the new mask from the original area and the act. VDB\n     It will be a part of 'area_p'*/\n    lv_area_t start_mask;\n    lv_area_intersect(&start_mask, area_p, &vdb->area);\n\n    /*Get the most top object which is not covered by others*/\n    top_p = lv_refr_get_top_obj(&start_mask, lv_disp_get_scr_act(disp_refr));\n\n    /*Do the refreshing from the top object*/\n    lv_refr_obj_and_children(top_p, &start_mask);\n\n    /*Also refresh top and sys layer unconditionally*/\n    lv_refr_obj_and_children(lv_disp_get_layer_top(disp_refr), &start_mask);\n    lv_refr_obj_and_children(lv_disp_get_layer_sys(disp_refr), &start_mask);\n\n    /* In true double buffered mode flush only once when all areas were rendered.\n     * In normal mode flush after every area */\n    if(lv_disp_is_true_double_buf(disp_refr) == false) {\n        lv_refr_vdb_flush();\n    }\n}\n\n/**\n * Search the most top object which fully covers an area\n * @param area_p pointer to an area\n * @param obj the first object to start the searching (typically a screen)\n * @return\n */\nstatic lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)\n{\n    lv_obj_t * found_p = NULL;\n\n    /*If this object is fully cover the draw area check the children too */\n    if(lv_area_is_in(area_p, &obj->coords) && obj->hidden == 0) {\n        lv_obj_t * i;\n        LV_LL_READ(obj->child_ll, i)\n        {\n            found_p = lv_refr_get_top_obj(area_p, i);\n\n            /*If a children is ok then break*/\n            if(found_p != NULL) {\n                break;\n            }\n        }\n\n        /*If no better children check this object*/\n        if(found_p == NULL) {\n            const lv_style_t * style = lv_obj_get_style(obj);\n            if(style->body.opa == LV_OPA_COVER && obj->design_cb(obj, area_p, LV_DESIGN_COVER_CHK) != false &&\n               lv_obj_get_opa_scale(obj) == LV_OPA_COVER) {\n                found_p = obj;\n            }\n        }\n    }\n\n    return found_p;\n}\n\n/**\n * Make the refreshing from an object. Draw all its children and the youngers too.\n * @param top_p pointer to an objects. Start the drawing from it.\n * @param mask_p pointer to an area, the objects will be drawn only here\n */\nstatic void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p)\n{\n    /* Normally always will be a top_obj (at least the screen)\n     * but in special cases (e.g. if the screen has alpha) it won't.\n     * In this case use the screen directly */\n    if(top_p == NULL) top_p = lv_disp_get_scr_act(disp_refr);\n\n    /*Refresh the top object and its children*/\n    lv_refr_obj(top_p, mask_p);\n\n    /*Draw the 'younger' sibling objects because they can be on top_obj */\n    lv_obj_t * par;\n    lv_obj_t * border_p = top_p;\n\n    par = lv_obj_get_parent(top_p);\n\n    /*Do until not reach the screen*/\n    while(par != NULL) {\n        /*object before border_p has to be redrawn*/\n        lv_obj_t * i = lv_ll_get_prev(&(par->child_ll), border_p);\n\n        while(i != NULL) {\n            /*Refresh the objects*/\n            lv_refr_obj(i, mask_p);\n            i = lv_ll_get_prev(&(par->child_ll), i);\n        }\n\n        /*Call the post draw design function of the parents of the to object*/\n        par->design_cb(par, mask_p, LV_DESIGN_DRAW_POST);\n\n        /*The new border will be there last parents,\n         *so the 'younger' brothers of parent will be refreshed*/\n        border_p = par;\n        /*Go a level deeper*/\n        par = lv_obj_get_parent(par);\n    }\n}\n\n/**\n * Refresh an object an all of its children. (Called recursively)\n * @param obj pointer to an object to refresh\n * @param mask_ori_p pointer to an area, the objects will be drawn only here\n */\nstatic void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)\n{\n    /*Do not refresh hidden objects*/\n    if(obj->hidden != 0) return;\n\n    bool union_ok; /* Store the return value of area_union */\n    /* Truncate the original mask to the coordinates of the parent\n     * because the parent and its children are visible only here */\n    lv_area_t obj_mask;\n    lv_area_t obj_ext_mask;\n    lv_area_t obj_area;\n    lv_coord_t ext_size = obj->ext_draw_pad;\n    lv_obj_get_coords(obj, &obj_area);\n    obj_area.x1 -= ext_size;\n    obj_area.y1 -= ext_size;\n    obj_area.x2 += ext_size;\n    obj_area.y2 += ext_size;\n    union_ok = lv_area_intersect(&obj_ext_mask, mask_ori_p, &obj_area);\n\n    /*Draw the parent and its children only if they ore on 'mask_parent'*/\n    if(union_ok != false) {\n\n        /* Redraw the object */\n        obj->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_MAIN);\n\n#if MASK_AREA_DEBUG\n        static lv_color_t debug_color = LV_COLOR_RED;\n        lv_draw_fill(&obj_ext_mask, &obj_ext_mask, debug_color, LV_OPA_50);\n        debug_color.full *= 17;\n        debug_color.full += 0xA1;\n#endif\n        /*Create a new 'obj_mask' without 'ext_size' because the children can't be visible there*/\n        lv_obj_get_coords(obj, &obj_area);\n        union_ok = lv_area_intersect(&obj_mask, mask_ori_p, &obj_area);\n        if(union_ok != false) {\n            lv_area_t mask_child; /*Mask from obj and its child*/\n            lv_obj_t * child_p;\n            lv_area_t child_area;\n            LV_LL_READ_BACK(obj->child_ll, child_p)\n            {\n                lv_obj_get_coords(child_p, &child_area);\n                ext_size = child_p->ext_draw_pad;\n                child_area.x1 -= ext_size;\n                child_area.y1 -= ext_size;\n                child_area.x2 += ext_size;\n                child_area.y2 += ext_size;\n                /* Get the union (common parts) of original mask (from obj)\n                 * and its child */\n                union_ok = lv_area_intersect(&mask_child, &obj_mask, &child_area);\n\n                /*If the parent and the child has common area then refresh the child */\n                if(union_ok) {\n                    /*Refresh the next children*/\n                    lv_refr_obj(child_p, &mask_child);\n                }\n            }\n        }\n\n        /* If all the children are redrawn make 'post draw' design */\n        obj->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_POST);\n    }\n}\n\n/**\n * Flush the content of the VDB\n */\nstatic void lv_refr_vdb_flush(void)\n{\n    lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);\n\n    /*In double buffered mode wait until the other buffer is flushed before flushing the current\n     * one*/\n    if(lv_disp_is_double_buf(disp_refr)) {\n        while(vdb->flushing)\n            ;\n    }\n\n    vdb->flushing = 1;\n\n    /*Flush the rendered content to the display*/\n    lv_disp_t * disp = lv_refr_get_disp_refreshing();\n    if(disp->driver.flush_cb) disp->driver.flush_cb(&disp->driver, &vdb->area, vdb->buf_act);\n\n    if(vdb->buf1 && vdb->buf2) {\n        if(vdb->buf_act == vdb->buf1)\n            vdb->buf_act = vdb->buf2;\n        else\n            vdb->buf_act = vdb->buf1;\n    }\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_core/lv_style.c",
    "content": "/**\n * @file lv_style.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_core/lv_obj.h\"\n#include \"libs/lvgl/lv_misc/lv_mem.h\"\n#include \"libs/lvgl/lv_misc/lv_anim.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define STYLE_MIX_MAX 256\n#define STYLE_MIX_SHIFT 8 /*log2(STYLE_MIX_MAX)*/\n\n#define VAL_PROP(v1, v2, r) v1 + (((v2 - v1) * r) >> STYLE_MIX_SHIFT)\n#define STYLE_ATTR_MIX(attr, r)                                                                                        \\\n    if(start->attr != end->attr) {                                                                                     \\\n        res->attr = VAL_PROP(start->attr, end->attr, r);                                                               \\\n    } else {                                                                                                           \\\n        res->attr = start->attr;                                                                                       \\\n    }\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n#if LV_USE_ANIMATION\nstatic void style_animator(lv_style_anim_dsc_t * dsc, lv_anim_value_t val);\nstatic void style_animation_common_end_cb(lv_anim_t * a);\n#endif\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nlv_style_t lv_style_scr;\nlv_style_t lv_style_transp;\nlv_style_t lv_style_transp_fit;\nlv_style_t lv_style_transp_tight;\nlv_style_t lv_style_plain;\nlv_style_t lv_style_plain_color;\nlv_style_t lv_style_pretty;\nlv_style_t lv_style_pretty_color;\nlv_style_t lv_style_btn_rel;\nlv_style_t lv_style_btn_pr;\nlv_style_t lv_style_btn_tgl_rel;\nlv_style_t lv_style_btn_tgl_pr;\nlv_style_t lv_style_btn_ina;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n *  Init the basic styles\n */\nvoid lv_style_init(void)\n{\n    /* Not White/Black/Gray colors are created by HSV model with\n     * HUE = 210*/\n\n    /*Screen style*/\n    lv_style_scr.glass               = 0;\n    lv_style_scr.body.opa            = LV_OPA_COVER;\n    lv_style_scr.body.main_color     = LV_COLOR_WHITE;\n    lv_style_scr.body.grad_color     = LV_COLOR_WHITE;\n    lv_style_scr.body.radius         = 0;\n    lv_style_scr.body.padding.left   = 0;\n    lv_style_scr.body.padding.right  = 0;\n    lv_style_scr.body.padding.top    = 0;\n    lv_style_scr.body.padding.bottom = 0;\n    lv_style_scr.body.padding.inner  = LV_DPI / 20;\n\n    lv_style_scr.body.border.color = LV_COLOR_BLACK;\n    lv_style_scr.body.border.opa   = LV_OPA_COVER;\n    lv_style_scr.body.border.width = 0;\n    lv_style_scr.body.border.part  = LV_BORDER_FULL;\n\n    lv_style_scr.body.shadow.color = LV_COLOR_GRAY;\n    lv_style_scr.body.shadow.type  = LV_SHADOW_FULL;\n    lv_style_scr.body.shadow.width = 0;\n\n    lv_style_scr.text.opa          = LV_OPA_COVER;\n    lv_style_scr.text.color        = lv_color_make(0x30, 0x30, 0x30);\n    lv_style_scr.text.sel_color    = lv_color_make(0x55, 0x96, 0xd8);\n    lv_style_scr.text.font         = LV_FONT_DEFAULT;\n    lv_style_scr.text.letter_space = 0;\n    lv_style_scr.text.line_space   = 2;\n\n    lv_style_scr.image.opa     = LV_OPA_COVER;\n    lv_style_scr.image.color   = lv_color_make(0x20, 0x20, 0x20);\n    lv_style_scr.image.intense = LV_OPA_TRANSP;\n\n    lv_style_scr.line.opa     = LV_OPA_COVER;\n    lv_style_scr.line.color   = lv_color_make(0x20, 0x20, 0x20);\n    lv_style_scr.line.width   = 2;\n    lv_style_scr.line.rounded = 0;\n\n    /*Plain style (by default near the same as the screen style)*/\n    lv_style_copy(&lv_style_plain, &lv_style_scr);\n    lv_style_plain.body.padding.left   = LV_DPI / 20;\n    lv_style_plain.body.padding.right  = LV_DPI / 20;\n    lv_style_plain.body.padding.top    = LV_DPI / 20;\n    lv_style_plain.body.padding.bottom = LV_DPI / 20;\n\n    /*Plain color style*/\n    lv_style_copy(&lv_style_plain_color, &lv_style_plain);\n    lv_style_plain_color.text.color      = lv_color_make(0xf0, 0xf0, 0xf0);\n    lv_style_plain_color.image.color     = lv_color_make(0xf0, 0xf0, 0xf0);\n    lv_style_plain_color.line.color      = lv_color_make(0xf0, 0xf0, 0xf0);\n    lv_style_plain_color.body.main_color = lv_color_make(0x55, 0x96, 0xd8);\n    lv_style_plain_color.body.grad_color = lv_style_plain_color.body.main_color;\n\n    /*Pretty style */\n    lv_style_copy(&lv_style_pretty, &lv_style_plain);\n    lv_style_pretty.text.color        = lv_color_make(0x20, 0x20, 0x20);\n    lv_style_pretty.image.color       = lv_color_make(0x20, 0x20, 0x20);\n    lv_style_pretty.line.color        = lv_color_make(0x20, 0x20, 0x20);\n    lv_style_pretty.body.main_color   = LV_COLOR_WHITE;\n    lv_style_pretty.body.grad_color   = LV_COLOR_SILVER;\n    lv_style_pretty.body.radius       = LV_DPI / 15;\n    lv_style_pretty.body.border.color = lv_color_make(0x40, 0x40, 0x40);\n    lv_style_pretty.body.border.width = LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1;\n    lv_style_pretty.body.border.opa   = LV_OPA_30;\n\n    /*Pretty color style*/\n    lv_style_copy(&lv_style_pretty_color, &lv_style_pretty);\n    lv_style_pretty_color.text.color        = lv_color_make(0xe0, 0xe0, 0xe0);\n    lv_style_pretty_color.image.color       = lv_color_make(0xe0, 0xe0, 0xe0);\n    lv_style_pretty_color.line.color        = lv_color_make(0xc0, 0xc0, 0xc0);\n    lv_style_pretty_color.body.main_color   = lv_color_make(0x6b, 0x9a, 0xc7);\n    lv_style_pretty_color.body.grad_color   = lv_color_make(0x2b, 0x59, 0x8b);\n    lv_style_pretty_color.body.border.color = lv_color_make(0x15, 0x2c, 0x42);\n\n    /*Transparent style*/\n    lv_style_copy(&lv_style_transp, &lv_style_plain);\n    lv_style_transp.glass             = 1;\n    lv_style_transp.body.border.width = 0;\n    lv_style_transp.body.opa          = LV_OPA_TRANSP;\n\n    /*Transparent fitting size*/\n    lv_style_copy(&lv_style_transp_fit, &lv_style_transp);\n    lv_style_transp_fit.body.padding.left   = 0;\n    lv_style_transp_fit.body.padding.right  = 0;\n    lv_style_transp_fit.body.padding.top    = 0;\n    lv_style_transp_fit.body.padding.bottom = 0;\n\n    /*Transparent tight style*/\n    lv_style_copy(&lv_style_transp_tight, &lv_style_transp_fit);\n    lv_style_transp_tight.body.padding.inner = 0;\n\n    /*Button released style*/\n    lv_style_copy(&lv_style_btn_rel, &lv_style_plain);\n    lv_style_btn_rel.body.main_color     = lv_color_make(0x76, 0xa2, 0xd0);\n    lv_style_btn_rel.body.grad_color     = lv_color_make(0x19, 0x3a, 0x5d);\n    lv_style_btn_rel.body.radius         = LV_DPI / 15;\n    lv_style_btn_rel.body.padding.left   = LV_DPI / 4;\n    lv_style_btn_rel.body.padding.right  = LV_DPI / 4;\n    lv_style_btn_rel.body.padding.top    = LV_DPI / 6;\n    lv_style_btn_rel.body.padding.bottom = LV_DPI / 6;\n    lv_style_btn_rel.body.padding.inner  = LV_DPI / 10;\n    lv_style_btn_rel.body.border.color   = lv_color_make(0x0b, 0x19, 0x28);\n    lv_style_btn_rel.body.border.width   = LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1;\n    lv_style_btn_rel.body.border.opa     = LV_OPA_70;\n    lv_style_btn_rel.body.shadow.color   = LV_COLOR_GRAY;\n    lv_style_btn_rel.body.shadow.width   = 0;\n    lv_style_btn_rel.text.color          = lv_color_make(0xff, 0xff, 0xff);\n    lv_style_btn_rel.image.color         = lv_color_make(0xff, 0xff, 0xff);\n\n    /*Button pressed style*/\n    lv_style_copy(&lv_style_btn_pr, &lv_style_btn_rel);\n    lv_style_btn_pr.body.main_color = lv_color_make(0x33, 0x62, 0x94);\n    lv_style_btn_pr.body.grad_color = lv_color_make(0x10, 0x26, 0x3c);\n    lv_style_btn_pr.text.color      = lv_color_make(0xa4, 0xb5, 0xc6);\n    lv_style_btn_pr.image.color     = lv_color_make(0xa4, 0xb5, 0xc6);\n    lv_style_btn_pr.line.color      = lv_color_make(0xa4, 0xb5, 0xc6);\n\n    /*Button toggle released style*/\n    lv_style_copy(&lv_style_btn_tgl_rel, &lv_style_btn_rel);\n    lv_style_btn_tgl_rel.body.main_color   = lv_color_make(0x0a, 0x11, 0x22);\n    lv_style_btn_tgl_rel.body.grad_color   = lv_color_make(0x37, 0x62, 0x90);\n    lv_style_btn_tgl_rel.body.border.color = lv_color_make(0x01, 0x07, 0x0d);\n    lv_style_btn_tgl_rel.text.color        = lv_color_make(0xc8, 0xdd, 0xf4);\n    lv_style_btn_tgl_rel.image.color       = lv_color_make(0xc8, 0xdd, 0xf4);\n    lv_style_btn_tgl_rel.line.color        = lv_color_make(0xc8, 0xdd, 0xf4);\n\n    /*Button toggle pressed style*/\n    lv_style_copy(&lv_style_btn_tgl_pr, &lv_style_btn_tgl_rel);\n    lv_style_btn_tgl_pr.body.main_color = lv_color_make(0x02, 0x14, 0x27);\n    lv_style_btn_tgl_pr.body.grad_color = lv_color_make(0x2b, 0x4c, 0x70);\n    lv_style_btn_tgl_pr.text.color      = lv_color_make(0xa4, 0xb5, 0xc6);\n    lv_style_btn_tgl_pr.image.color     = lv_color_make(0xa4, 0xb5, 0xc6);\n    lv_style_btn_tgl_pr.line.color      = lv_color_make(0xa4, 0xb5, 0xc6);\n\n    /*Button inactive style*/\n    lv_style_copy(&lv_style_btn_ina, &lv_style_btn_rel);\n    lv_style_btn_ina.body.main_color   = lv_color_make(0xd8, 0xd8, 0xd8);\n    lv_style_btn_ina.body.grad_color   = lv_color_make(0xd8, 0xd8, 0xd8);\n    lv_style_btn_ina.body.border.color = lv_color_make(0x90, 0x90, 0x90);\n    lv_style_btn_ina.text.color        = lv_color_make(0x70, 0x70, 0x70);\n    lv_style_btn_ina.image.color       = lv_color_make(0x70, 0x70, 0x70);\n    lv_style_btn_ina.line.color        = lv_color_make(0x70, 0x70, 0x70);\n}\n\n/**\n * Copy a style to an other\n * @param dest pointer to the destination style\n * @param src pointer to the source style\n */\nvoid lv_style_copy(lv_style_t * dest, const lv_style_t * src)\n{\n    memcpy(dest, src, sizeof(lv_style_t));\n}\n\n/**\n * Mix two styles according to a given ratio\n * @param start start style\n * @param end end style\n * @param res store the result style here\n * @param ratio the ratio of mix [0..256]; 0: `start` style; 256: `end` style\n */\nvoid lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * res, uint16_t ratio)\n{\n    STYLE_ATTR_MIX(body.opa, ratio);\n    STYLE_ATTR_MIX(body.radius, ratio);\n    STYLE_ATTR_MIX(body.border.width, ratio);\n    STYLE_ATTR_MIX(body.border.opa, ratio);\n    STYLE_ATTR_MIX(body.shadow.width, ratio);\n    STYLE_ATTR_MIX(body.padding.left, ratio);\n    STYLE_ATTR_MIX(body.padding.right, ratio);\n    STYLE_ATTR_MIX(body.padding.top, ratio);\n    STYLE_ATTR_MIX(body.padding.bottom, ratio);\n    STYLE_ATTR_MIX(body.padding.inner, ratio);\n    STYLE_ATTR_MIX(text.line_space, ratio);\n    STYLE_ATTR_MIX(text.letter_space, ratio);\n    STYLE_ATTR_MIX(text.opa, ratio);\n    STYLE_ATTR_MIX(line.width, ratio);\n    STYLE_ATTR_MIX(line.opa, ratio);\n    STYLE_ATTR_MIX(image.intense, ratio);\n    STYLE_ATTR_MIX(image.opa, ratio);\n\n    lv_opa_t opa = ratio == STYLE_MIX_MAX ? LV_OPA_COVER : ratio;\n\n    res->body.main_color   = lv_color_mix(end->body.main_color, start->body.main_color, opa);\n    res->body.grad_color   = lv_color_mix(end->body.grad_color, start->body.grad_color, opa);\n    res->body.border.color = lv_color_mix(end->body.border.color, start->body.border.color, opa);\n    res->body.shadow.color = lv_color_mix(end->body.shadow.color, start->body.shadow.color, opa);\n    res->text.color        = lv_color_mix(end->text.color, start->text.color, opa);\n    res->image.color       = lv_color_mix(end->image.color, start->image.color, opa);\n    res->line.color        = lv_color_mix(end->line.color, start->line.color, opa);\n\n    if(ratio < (STYLE_MIX_MAX >> 1)) {\n        res->body.border.part = start->body.border.part;\n        res->glass            = start->glass;\n        res->text.font        = start->text.font;\n        res->body.shadow.type = start->body.shadow.type;\n        res->line.rounded     = start->line.rounded;\n    } else {\n        res->body.border.part = end->body.border.part;\n        res->glass            = end->glass;\n        res->text.font        = end->text.font;\n        res->body.shadow.type = end->body.shadow.type;\n        res->line.rounded     = end->line.rounded;\n    }\n}\n\n#if LV_USE_ANIMATION\n\nvoid lv_style_anim_init(lv_anim_t * a)\n{\n    lv_anim_init(a);\n    a->start    = 0;\n    a->end      = STYLE_MIX_MAX;\n    a->exec_cb  = (lv_anim_exec_xcb_t)style_animator;\n    a->path_cb  = lv_anim_path_linear;\n    a->ready_cb = style_animation_common_end_cb;\n\n    lv_style_anim_dsc_t * dsc;\n    dsc = lv_mem_alloc(sizeof(lv_style_anim_dsc_t));\n    lv_mem_assert(dsc);\n    if(dsc == NULL) return;\n    dsc->ready_cb   = NULL;\n    dsc->style_anim = NULL;\n    lv_style_copy(&dsc->style_start, &lv_style_plain);\n    lv_style_copy(&dsc->style_end, &lv_style_plain);\n\n    a->var = (void *)dsc;\n}\n\nvoid lv_style_anim_set_styles(lv_anim_t * a, lv_style_t * to_anim, const lv_style_t * start, const lv_style_t * end)\n{\n\n    lv_style_anim_dsc_t * dsc = a->var;\n    dsc->style_anim           = to_anim;\n    memcpy(&dsc->style_start, start, sizeof(lv_style_t));\n    memcpy(&dsc->style_end, end, sizeof(lv_style_t));\n    memcpy(dsc->style_anim, start, sizeof(lv_style_t));\n}\n#endif\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n#if LV_USE_ANIMATION\n/**\n * Used by the style animations to set the values of a style according to start and end style.\n * @param dsc the 'animated variable' set by lv_style_anim_create()\n * @param val the current state of the animation between 0 and LV_ANIM_RESOLUTION\n */\nstatic void style_animator(lv_style_anim_dsc_t * dsc, lv_anim_value_t val)\n{\n    const lv_style_t * start = &dsc->style_start;\n    const lv_style_t * end   = &dsc->style_end;\n    lv_style_t * act         = dsc->style_anim;\n\n    lv_style_mix(start, end, act, val);\n\n    lv_obj_report_style_mod(dsc->style_anim);\n}\n\n/**\n * Called when a style animation is ready\n * It called the user defined call back and free the allocated memories\n * @param a pointer to the animation\n */\nstatic void style_animation_common_end_cb(lv_anim_t * a)\n{\n\n    (void)a;                            /*Unused*/\n    lv_style_anim_dsc_t * dsc = a->var; /*To avoid casting*/\n\n    if(dsc->ready_cb) dsc->ready_cb(a);\n\n    lv_mem_free(dsc);\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_draw/lv_draw.c",
    "content": "/**\n * @file lv_draw.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n\n#include <stdio.h>\n#include \"utils/types.h\"\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n#include \"libs/lvgl/lv_misc/lv_log.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n#include \"libs/lvgl/lv_misc/lv_mem.h\"\n#include \"libs/lvgl/lv_misc/lv_gc.h\"\n\n#if defined(LV_GC_INCLUDE)\n#include LV_GC_INCLUDE\n#endif /* LV_ENABLE_GC */\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic uint32_t draw_buf_size = 0;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Give a buffer with the given to use during drawing.\n * Be careful to not use the buffer while other processes are using it.\n * @param size the required size\n */\nvoid * lv_draw_get_buf(uint32_t size)\n{\n    if(size <= draw_buf_size) return LV_GC_ROOT(_lv_draw_buf);\n\n    LV_LOG_TRACE(\"lv_draw_get_buf: allocate\");\n\n    draw_buf_size = size;\n\n    if(LV_GC_ROOT(_lv_draw_buf) == NULL) {\n        LV_GC_ROOT(_lv_draw_buf) = lv_mem_alloc(size);\n        lv_mem_assert(LV_GC_ROOT(_lv_draw_buf));\n        return LV_GC_ROOT(_lv_draw_buf);\n    }\n\n    LV_GC_ROOT(_lv_draw_buf) = lv_mem_realloc(LV_GC_ROOT(_lv_draw_buf), size);\n    lv_mem_assert(LV_GC_ROOT(_lv_draw_buf));\n    return LV_GC_ROOT(_lv_draw_buf);\n}\n\n/**\n * Free the draw buffer\n */\nvoid lv_draw_free_buf(void)\n{\n    if(LV_GC_ROOT(_lv_draw_buf)) {\n        lv_mem_free(LV_GC_ROOT(_lv_draw_buf));\n        LV_GC_ROOT(_lv_draw_buf) = NULL;\n        draw_buf_size = 0;\n    }\n}\n\n#if LV_ANTIALIAS\n\n/**\n * Get the opacity of a pixel based it's position in a line segment\n * @param seg segment length\n * @param px_id position of  of a pixel which opacity should be get [0..seg-1]\n * @param base_opa the base opacity\n * @return the opacity of the given pixel\n */\nlv_opa_t lv_draw_aa_get_opa(lv_coord_t seg, lv_coord_t px_id, lv_opa_t base_opa)\n{\n    /* How to calculate the opacity of pixels on the edges which makes the anti-aliasing?\n     * For example we have a line like this (y = -0.5 * x):\n     *\n     *  | _ _\n     *    * * |\n     *\n     * Anti-aliased pixels come to the '*' characters\n     * Calculate what percentage of the pixels should be covered if real line (not rasterized) would\n     * be drawn:\n     * 1. A real line should start on (0;0) and end on (2;1)\n     * 2. So the line intersection coordinates on the first pixel: (0;0) (1;0.5) -> 25% covered\n     * pixel in average\n     * 3. For the second pixel: (1;0.5) (2;1) -> 75% covered pixel in average\n     * 4. The equation: (px_id * 2 + 1) / (segment_width * 2)\n     *                   segment_width: the line segment which is being anti-aliased (was 2 in the\n     * example) px_id: pixel ID from 0 to  (segment_width - 1) result: [0..1] coverage of the pixel\n     */\n\n    /*Accelerate the common segment sizes to avoid division*/\n    static const lv_opa_t seg1[1] = {128};\n    static const lv_opa_t seg2[2] = {64, 192};\n    static const lv_opa_t seg3[3] = {42, 128, 212};\n    static const lv_opa_t seg4[4] = {32, 96, 159, 223};\n    static const lv_opa_t seg5[5] = {26, 76, 128, 178, 230};\n    static const lv_opa_t seg6[6] = {21, 64, 106, 148, 191, 234};\n    static const lv_opa_t seg7[7] = {18, 55, 91, 128, 164, 200, 237};\n    static const lv_opa_t seg8[8] = {16, 48, 80, 112, 143, 175, 207, 239};\n\n    static const lv_opa_t * seg_map[] = {seg1, seg2, seg3, seg4, seg5, seg6, seg7, seg8};\n\n    if(seg == 0)\n        return LV_OPA_TRANSP;\n    else if(seg < 8)\n        return (uint32_t)((uint32_t)seg_map[seg - 1][px_id] * base_opa) >> 8;\n    else {\n        return ((px_id * 2 + 1) * base_opa) / (2 * seg);\n    }\n}\n\n/**\n * Add a vertical  anti-aliasing segment (pixels with decreasing opacity)\n * @param x start point x coordinate\n * @param y start point y coordinate\n * @param length length of segment (negative value to start from 0 opacity)\n * @param mask draw only in this area\n * @param color color of pixels\n * @param opa maximum opacity\n */\nvoid lv_draw_aa_ver_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask, lv_color_t color,\n                        lv_opa_t opa)\n{\n    bool aa_inv = false;\n    if(length < 0) {\n        aa_inv = true;\n        length = -length;\n    }\n\n    lv_coord_t i;\n    for(i = 0; i < length; i++) {\n        lv_opa_t px_opa = lv_draw_aa_get_opa(length, i, opa);\n        if(aa_inv) px_opa = opa - px_opa;\n        lv_draw_px(x, y + i, mask, color, px_opa);\n    }\n}\n\n/**\n * Add a horizontal anti-aliasing segment (pixels with decreasing opacity)\n * @param x start point x coordinate\n * @param y start point y coordinate\n * @param length length of segment (negative value to start from 0 opacity)\n * @param mask draw only in this area\n * @param color color of pixels\n * @param opa maximum opacity\n */\nvoid lv_draw_aa_hor_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask, lv_color_t color,\n                        lv_opa_t opa)\n{\n    bool aa_inv = false;\n    if(length < 0) {\n        aa_inv = true;\n        length = -length;\n    }\n\n    lv_coord_t i;\n    for(i = 0; i < length; i++) {\n        lv_opa_t px_opa = lv_draw_aa_get_opa(length, i, opa);\n        if(aa_inv) px_opa = opa - px_opa;\n        lv_draw_px(x + i, y, mask, color, px_opa);\n    }\n}\n\n#endif\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_draw/lv_draw.mk",
    "content": "CSRCS += lv_draw_basic.c\nCSRCS += lv_draw.c\nCSRCS += lv_draw_rect.c\nCSRCS += lv_draw_label.c\nCSRCS += lv_draw_line.c\nCSRCS += lv_draw_img.c\nCSRCS += lv_draw_arc.c\nCSRCS += lv_draw_triangle.c\nCSRCS += lv_img_decoder.c\nCSRCS += lv_img_cache.c\n\nDEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_draw\nVPATH += :$(LVGL_DIR)/lvgl/src/lv_draw\n\nCFLAGS += \"-I$(LVGL_DIR)lvgl/src/lv_draw\"\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_draw/lv_draw_arc.c",
    "content": "/**\n * @file lv_draw_arc.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_draw/lv_draw_arc.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic uint16_t fast_atan2(int x, int y);\nstatic void ver_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color,\n                     lv_opa_t opa);\nstatic void hor_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color,\n                     lv_opa_t opa);\nstatic bool deg_test_norm(uint16_t deg, uint16_t start, uint16_t end);\nstatic bool deg_test_inv(uint16_t deg, uint16_t start, uint16_t end);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Draw an arc. (Can draw pie too with great thickness.)\n * @param center_x the x coordinate of the center of the arc\n * @param center_y the y coordinate of the center of the arc\n * @param radius the radius of the arc\n * @param mask the arc will be drawn only in this mask\n * @param start_angle the start angle of the arc (0 deg on the bottom, 90 deg on the right)\n * @param end_angle the end angle of the arc\n * @param style style of the arc (`body.thickness`, `body.main_color`, `body.opa` is used)\n * @param opa_scale scale down all opacities by the factor\n */\nvoid lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, const lv_area_t * mask,\n                 uint16_t start_angle, uint16_t end_angle, const lv_style_t * style, lv_opa_t opa_scale)\n{\n    lv_coord_t thickness = style->line.width;\n    if(thickness > radius) thickness = radius;\n\n    lv_coord_t r_out = radius;\n    lv_coord_t r_in  = r_out - thickness;\n    int16_t deg_base;\n    int16_t deg;\n    lv_coord_t x_start[4];\n    lv_coord_t x_end[4];\n\n    lv_color_t color = style->line.color;\n    lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->body.opa : (uint16_t)((uint16_t)style->body.opa * opa_scale) >> 8;\n\n    bool (*deg_test)(uint16_t, uint16_t, uint16_t);\n    if(start_angle <= end_angle)\n        deg_test = deg_test_norm;\n    else\n        deg_test = deg_test_inv;\n\n    if(deg_test(270, start_angle, end_angle))\n        hor_line(center_x - r_out + 1, center_y, mask, thickness - 1, color, opa); /*Left Middle*/\n    if(deg_test(90, start_angle, end_angle))\n        hor_line(center_x + r_in, center_y, mask, thickness - 1, color, opa); /*Right Middle*/\n    if(deg_test(180, start_angle, end_angle))\n        ver_line(center_x, center_y - r_out + 1, mask, thickness - 1, color, opa); /*Top Middle*/\n    if(deg_test(0, start_angle, end_angle))\n        ver_line(center_x, center_y + r_in, mask, thickness - 1, color, opa); /*Bottom middle*/\n\n    uint32_t r_out_sqr = r_out * r_out;\n    uint32_t r_in_sqr  = r_in * r_in;\n    int16_t xi;\n    int16_t yi;\n    for(yi = -r_out; yi < 0; yi++) {\n        x_start[0] = LV_COORD_MIN;\n        x_start[1] = LV_COORD_MIN;\n        x_start[2] = LV_COORD_MIN;\n        x_start[3] = LV_COORD_MIN;\n        x_end[0]   = LV_COORD_MIN;\n        x_end[1]   = LV_COORD_MIN;\n        x_end[2]   = LV_COORD_MIN;\n        x_end[3]   = LV_COORD_MIN;\n        for(xi = -r_out; xi < 0; xi++) {\n\n            uint32_t r_act_sqr = xi * xi + yi * yi;\n            if(r_act_sqr > r_out_sqr) continue;\n\n            deg_base = fast_atan2(xi, yi) - 180;\n\n            deg = 180 + deg_base;\n            if(deg_test(deg, start_angle, end_angle)) {\n                if(x_start[0] == LV_COORD_MIN) x_start[0] = xi;\n            } else if(x_start[0] != LV_COORD_MIN && x_end[0] == LV_COORD_MIN) {\n                x_end[0] = xi - 1;\n            }\n\n            deg = 360 - deg_base;\n            if(deg_test(deg, start_angle, end_angle)) {\n                if(x_start[1] == LV_COORD_MIN) x_start[1] = xi;\n            } else if(x_start[1] != LV_COORD_MIN && x_end[1] == LV_COORD_MIN) {\n                x_end[1] = xi - 1;\n            }\n\n            deg = 180 - deg_base;\n            if(deg_test(deg, start_angle, end_angle)) {\n                if(x_start[2] == LV_COORD_MIN) x_start[2] = xi;\n            } else if(x_start[2] != LV_COORD_MIN && x_end[2] == LV_COORD_MIN) {\n                x_end[2] = xi - 1;\n            }\n\n            deg = deg_base;\n            if(deg_test(deg, start_angle, end_angle)) {\n                if(x_start[3] == LV_COORD_MIN) x_start[3] = xi;\n            } else if(x_start[3] != LV_COORD_MIN && x_end[3] == LV_COORD_MIN) {\n                x_end[3] = xi - 1;\n            }\n\n            if(r_act_sqr < r_in_sqr)\n                break; /*No need to continue the iteration in x once we found the inner edge of the\n                          arc*/\n        }\n\n        if(x_start[0] != LV_COORD_MIN) {\n            if(x_end[0] == LV_COORD_MIN) x_end[0] = xi - 1;\n            hor_line(center_x + x_start[0], center_y + yi, mask, x_end[0] - x_start[0], color, opa);\n        }\n\n        if(x_start[1] != LV_COORD_MIN) {\n            if(x_end[1] == LV_COORD_MIN) x_end[1] = xi - 1;\n            hor_line(center_x + x_start[1], center_y - yi, mask, x_end[1] - x_start[1], color, opa);\n        }\n\n        if(x_start[2] != LV_COORD_MIN) {\n            if(x_end[2] == LV_COORD_MIN) x_end[2] = xi - 1;\n            hor_line(center_x - x_end[2], center_y + yi, mask, LV_MATH_ABS(x_end[2] - x_start[2]), color, opa);\n        }\n\n        if(x_start[3] != LV_COORD_MIN) {\n            if(x_end[3] == LV_COORD_MIN) x_end[3] = xi - 1;\n            hor_line(center_x - x_end[3], center_y - yi, mask, LV_MATH_ABS(x_end[3] - x_start[3]), color, opa);\n        }\n\n#if LV_ANTIALIAS\n        /*TODO*/\n\n#endif\n    }\n}\n\nstatic uint16_t fast_atan2(int x, int y)\n{\n    // Fast XY vector to integer degree algorithm - Jan 2011 www.RomanBlack.com\n    // Converts any XY values including 0 to a degree value that should be\n    // within +/- 1 degree of the accurate value without needing\n    // large slow trig functions like ArcTan() or ArcCos().\n    // NOTE! at least one of the X or Y values must be non-zero!\n    // This is the full version, for all 4 quadrants and will generate\n    // the angle in integer degrees from 0-360.\n    // Any values of X and Y are usable including negative values provided\n    // they are between -1456 and 1456 so the 16bit multiply does not overflow.\n\n    unsigned char negflag;\n    unsigned char tempdegree;\n    unsigned char comp;\n    unsigned int degree; /*this will hold the result*/\n    unsigned int ux;\n    unsigned int uy;\n\n    /*Save the sign flags then remove signs and get XY as unsigned ints*/\n    negflag = 0;\n    if(x < 0) {\n        negflag += 0x01; /*x flag bit*/\n        x = (0 - x);     /*is now +*/\n    }\n    ux = x; /*copy to unsigned var before multiply*/\n    if(y < 0) {\n        negflag += 0x02; /*y flag bit*/\n        y = (0 - y);     /*is now +*/\n    }\n    uy = y; /*copy to unsigned var before multiply*/\n\n    /*1. Calc the scaled \"degrees\"*/\n    if(ux > uy) {\n        degree = (uy * 45) / ux; /*degree result will be 0-45 range*/\n        negflag += 0x10;         /*octant flag bit*/\n    } else {\n        degree = (ux * 45) / uy; /*degree result will be 0-45 range*/\n    }\n\n    /*2. Compensate for the 4 degree error curve*/\n    comp       = 0;\n    tempdegree = degree;  /*use an unsigned char for speed!*/\n    if(tempdegree > 22) { /*if top half of range*/\n        if(tempdegree <= 44) comp++;\n        if(tempdegree <= 41) comp++;\n        if(tempdegree <= 37) comp++;\n        if(tempdegree <= 32) comp++; /*max is 4 degrees compensated*/\n    } else {                         /*else is lower half of range*/\n        if(tempdegree >= 2) comp++;\n        if(tempdegree >= 6) comp++;\n        if(tempdegree >= 10) comp++;\n        if(tempdegree >= 15) comp++; /*max is 4 degrees compensated*/\n    }\n    degree += comp; /*degree is now accurate to +/- 1 degree!*/\n\n    /*Invert degree if it was X>Y octant, makes 0-45 into 90-45*/\n      if(negflag & 0x10) degree = (90 - degree);\n\n    /*3. Degree is now 0-90 range for this quadrant,*/\n    /*need to invert it for whichever quadrant it was in*/\n    if(negflag & 0x02) {   /*if -Y*/\n        if(negflag & 0x01) /*if -Y -X*/\n            degree = (180 + degree);\n        else /*else is -Y +X*/\n            degree = (180 - degree);\n    } else {               /*else is +Y*/\n        if(negflag & 0x01) /*if +Y -X*/\n            degree = (360 - degree);\n    }\n    return degree;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\nstatic void ver_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color, lv_opa_t opa)\n{\n    lv_area_t area;\n    lv_area_set(&area, x, y, x, y + len);\n\n    lv_draw_fill(&area, mask, color, opa);\n}\n\nstatic void hor_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color, lv_opa_t opa)\n{\n    lv_area_t area;\n    lv_area_set(&area, x, y, x + len, y);\n\n    lv_draw_fill(&area, mask, color, opa);\n}\n\nstatic bool deg_test_norm(uint16_t deg, uint16_t start, uint16_t end)\n{\n    if(deg >= start && deg <= end)\n        return true;\n    else\n        return false;\n}\n\nstatic bool deg_test_inv(uint16_t deg, uint16_t start, uint16_t end)\n{\n    if(deg >= start || deg <= end) {\n        return true;\n    } else\n        return false;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_draw/lv_draw_basic.c",
    "content": "/**\n * @file lv_draw_basic.c\n *\n */\n\n#include \"libs/lvgl/lv_draw/lv_draw_basic.h\"\n\n#include \"utils/types.h\"\n#include <stdint.h>\n#include <string.h>\n\n#include \"libs/lvgl/lv_core/lv_refr.h\"\n#include \"libs/lvgl/lv_hal/lv_hal.h\"\n#include \"libs/lvgl/lv_font/lv_font.h\"\n#include \"libs/lvgl/lv_misc/lv_area.h\"\n#include \"libs/lvgl/lv_misc/lv_color.h\"\n#include \"libs/lvgl/lv_misc/lv_log.h\"\n\n#include <stddef.h>\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n\n/*********************\n *      INCLUDES\n *********************/\n\n/*********************\n *      DEFINES\n *********************/\n\n/*Always fill < 50 px with 'sw_color_fill' because of the hw. init overhead*/\n#define VFILL_HW_ACC_SIZE_LIMIT 50\n\n#ifndef LV_ATTRIBUTE_MEM_ALIGN\n#define LV_ATTRIBUTE_MEM_ALIGN\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic void sw_mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa);\nstatic void sw_color_fill(lv_color_t * mem, lv_coord_t mem_width, const lv_area_t * fill_area, lv_color_t color,\n                          lv_opa_t opa);\n\n#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP\nstatic inline lv_color_t color_mix_2_alpha(lv_color_t bg_color, lv_opa_t bg_opa, lv_color_t fg_color, lv_opa_t fg_opa);\n#endif\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Put a pixel in the Virtual Display Buffer\n * @param x pixel x coordinate\n * @param y pixel y coordinate\n * @param mask_p fill only on this mask (truncated to VDB area)\n * @param color pixel color\n * @param opa opacity of the area (0..255)\n */\nvoid lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa)\n{\n\n    if(opa < LV_OPA_MIN) return;\n    if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;\n\n    /*Pixel out of the mask*/\n    if(x < mask_p->x1 || x > mask_p->x2 || y < mask_p->y1 || y > mask_p->y2) {\n        return;\n    }\n\n    lv_disp_t * disp    = lv_refr_get_disp_refreshing();\n    lv_disp_buf_t * vdb = lv_disp_get_buf(disp);\n    uint32_t vdb_width  = lv_area_get_width(&vdb->area);\n\n    /*Make the coordinates relative to VDB*/\n    x -= vdb->area.x1;\n    y -= vdb->area.y1;\n\n    if(disp->driver.set_px_cb) {\n        disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, x, y, color, opa);\n    } else {\n        bool scr_transp = false;\n#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP\n        scr_transp = disp->driver.screen_transp;\n#endif\n\n        lv_color_t * vdb_px_p = vdb->buf_act;\n        vdb_px_p += y * vdb_width + x;\n\n        if(scr_transp == false) {\n            if(opa == LV_OPA_COVER) {\n                *vdb_px_p = color;\n            } else {\n                *vdb_px_p = lv_color_mix(color, *vdb_px_p, opa);\n            }\n        } else {\n#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP\n            *vdb_px_p = color_mix_2_alpha(*vdb_px_p, (*vdb_px_p).ch.alpha, color, opa);\n#endif\n        }\n    }\n}\n\n/**\n * Fill an area in the Virtual Display Buffer\n * @param cords_p coordinates of the area to fill\n * @param mask_p fill only o this mask  (truncated to VDB area)\n * @param color fill color\n * @param opa opacity of the area (0..255)\n */\nvoid lv_draw_fill(const lv_area_t * cords_p, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa)\n{\n    if(opa < LV_OPA_MIN) return;\n    if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;\n\n    lv_area_t res_a;\n    bool union_ok;\n\n    /*Get the union of cord and mask*/\n    /* The mask is already truncated to the vdb size\n     * in 'lv_refr_area_with_vdb' function */\n    union_ok = lv_area_intersect(&res_a, cords_p, mask_p);\n\n    /*If there are common part of the three area then draw to the vdb*/\n    if(union_ok == false) {\n        return;\n    }\n\n    lv_disp_t * disp    = lv_refr_get_disp_refreshing();\n    lv_disp_buf_t * vdb = lv_disp_get_buf(disp);\n\n    lv_area_t vdb_rel_a; /*Stores relative coordinates on vdb*/\n    vdb_rel_a.x1 = res_a.x1 - vdb->area.x1;\n    vdb_rel_a.y1 = res_a.y1 - vdb->area.y1;\n    vdb_rel_a.x2 = res_a.x2 - vdb->area.x1;\n    vdb_rel_a.y2 = res_a.y2 - vdb->area.y1;\n\n    lv_color_t * vdb_buf_tmp = vdb->buf_act;\n    uint32_t vdb_width       = lv_area_get_width(&vdb->area);\n    /*Move the vdb_tmp to the first row*/\n    vdb_buf_tmp += vdb_width * vdb_rel_a.y1;\n\n#if LV_USE_GPU\n    static LV_ATTRIBUTE_MEM_ALIGN lv_color_t color_array_tmp[LV_HOR_RES_MAX]; /*Used by 'lv_disp_mem_blend'*/\n    static lv_coord_t last_width = -1;\n\n    lv_coord_t w = lv_area_get_width(&vdb_rel_a);\n    /*Don't use hw. acc. for every small fill (because of the init overhead)*/\n    if(w < VFILL_HW_ACC_SIZE_LIMIT) {\n        sw_color_fill(vdb->buf_act, vdb_width, &vdb_rel_a, color, opa);\n    }\n    /*Not opaque fill*/\n    else if(opa == LV_OPA_COVER) {\n        /*Use hw fill if present*/\n        if(disp->driver.gpu_fill_cb) {\n            disp->driver.gpu_fill_cb(&disp->driver, vdb->buf_act, vdb_width, &vdb_rel_a, color);\n        }\n        /*Use hw blend if present and the area is not too small*/\n        else if(lv_area_get_height(&vdb_rel_a) > VFILL_HW_ACC_SIZE_LIMIT && disp->driver.gpu_blend_cb) {\n            /*Fill a  one line sized buffer with a color and blend this later*/\n            if(color_array_tmp[0].full != color.full || last_width != w) {\n                uint16_t i;\n                for(i = 0; i < w; i++) {\n                    color_array_tmp[i].full = color.full;\n                }\n                last_width = w;\n            }\n\n            /*Blend the filled line to every line VDB line-by-line*/\n            lv_coord_t row;\n            for(row = vdb_rel_a.y1; row <= vdb_rel_a.y2; row++) {\n                disp->driver.gpu_blend_cb(&disp->driver, &vdb_buf_tmp[vdb_rel_a.x1], color_array_tmp, w, opa);\n                vdb_buf_tmp += vdb_width;\n            }\n\n        }\n        /*Else use sw fill if no better option*/\n        else {\n            sw_color_fill(vdb->buf_act, vdb_width, &vdb_rel_a, color, opa);\n        }\n\n    }\n    /*Fill with opacity*/\n    else {\n        /*Use hw blend if present*/\n        if(disp->driver.gpu_blend_cb) {\n            if(color_array_tmp[0].full != color.full || last_width != w) {\n                uint16_t i;\n                for(i = 0; i < w; i++) {\n                    color_array_tmp[i].full = color.full;\n                }\n\n                last_width = w;\n            }\n            lv_coord_t row;\n            for(row = vdb_rel_a.y1; row <= vdb_rel_a.y2; row++) {\n                disp->driver.gpu_blend_cb(&disp->driver, &vdb_buf_tmp[vdb_rel_a.x1], color_array_tmp, w, opa);\n                vdb_buf_tmp += vdb_width;\n            }\n\n        }\n        /*Use sw fill with opa if no better option*/\n        else {\n            sw_color_fill(vdb->buf_act, vdb_width, &vdb_rel_a, color, opa);\n        }\n    }\n#else\n    sw_color_fill(vdb->buf_act, vdb_width, &vdb_rel_a, color, opa);\n#endif\n}\n\n/**\n * Draw a letter in the Virtual Display Buffer\n * @param pos_p left-top coordinate of the latter\n * @param mask_p the letter will be drawn only on this area  (truncated to VDB area)\n * @param font_p pointer to font\n * @param letter a letter to draw\n * @param color color of letter\n * @param opa opacity of letter (0..255)\n */\nvoid lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv_font_t * font_p, uint32_t letter,\n                    lv_color_t color, lv_opa_t opa)\n{\n    /*clang-format off*/\n    const uint8_t bpp1_opa_table[2]  = {0, 255};          /*Opacity mapping with bpp = 1 (Just for compatibility)*/\n    const uint8_t bpp2_opa_table[4]  = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/\n    const uint8_t bpp4_opa_table[16] = {0,  17, 34,  51,  /*Opacity mapping with bpp = 4*/\n                                        68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};\n    /*clang-format on*/\n\n    if(opa < LV_OPA_MIN) return;\n    if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;\n\n    if(font_p == NULL) {\n        LV_LOG_WARN(\"Font: character's bitmap not found\");\n        return;\n    }\n\n    lv_font_glyph_dsc_t g;\n    bool g_ret = lv_font_get_glyph_dsc(font_p, &g, letter, '\\0');\n    if(g_ret == false) return;\n\n    lv_coord_t pos_x = pos_p->x + g.ofs_x;\n    lv_coord_t pos_y = pos_p->y + (font_p->line_height - font_p->base_line) - g.box_h - g.ofs_y;\n\n    const uint8_t * bpp_opa_table;\n    uint8_t bitmask_init;\n    uint8_t bitmask;\n\n    switch(g.bpp) {\n        case 1:\n            bpp_opa_table = bpp1_opa_table;\n            bitmask_init  = 0x80;\n            break;\n        case 2:\n            bpp_opa_table = bpp2_opa_table;\n            bitmask_init  = 0xC0;\n            break;\n        case 4:\n            bpp_opa_table = bpp4_opa_table;\n            bitmask_init  = 0xF0;\n            break;\n        case 8:\n            bpp_opa_table = NULL;\n            bitmask_init  = 0xFF;\n            break;       /*No opa table, pixel value will be used directly*/\n        default: return; /*Invalid bpp. Can't render the letter*/\n    }\n\n    const uint8_t * map_p = lv_font_get_glyph_bitmap(font_p, letter);\n\n    if(map_p == NULL) return;\n\n    /*If the letter is completely out of mask don't draw it */\n    if(pos_x + g.box_w < mask_p->x1 || pos_x > mask_p->x2 || pos_y + g.box_h < mask_p->y1 || pos_y > mask_p->y2) return;\n\n    lv_disp_t * disp    = lv_refr_get_disp_refreshing();\n    lv_disp_buf_t * vdb = lv_disp_get_buf(disp);\n\n    lv_coord_t vdb_width     = lv_area_get_width(&vdb->area);\n    lv_color_t * vdb_buf_tmp = vdb->buf_act;\n    lv_coord_t col, row;\n\n    uint8_t width_byte_scr = g.box_w >> 3; /*Width in bytes (on the screen finally) (e.g. w = 11 -> 2 bytes wide)*/\n    if(g.box_w & 0x7) width_byte_scr++;\n    uint16_t width_bit = g.box_w * g.bpp; /*Letter width in bits*/\n\n    /* Calculate the col/row start/end on the map*/\n    lv_coord_t col_start = pos_x >= mask_p->x1 ? 0 : mask_p->x1 - pos_x;\n    lv_coord_t col_end   = pos_x + g.box_w <= mask_p->x2 ? g.box_w : mask_p->x2 - pos_x + 1;\n    lv_coord_t row_start = pos_y >= mask_p->y1 ? 0 : mask_p->y1 - pos_y;\n    lv_coord_t row_end   = pos_y + g.box_h <= mask_p->y2 ? g.box_h : mask_p->y2 - pos_y + 1;\n\n    /*Set a pointer on VDB to the first pixel of the letter*/\n    vdb_buf_tmp += ((pos_y - vdb->area.y1) * vdb_width) + pos_x - vdb->area.x1;\n\n    /*If the letter is partially out of mask the move there on VDB*/\n    vdb_buf_tmp += (row_start * vdb_width) + col_start;\n\n    /*Move on the map too*/\n    uint32_t bit_ofs = (row_start * width_bit) + (col_start * g.bpp);\n    map_p += bit_ofs >> 3;\n\n    uint8_t letter_px;\n    lv_opa_t px_opa;\n    uint16_t col_bit;\n    col_bit = bit_ofs & 0x7; /* \"& 0x7\" equals to \"% 8\" just faster */\n\n    bool scr_transp = false;\n#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP\n    scr_transp = disp->driver.screen_transp;\n#endif\n\n    for(row = row_start; row < row_end; row++) {\n        bitmask = bitmask_init >> col_bit;\n        for(col = col_start; col < col_end; col++) {\n            letter_px = (*map_p & bitmask) >> (8 - col_bit - g.bpp);\n            if(letter_px != 0) {\n                if(opa == LV_OPA_COVER) {\n                    px_opa = g.bpp == 8 ? letter_px : bpp_opa_table[letter_px];\n                } else {\n                    px_opa = g.bpp == 8 ? (uint16_t)((uint16_t)letter_px * opa) >> 8\n                                        : (uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8;\n                }\n\n                if(disp->driver.set_px_cb) {\n                    disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width,\n                                           (col + pos_x) - vdb->area.x1, (row + pos_y) - vdb->area.y1, color, px_opa);\n                } else if(vdb_buf_tmp->full != color.full) {\n                    if(px_opa > LV_OPA_MAX)\n                        *vdb_buf_tmp = color;\n                    else if(px_opa > LV_OPA_MIN) {\n                        if(scr_transp == false) {\n                            *vdb_buf_tmp = lv_color_mix(color, *vdb_buf_tmp, px_opa);\n                        } else {\n#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP\n                            *vdb_buf_tmp = color_mix_2_alpha(*vdb_buf_tmp, (*vdb_buf_tmp).ch.alpha, color, px_opa);\n#endif\n                        }\n                    }\n                }\n            }\n\n            vdb_buf_tmp++;\n\n            if(col_bit < 8 - g.bpp) {\n                col_bit += g.bpp;\n                bitmask = bitmask >> g.bpp;\n            } else {\n                col_bit = 0;\n                bitmask = bitmask_init;\n                map_p++;\n            }\n        }\n        col_bit += ((g.box_w - col_end) + col_start) * g.bpp;\n\n        map_p += (col_bit >> 3);\n        col_bit = col_bit & 0x7;\n        vdb_buf_tmp += vdb_width - (col_end - col_start); /*Next row in VDB*/\n    }\n}\n\n/**\n * Draw a color map to the display (image)\n * @param cords_p coordinates the color map\n * @param mask_p the map will drawn only on this area  (truncated to VDB area)\n * @param map_p pointer to a lv_color_t array\n * @param opa opacity of the map\n * @param chroma_keyed true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels\n * @param alpha_byte true: extra alpha byte is inserted for every pixel\n * @param recolor mix the pixels with this color\n * @param recolor_opa the intense of recoloring\n */\nvoid lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p, const uint8_t * map_p, lv_opa_t opa,\n                 bool chroma_key, bool alpha_byte, lv_color_t recolor, lv_opa_t recolor_opa)\n{\n\n    if(opa < LV_OPA_MIN) return;\n    if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;\n\n    lv_area_t masked_a;\n    bool union_ok;\n\n    /*Get the union of map size and mask*/\n    /* The mask is already truncated to the vdb size\n     * in 'lv_refr_area_with_vdb' function */\n    union_ok = lv_area_intersect(&masked_a, cords_p, mask_p);\n\n    /*If there are common part of the three area then draw to the vdb*/\n    if(union_ok == false) return;\n\n    /*The pixel size in byte is different if an alpha byte is added too*/\n    uint8_t px_size_byte = alpha_byte ? LV_IMG_PX_SIZE_ALPHA_BYTE : sizeof(lv_color_t);\n\n    /*If the map starts OUT of the masked area then calc. the first pixel*/\n    lv_coord_t map_width = lv_area_get_width(cords_p);\n    if(cords_p->y1 < masked_a.y1) {\n        map_p += (uint32_t)map_width * ((masked_a.y1 - cords_p->y1)) * px_size_byte;\n    }\n    if(cords_p->x1 < masked_a.x1) {\n        map_p += (masked_a.x1 - cords_p->x1) * px_size_byte;\n    }\n\n    lv_disp_t * disp    = lv_refr_get_disp_refreshing();\n    lv_disp_buf_t * vdb = lv_disp_get_buf(disp);\n\n    /*Stores coordinates relative to the current VDB*/\n    masked_a.x1 = masked_a.x1 - vdb->area.x1;\n    masked_a.y1 = masked_a.y1 - vdb->area.y1;\n    masked_a.x2 = masked_a.x2 - vdb->area.x1;\n    masked_a.y2 = masked_a.y2 - vdb->area.y1;\n\n    lv_coord_t vdb_width     = lv_area_get_width(&vdb->area);\n    lv_color_t * vdb_buf_tmp = vdb->buf_act;\n    vdb_buf_tmp += (uint32_t)vdb_width * masked_a.y1; /*Move to the first row*/\n    vdb_buf_tmp += (uint32_t)masked_a.x1;             /*Move to the first col*/\n\n    lv_coord_t row;\n    lv_coord_t map_useful_w = lv_area_get_width(&masked_a);\n\n    bool scr_transp = false;\n#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP\n    scr_transp = disp->driver.screen_transp;\n#endif\n\n    /*The simplest case just copy the pixels into the VDB*/\n    if(chroma_key == false && alpha_byte == false && opa == LV_OPA_COVER && recolor_opa == LV_OPA_TRANSP) {\n\n        /*Use the custom VDB write function is exists*/\n        if(disp->driver.set_px_cb) {\n            lv_coord_t col;\n            for(row = masked_a.y1; row <= masked_a.y2; row++) {\n                for(col = 0; col < map_useful_w; col++) {\n                    lv_color_t px_color = *((lv_color_t *)&map_p[(uint32_t)col * px_size_byte]);\n                    disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1, row,\n                                           px_color, opa);\n                }\n                map_p += map_width * px_size_byte; /*Next row on the map*/\n            }\n        }\n        /*Normal native VDB*/\n        else {\n            for(row = masked_a.y1; row <= masked_a.y2; row++) {\n#if LV_USE_GPU\n                if(disp->driver.gpu_blend_cb == false) {\n                    sw_mem_blend(vdb_buf_tmp, (lv_color_t *)map_p, map_useful_w, opa);\n                } else {\n                    disp->driver.gpu_blend_cb(&disp->driver, vdb_buf_tmp, (lv_color_t *)map_p, map_useful_w, opa);\n                }\n#else\n                sw_mem_blend(vdb_buf_tmp, (lv_color_t *)map_p, map_useful_w, opa);\n#endif\n                map_p += map_width * px_size_byte; /*Next row on the map*/\n                vdb_buf_tmp += vdb_width;          /*Next row on the VDB*/\n            }\n        }\n    }\n\n    /*In the other cases every pixel need to be checked one-by-one*/\n    else {\n\n        lv_coord_t col;\n        lv_color_t last_img_px  = LV_COLOR_BLACK;\n        lv_color_t recolored_px = lv_color_mix(recolor, last_img_px, recolor_opa);\n        for(row = masked_a.y1; row <= masked_a.y2; row++) {\n            for(col = 0; col < map_useful_w; col++) {\n                lv_opa_t opa_result  = opa;\n                uint8_t * px_color_p = (uint8_t *)&map_p[(uint32_t)col * px_size_byte];\n                lv_color_t px_color;\n\n                /*Calculate with the pixel level alpha*/\n                if(alpha_byte) {\n#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1\n                    px_color.full = px_color_p[0];\n#elif LV_COLOR_DEPTH == 16\n                    /*Because of Alpha byte 16 bit color can start on odd address which can cause\n                     * crash*/\n                    px_color.full = px_color_p[0] + (px_color_p[1] << 8);\n#elif LV_COLOR_DEPTH == 32\n                    px_color = *((lv_color_t *)px_color_p);\n#endif\n                    lv_opa_t px_opa = *(px_color_p + LV_IMG_PX_SIZE_ALPHA_BYTE - 1);\n                    if(px_opa == LV_OPA_TRANSP)\n                        continue;\n                    else if(px_opa != LV_OPA_COVER)\n                        opa_result = (uint32_t)((uint32_t)px_opa * opa_result) >> 8;\n                } else {\n                    px_color = *((lv_color_t *)px_color_p);\n                }\n\n                /*Handle chroma key*/\n                if(chroma_key && px_color.full == disp->driver.color_chroma_key.full) continue;\n\n                /*Re-color the pixel if required*/\n                if(recolor_opa != LV_OPA_TRANSP) {\n                    if(last_img_px.full != px_color.full) { /*Minor acceleration: calculate only for\n                                                               new colors (save the last)*/\n                        last_img_px  = px_color;\n                        recolored_px = lv_color_mix(recolor, last_img_px, recolor_opa);\n                    }\n                    /*Handle custom VDB write is present*/\n                    if(disp->driver.set_px_cb) {\n                        disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1,\n                                               row, recolored_px, opa_result);\n                    }\n                    /*Normal native VDB write*/\n                    else {\n                        if(opa_result == LV_OPA_COVER)\n                            vdb_buf_tmp[col].full = recolored_px.full;\n                        else\n                            vdb_buf_tmp[col] = lv_color_mix(recolored_px, vdb_buf_tmp[col], opa_result);\n                    }\n                } else {\n                    /*Handle custom VDB write is present*/\n                    if(disp->driver.set_px_cb) {\n                        disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1,\n                                               row, px_color, opa_result);\n                    }\n                    /*Normal native VDB write*/\n                    else {\n\n                        if(opa_result == LV_OPA_COVER)\n                            vdb_buf_tmp[col] = px_color;\n                        else {\n                            if(scr_transp == false) {\n                                vdb_buf_tmp[col] = lv_color_mix(px_color, vdb_buf_tmp[col], opa_result);\n                            } else {\n#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP\n                                vdb_buf_tmp[col] = color_mix_2_alpha(vdb_buf_tmp[col], vdb_buf_tmp[col].ch.alpha,\n                                                                     px_color, opa_result);\n#endif\n                            }\n                        }\n                    }\n                }\n            }\n\n            map_p += map_width * px_size_byte; /*Next row on the map*/\n            vdb_buf_tmp += vdb_width;          /*Next row on the VDB*/\n        }\n    }\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Blend pixels to destination memory using opacity\n * @param dest a memory address. Copy 'src' here.\n * @param src pointer to pixel map. Copy it to 'dest'.\n * @param length number of pixels in 'src'\n * @param opa opacity (0, LV_OPA_TRANSP: transparent ... 255, LV_OPA_COVER, fully cover)\n */\nstatic void sw_mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa)\n{\n    if(opa == LV_OPA_COVER) {\n        memcpy(dest, src, length * sizeof(lv_color_t));\n    } else {\n        uint32_t col;\n        for(col = 0; col < length; col++) {\n            dest[col] = lv_color_mix(src[col], dest[col], opa);\n        }\n    }\n}\n\n/**\n * Fill an area with a color\n * @param mem a memory address. Considered to a rectangular window according to 'mem_area'\n * @param mem_width width of the 'mem' buffer\n * @param fill_area coordinates of an area to fill. Relative to 'mem_area'.\n * @param color fill color\n * @param opa opacity (0, LV_OPA_TRANSP: transparent ... 255, LV_OPA_COVER, fully cover)\n */\nstatic void sw_color_fill(lv_color_t * mem, lv_coord_t mem_width, const lv_area_t * fill_area, lv_color_t color,\n                          lv_opa_t opa)\n{\n    /*Set all row in vdb to the given color*/\n    lv_coord_t row;\n    lv_coord_t col;\n\n    lv_disp_t * disp = lv_refr_get_disp_refreshing();\n    if(disp->driver.set_px_cb) {\n        for(col = fill_area->x1; col <= fill_area->x2; col++) {\n            for(row = fill_area->y1; row <= fill_area->y2; row++) {\n                disp->driver.set_px_cb(&disp->driver, (uint8_t *)mem, mem_width, col, row, color, opa);\n            }\n        }\n    } else {\n        mem += fill_area->y1 * mem_width; /*Go to the first row*/\n\n        /*Run simpler function without opacity*/\n        if(opa == LV_OPA_COVER) {\n\n            /*Fill the first row with 'color'*/\n            for(col = fill_area->x1; col <= fill_area->x2; col++) {\n                mem[col] = color;\n            }\n\n            /*Copy the first row to all other rows*/\n            lv_color_t * mem_first = &mem[fill_area->x1];\n            lv_coord_t copy_size   = (fill_area->x2 - fill_area->x1 + 1) * sizeof(lv_color_t);\n            mem += mem_width;\n\n            for(row = fill_area->y1 + 1; row <= fill_area->y2; row++) {\n                memcpy(&mem[fill_area->x1], mem_first, copy_size);\n                mem += mem_width;\n            }\n        }\n        /*Calculate with alpha too*/\n        else {\n            bool scr_transp = false;\n#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP\n            scr_transp = disp->driver.screen_transp;\n#endif\n\n            lv_color_t bg_tmp  = LV_COLOR_BLACK;\n            lv_color_t opa_tmp = lv_color_mix(color, bg_tmp, opa);\n            for(row = fill_area->y1; row <= fill_area->y2; row++) {\n                for(col = fill_area->x1; col <= fill_area->x2; col++) {\n                    if(scr_transp == false) {\n                        /*If the bg color changed recalculate the result color*/\n                        if(mem[col].full != bg_tmp.full) {\n                            bg_tmp  = mem[col];\n                            opa_tmp = lv_color_mix(color, bg_tmp, opa);\n                        }\n\n                        mem[col] = opa_tmp;\n\n                    } else {\n#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP\n                        mem[col] = color_mix_2_alpha(mem[col], mem[col].ch.alpha, color, opa);\n#endif\n                    }\n                }\n                mem += mem_width;\n            }\n        }\n    }\n}\n\n#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP\n/**\n * Mix two colors. Both color can have alpha value. It requires ARGB888 colors.\n * @param bg_color background color\n * @param bg_opa alpha of the background color\n * @param fg_color foreground color\n * @param fg_opa alpha of the foreground color\n * @return the mixed color. the alpha channel (color.alpha) contains the result alpha\n */\nstatic inline lv_color_t color_mix_2_alpha(lv_color_t bg_color, lv_opa_t bg_opa, lv_color_t fg_color, lv_opa_t fg_opa)\n{\n    /* Pick the foreground if it's fully opaque or the Background is fully transparent*/\n    if(fg_opa > LV_OPA_MAX || bg_opa <= LV_OPA_MIN) {\n        fg_color.ch.alpha = fg_opa;\n        return fg_color;\n    }\n    /*Transparent foreground: use the Background*/\n    else if(fg_opa <= LV_OPA_MIN) {\n        return bg_color;\n    }\n    /*Opaque background: use simple mix*/\n    else if(bg_opa >= LV_OPA_MAX) {\n        return lv_color_mix(fg_color, bg_color, fg_opa);\n    }\n    /*Both colors have alpha. Expensive calculation need to be applied*/\n    else {\n        /*Save the parameters and the result. If they will be asked again don't compute again*/\n        static lv_opa_t fg_opa_save     = 0;\n        static lv_opa_t bg_opa_save     = 0;\n        static lv_color_t fg_color_save = {{0}};\n        static lv_color_t bg_color_save = {{0}};\n        static lv_color_t c             = {{0}};\n\n        if(fg_opa != fg_opa_save || bg_opa != bg_opa_save || fg_color.full != fg_color_save.full ||\n           bg_color.full != bg_color_save.full) {\n            fg_opa_save        = fg_opa;\n            bg_opa_save        = bg_opa;\n            fg_color_save.full = fg_color.full;\n            bg_color_save.full = bg_color.full;\n            /*Info:\n             * https://en.wikipedia.org/wiki/Alpha_compositing#Analytical_derivation_of_the_over_operator*/\n            lv_opa_t alpha_res = 255 - ((uint16_t)((uint16_t)(255 - fg_opa) * (255 - bg_opa)) >> 8);\n            if(alpha_res == 0) {\n                while(1)\n                    ;\n            }\n            lv_opa_t ratio = (uint16_t)((uint16_t)fg_opa * 255) / alpha_res;\n            c              = lv_color_mix(fg_color, bg_color, ratio);\n            c.ch.alpha     = alpha_res;\n        }\n        return c;\n    }\n}\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_draw/lv_draw_img.c",
    "content": "/**\n * @file lv_draw_img.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_draw/lv_draw_img.h\"\n#include \"libs/lvgl/lv_draw/lv_img_cache.h\"\n#include \"libs/lvgl/lv_misc/lv_log.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mask, const void * src,\n                                 const lv_style_t * style, lv_opa_t opa_scale);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Draw an image\n * @param coords the coordinates of the image\n * @param mask the image will be drawn only in this area\n * @param src pointer to a lv_color_t array which contains the pixels of the image\n * @param style style of the image\n * @param opa_scale scale down all opacities by the factor\n */\nvoid lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_style_t * style,\n                 lv_opa_t opa_scale)\n{\n    if(src == NULL) {\n        LV_LOG_WARN(\"Image draw: src is NULL\");\n        lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);\n        lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, \"No\\ndata\", LV_TXT_FLAG_NONE, NULL, -1, -1, NULL);\n        return;\n    }\n\n    lv_res_t res;\n    res = lv_img_draw_core(coords, mask, src, style, opa_scale);\n\n    if(res == LV_RES_INV) {\n        LV_LOG_WARN(\"Image draw error\");\n        lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);\n        lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, \"No\\ndata\", LV_TXT_FLAG_NONE, NULL, -1, -1, NULL);\n        return;\n    }\n}\n\n/**\n * Get the color of an image's pixel\n * @param dsc an image descriptor\n * @param x x coordinate of the point to get\n * @param y x coordinate of the point to get\n * @param style style of the image. In case of `LV_IMG_CF_ALPHA_1/2/4/8` `style->image.color` shows\n * the color. Can be `NULL` but for `ALPHA` images black will be returned. In other cases it is not\n * used.\n * @return color of the point\n */\nlv_color_t lv_img_buf_get_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, const lv_style_t * style)\n{\n    lv_color_t p_color = LV_COLOR_BLACK;\n    if(x >= dsc->header.w) {\n        x = dsc->header.w - 1;\n        LV_LOG_WARN(\"lv_canvas_get_px: x is too large (out of canvas)\");\n    } else if(x < 0) {\n        x = 0;\n        LV_LOG_WARN(\"lv_canvas_get_px: x is < 0 (out of canvas)\");\n    }\n\n    if(y >= dsc->header.h) {\n        y = dsc->header.h - 1;\n        LV_LOG_WARN(\"lv_canvas_get_px: y is too large (out of canvas)\");\n    } else if(y < 0) {\n        y = 0;\n        LV_LOG_WARN(\"lv_canvas_get_px: y is < 0 (out of canvas)\");\n    }\n\n    uint8_t * buf_u8 = (uint8_t *)dsc->data;\n\n    if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED ||\n       dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA) {\n        uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf) >> 3;\n        uint32_t px     = dsc->header.w * y * px_size + x * px_size;\n        memcpy(&p_color, &buf_u8[px], sizeof(lv_color_t));\n#if LV_COLOR_SIZE == 32\n        p_color.ch.alpha = 0xFF; /*Only the color should be get so use a deafult alpha value*/\n#endif\n    } else if(dsc->header.cf == LV_IMG_CF_INDEXED_1BIT) {\n        buf_u8 += 4 * 2;\n        uint8_t bit = x & 0x7;\n        x           = x >> 3;\n\n        /* Get the current pixel.\n         * dsc->header.w + 7 means rounding up to 8 because the lines are byte aligned\n         * so the possible real width are 8, 16, 24 ...*/\n        uint32_t px  = ((dsc->header.w + 7) >> 3) * y + x;\n        p_color.full = (buf_u8[px] & (1 << (7 - bit))) >> (7 - bit);\n    } else if(dsc->header.cf == LV_IMG_CF_INDEXED_2BIT) {\n        buf_u8 += 4 * 4;\n        uint8_t bit = (x & 0x3) * 2;\n        x           = x >> 2;\n\n        /* Get the current pixel.\n         * dsc->header.w + 3 means rounding up to 4 because the lines are byte aligned\n         * so the possible real width are 4, 8, 12 ...*/\n        uint32_t px  = ((dsc->header.w + 3) >> 2) * y + x;\n        p_color.full = (buf_u8[px] & (3 << (6 - bit))) >> (6 - bit);\n    } else if(dsc->header.cf == LV_IMG_CF_INDEXED_4BIT) {\n        buf_u8 += 4 * 16;\n        uint8_t bit = (x & 0x1) * 4;\n        x           = x >> 1;\n\n        /* Get the current pixel.\n         * dsc->header.w + 1 means rounding up to 2 because the lines are byte aligned\n         * so the possible real width are 2, 4, 6 ...*/\n        uint32_t px  = ((dsc->header.w + 1) >> 1) * y + x;\n        p_color.full = (buf_u8[px] & (0xF << (4 - bit))) >> (4 - bit);\n    } else if(dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) {\n        buf_u8 += 4 * 256;\n        uint32_t px  = dsc->header.w * y + x;\n        p_color.full = buf_u8[px];\n    } else if(dsc->header.cf == LV_IMG_CF_ALPHA_1BIT || dsc->header.cf == LV_IMG_CF_ALPHA_2BIT ||\n              dsc->header.cf == LV_IMG_CF_ALPHA_4BIT || dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) {\n        if(style)\n            p_color = style->image.color;\n        else\n            p_color = LV_COLOR_BLACK;\n    }\n    return p_color;\n}\n\n/**\n * Get the alpha value of an image's pixel\n * @param dsc pointer to an image descriptor\n * @param x x coordinate of the point to set\n * @param y x coordinate of the point to set\n * @return alpha value of the point\n */\nlv_opa_t lv_img_buf_get_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y)\n{\n    if(x >= dsc->header.w) {\n        x = dsc->header.w - 1;\n        LV_LOG_WARN(\"lv_canvas_get_px: x is too large (out of canvas)\");\n    } else if(x < 0) {\n        x = 0;\n        LV_LOG_WARN(\"lv_canvas_get_px: x is < 0 (out of canvas)\");\n    }\n\n    if(y >= dsc->header.h) {\n        y = dsc->header.h - 1;\n        LV_LOG_WARN(\"lv_canvas_get_px: y is too large (out of canvas)\");\n    } else if(y < 0) {\n        y = 0;\n        LV_LOG_WARN(\"lv_canvas_get_px: y is < 0 (out of canvas)\");\n    }\n\n    uint8_t * buf_u8 = (uint8_t *)dsc->data;\n\n    if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA) {\n        uint32_t px = dsc->header.w * y * LV_IMG_PX_SIZE_ALPHA_BYTE + x * LV_IMG_PX_SIZE_ALPHA_BYTE;\n        return buf_u8[px + LV_IMG_PX_SIZE_ALPHA_BYTE - 1];\n    } else if(dsc->header.cf == LV_IMG_CF_ALPHA_1BIT) {\n        uint8_t bit = x & 0x7;\n        x           = x >> 3;\n\n        /* Get the current pixel.\n         * dsc->header.w + 7 means rounding up to 8 because the lines are byte aligned\n         * so the possible real width are 8 ,16, 24 ...*/\n        uint32_t px    = ((dsc->header.w + 7) >> 3) * y + x;\n        uint8_t px_opa = (buf_u8[px] & (1 << (7 - bit))) >> (7 - bit);\n        return px_opa ? LV_OPA_TRANSP : LV_OPA_COVER;\n    } else if(dsc->header.cf == LV_IMG_CF_ALPHA_2BIT) {\n        const uint8_t opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/\n\n        uint8_t bit = (x & 0x3) * 2;\n        x           = x >> 2;\n\n        /* Get the current pixel.\n         * dsc->header.w + 4 means rounding up to 8 because the lines are byte aligned\n         * so the possible real width are 4 ,8, 12 ...*/\n        uint32_t px    = ((dsc->header.w + 3) >> 2) * y + x;\n        uint8_t px_opa = (buf_u8[px] & (3 << (6 - bit))) >> (6 - bit);\n        return opa_table[px_opa];\n    } else if(dsc->header.cf == LV_IMG_CF_ALPHA_4BIT) {\n        const uint8_t opa_table[16] = {0,  17, 34,  51, /*Opacity mapping with bpp = 4*/\n                                       68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};\n\n        uint8_t bit = (x & 0x1) * 4;\n        x           = x >> 1;\n\n        /* Get the current pixel.\n         * dsc->header.w + 1 means rounding up to 8 because the lines are byte aligned\n         * so the possible real width are 2 ,4, 6 ...*/\n        uint32_t px    = ((dsc->header.w + 1) >> 1) * y + x;\n        uint8_t px_opa = (buf_u8[px] & (0xF << (4 - bit))) >> (4 - bit);\n        return opa_table[px_opa];\n    } else if(dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) {\n        uint32_t px = dsc->header.w * y + x;\n        return buf_u8[px];\n    }\n\n    return LV_OPA_COVER;\n}\n\n/**\n * Set the color of a pixel of an image. The alpha channel won't be affected.\n * @param dsc pointer to an image descriptor\n * @param x x coordinate of the point to set\n * @param y x coordinate of the point to set\n * @param c color of the point\n */\nvoid lv_img_buf_set_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_color_t c)\n{\n    uint8_t * buf_u8 = (uint8_t *)dsc->data;\n\n    if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) {\n        uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf) >> 3;\n        uint32_t px     = dsc->header.w * y * px_size + x * px_size;\n        memcpy(&buf_u8[px], &c, px_size);\n    } else if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA) {\n        uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf) >> 3;\n        uint32_t px     = dsc->header.w * y * px_size + x * px_size;\n        memcpy(&buf_u8[px], &c, px_size - 1); /*-1 to not overwrite the alpha value*/\n    } else if(dsc->header.cf == LV_IMG_CF_INDEXED_1BIT) {\n        buf_u8 += sizeof(lv_color32_t) * 2; /*Skip the palette*/\n\n        uint8_t bit = x & 0x7;\n        x           = x >> 3;\n\n        /* Get the current pixel.\n         * dsc->header.w + 7 means rounding up to 8 because the lines are byte aligned\n         * so the possible real width are 8 ,16, 24 ...*/\n        uint32_t px = ((dsc->header.w + 7) >> 3) * y + x;\n        buf_u8[px]  = buf_u8[px] & ~(1 << (7 - bit));\n        buf_u8[px]  = buf_u8[px] | ((c.full & 0x1) << (7 - bit));\n    } else if(dsc->header.cf == LV_IMG_CF_INDEXED_2BIT) {\n        buf_u8 += sizeof(lv_color32_t) * 4; /*Skip the palette*/\n        uint8_t bit = (x & 0x3) * 2;\n        x           = x >> 2;\n\n        /* Get the current pixel.\n         * dsc->header.w + 3 means rounding up to 4 because the lines are byte aligned\n         * so the possible real width are 4, 8 ,12 ...*/\n        uint32_t px = ((dsc->header.w + 3) >> 2) * y + x;\n\n        buf_u8[px] = buf_u8[px] & ~(3 << (6 - bit));\n        buf_u8[px] = buf_u8[px] | ((c.full & 0x3) << (6 - bit));\n    } else if(dsc->header.cf == LV_IMG_CF_INDEXED_4BIT) {\n        buf_u8 += sizeof(lv_color32_t) * 16; /*Skip the palette*/\n        uint8_t bit = (x & 0x1) * 4;\n        x           = x >> 1;\n\n        /* Get the current pixel.\n         * dsc->header.w + 1 means rounding up to 2 because the lines are byte aligned\n         * so the possible real width are 2 ,4, 6 ...*/\n        uint32_t px = ((dsc->header.w + 1) >> 1) * y + x;\n        buf_u8[px]  = buf_u8[px] & ~(0xF << (4 - bit));\n        buf_u8[px]  = buf_u8[px] | ((c.full & 0xF) << (4 - bit));\n    } else if(dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) {\n        buf_u8 += sizeof(lv_color32_t) * 256; /*Skip the palette*/\n        uint32_t px = dsc->header.w * y + x;\n        buf_u8[px]  = c.full;\n    }\n}\n\n/**\n * Set the alpha value of a pixel of an image. The color won't be affected\n * @param dsc pointer to an image descriptor\n * @param x x coordinate of the point to set\n * @param y x coordinate of the point to set\n * @param opa the desired opacity\n */\nvoid lv_img_buf_set_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_opa_t opa)\n{\n    uint8_t * buf_u8 = (uint8_t *)dsc->data;\n\n    if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA) {\n        uint8_t px_size          = lv_img_color_format_get_px_size(dsc->header.cf) >> 3;\n        uint32_t px              = dsc->header.w * y * px_size + x * px_size;\n        buf_u8[px + px_size - 1] = opa;\n    } else if(dsc->header.cf == LV_IMG_CF_ALPHA_1BIT) {\n        opa         = opa >> 7; /*opa -> [0,1]*/\n        uint8_t bit = x & 0x7;\n        x           = x >> 3;\n\n        /* Get the current pixel.\n         * dsc->header.w + 7 means rounding up to 8 because the lines are byte aligned\n         * so the possible real width are 8 ,16, 24 ...*/\n        uint32_t px = ((dsc->header.w + 7) >> 3) * y + x;\n        buf_u8[px]  = buf_u8[px] & ~(1 << (7 - bit));\n        buf_u8[px]  = buf_u8[px] | ((opa & 0x1) << (7 - bit));\n    } else if(dsc->header.cf == LV_IMG_CF_ALPHA_2BIT) {\n        opa         = opa >> 6; /*opa -> [0,3]*/\n        uint8_t bit = (x & 0x3) * 2;\n        x           = x >> 2;\n\n        /* Get the current pixel.\n         * dsc->header.w + 4 means rounding up to 8 because the lines are byte aligned\n         * so the possible real width are 4 ,8, 12 ...*/\n        uint32_t px = ((dsc->header.w + 3) >> 2) * y + x;\n        buf_u8[px]  = buf_u8[px] & ~(3 << (6 - bit));\n        buf_u8[px]  = buf_u8[px] | ((opa & 0x3) << (6 - bit));\n    } else if(dsc->header.cf == LV_IMG_CF_ALPHA_4BIT) {\n        opa         = opa >> 4; /*opa -> [0,15]*/\n        uint8_t bit = (x & 0x1) * 4;\n        x           = x >> 1;\n\n        /* Get the current pixel.\n         * dsc->header.w + 1 means rounding up to 8 because the lines are byte aligned\n         * so the possible real width are 2 ,4, 6 ...*/\n        uint32_t px = ((dsc->header.w + 1) >> 1) * y + x;\n        buf_u8[px]  = buf_u8[px] & ~(0xF << (4 - bit));\n        buf_u8[px]  = buf_u8[px] | ((opa & 0xF) << (4 - bit));\n    } else if(dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) {\n        uint32_t px = dsc->header.w * y + x;\n        buf_u8[px]  = opa;\n    }\n}\n\n/**\n * Set the palette color of an indexed image. Valid only for `LV_IMG_CF_INDEXED1/2/4/8`\n * @param dsc pointer to an image descriptor\n * @param id the palette color to set:\n *   - for `LV_IMG_CF_INDEXED1`: 0..1\n *   - for `LV_IMG_CF_INDEXED2`: 0..3\n *   - for `LV_IMG_CF_INDEXED4`: 0..15\n *   - for `LV_IMG_CF_INDEXED8`: 0..255\n * @param c the color to set\n */\nvoid lv_img_buf_set_palette(lv_img_dsc_t * dsc, uint8_t id, lv_color_t c)\n{\n    if((dsc->header.cf == LV_IMG_CF_ALPHA_1BIT && id > 1) || (dsc->header.cf == LV_IMG_CF_ALPHA_2BIT && id > 3) ||\n       (dsc->header.cf == LV_IMG_CF_ALPHA_4BIT && id > 15) || (dsc->header.cf == LV_IMG_CF_ALPHA_8BIT)) {\n        LV_LOG_WARN(\"lv_img_buf_set_px_alpha: invalid 'id'\");\n        return;\n    }\n\n    lv_color32_t c32;\n    c32.full      = lv_color_to32(c);\n    uint8_t * buf = (uint8_t *)dsc->data;\n    memcpy(&buf[id * sizeof(c32)], &c32, sizeof(c32));\n}\n\n/**\n * Get the pixel size of a color format in bits\n * @param cf a color format (`LV_IMG_CF_...`)\n * @return the pixel size in bits\n */\nuint8_t lv_img_color_format_get_px_size(lv_img_cf_t cf)\n{\n    uint8_t px_size = 0;\n\n    switch(cf) {\n        case LV_IMG_CF_UNKNOWN:\n        case LV_IMG_CF_RAW: px_size = 0; break;\n        case LV_IMG_CF_TRUE_COLOR:\n        case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED: px_size = LV_COLOR_SIZE; break;\n        case LV_IMG_CF_TRUE_COLOR_ALPHA: px_size = LV_IMG_PX_SIZE_ALPHA_BYTE << 3; break;\n        case LV_IMG_CF_INDEXED_1BIT:\n        case LV_IMG_CF_ALPHA_1BIT: px_size = 1; break;\n        case LV_IMG_CF_INDEXED_2BIT:\n        case LV_IMG_CF_ALPHA_2BIT: px_size = 2; break;\n        case LV_IMG_CF_INDEXED_4BIT:\n        case LV_IMG_CF_ALPHA_4BIT: px_size = 4; break;\n        case LV_IMG_CF_INDEXED_8BIT:\n        case LV_IMG_CF_ALPHA_8BIT: px_size = 8; break;\n        default: px_size = 0; break;\n    }\n\n    return px_size;\n}\n\n/**\n * Check if a color format is chroma keyed or not\n * @param cf a color format (`LV_IMG_CF_...`)\n * @return true: chroma keyed; false: not chroma keyed\n */\nbool lv_img_color_format_is_chroma_keyed(lv_img_cf_t cf)\n{\n    bool is_chroma_keyed = false;\n\n    switch(cf) {\n        case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED:\n        case LV_IMG_CF_RAW_CHROMA_KEYED:\n        case LV_IMG_CF_INDEXED_1BIT:\n        case LV_IMG_CF_INDEXED_2BIT:\n        case LV_IMG_CF_INDEXED_4BIT:\n        case LV_IMG_CF_INDEXED_8BIT: is_chroma_keyed = true; break;\n        default: is_chroma_keyed = false; break;\n    }\n\n    return is_chroma_keyed;\n}\n\n/**\n * Check if a color format has alpha channel or not\n * @param cf a color format (`LV_IMG_CF_...`)\n * @return true: has alpha channel; false: doesn't have alpha channel\n */\nbool lv_img_color_format_has_alpha(lv_img_cf_t cf)\n{\n    bool has_alpha = false;\n\n    switch(cf) {\n        case LV_IMG_CF_TRUE_COLOR_ALPHA:\n        case LV_IMG_CF_RAW_ALPHA:\n        case LV_IMG_CF_ALPHA_1BIT:\n        case LV_IMG_CF_ALPHA_2BIT:\n        case LV_IMG_CF_ALPHA_4BIT:\n        case LV_IMG_CF_ALPHA_8BIT: has_alpha = true; break;\n        default: has_alpha = false; break;\n    }\n\n    return has_alpha;\n}\n\n/**\n * Get the type of an image source\n * @param src pointer to an image source:\n *  - pointer to an 'lv_img_t' variable (image stored internally and compiled into the code)\n *  - a path to a file (e.g. \"S:/folder/image.bin\")\n *  - or a symbol (e.g. LV_SYMBOL_CLOSE)\n * @return type of the image source LV_IMG_SRC_VARIABLE/FILE/SYMBOL/UNKNOWN\n */\nlv_img_src_t lv_img_src_get_type(const void * src)\n{\n    lv_img_src_t img_src_type = LV_IMG_SRC_UNKNOWN;\n\n    if(src == NULL) return img_src_type;\n    const uint8_t * u8_p = src;\n\n    /*The first byte shows the type of the image source*/\n    if(u8_p[0] >= 0x20 && u8_p[0] <= 0x7F) {\n        img_src_type = LV_IMG_SRC_FILE; /*If it's an ASCII character then it's file name*/\n    } else if(u8_p[0] >= 0x80) {\n        img_src_type = LV_IMG_SRC_SYMBOL; /*Symbols begins after 0x7F*/\n    } else {\n        img_src_type = LV_IMG_SRC_VARIABLE; /*`lv_img_dsc_t` is design to the first byte < 0x20*/\n    }\n\n    if(LV_IMG_SRC_UNKNOWN == img_src_type) {\n        LV_LOG_WARN(\"lv_img_src_get_type: unknown image type\");\n    }\n\n    return img_src_type;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\nstatic lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mask, const void * src,\n                                 const lv_style_t * style, lv_opa_t opa_scale)\n{\n\n    lv_area_t mask_com; /*Common area of mask and coords*/\n    bool union_ok;\n    union_ok = lv_area_intersect(&mask_com, mask, coords);\n    if(union_ok == false) {\n        return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn\n                             successfully.*/\n    }\n\n    lv_opa_t opa =\n        opa_scale == LV_OPA_COVER ? style->image.opa : (uint16_t)((uint16_t)style->image.opa * opa_scale) >> 8;\n\n    lv_img_cache_entry_t * cdsc = lv_img_cache_open(src, style);\n\n    if(cdsc == NULL) return LV_RES_INV;\n\n    bool chroma_keyed = lv_img_color_format_is_chroma_keyed(cdsc->dec_dsc.header.cf);\n    bool alpha_byte   = lv_img_color_format_has_alpha(cdsc->dec_dsc.header.cf);\n\n    if(cdsc->dec_dsc.error_msg != NULL) {\n        LV_LOG_WARN(\"Image draw error\");\n        lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);\n        lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, cdsc->dec_dsc.error_msg, LV_TXT_FLAG_NONE, NULL, -1,\n                      -1, NULL);\n    }\n    /* The decoder open could open the image and gave the entire uncompressed image.\n     * Just draw it!*/\n    else if(cdsc->dec_dsc.img_data) {\n        lv_draw_map(coords, mask, cdsc->dec_dsc.img_data, opa, chroma_keyed, alpha_byte, style->image.color,\n                    style->image.intense);\n    }\n    /* The whole uncompressed image is not available. Try to read it line-by-line*/\n    else {\n        lv_coord_t width = lv_area_get_width(&mask_com);\n\n        uint8_t  * buf = lv_draw_get_buf(lv_area_get_width(&mask_com) * ((LV_COLOR_DEPTH >> 3) + 1));  /*+1 because of the possible alpha byte*/\n\n        lv_area_t line;\n        lv_area_copy(&line, &mask_com);\n        lv_area_set_height(&line, 1);\n        lv_coord_t x = mask_com.x1 - coords->x1;\n        lv_coord_t y = mask_com.y1 - coords->y1;\n        lv_coord_t row;\n        lv_res_t read_res;\n        for(row = mask_com.y1; row <= mask_com.y2; row++) {\n            read_res = lv_img_decoder_read_line(&cdsc->dec_dsc, x, y, width, buf);\n            if(read_res != LV_RES_OK) {\n                lv_img_decoder_close(&cdsc->dec_dsc);\n                LV_LOG_WARN(\"Image draw can't read the line\");\n                return LV_RES_INV;\n            }\n            lv_draw_map(&line, mask, buf, opa, chroma_keyed, alpha_byte, style->image.color, style->image.intense);\n            line.y1++;\n            line.y2++;\n            y++;\n        }\n    }\n\n    return LV_RES_OK;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_draw/lv_draw_label.c",
    "content": "/**\n * @file lv_draw_label.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_draw/lv_draw_label.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LABEL_RECOLOR_PAR_LENGTH 6\n#define LV_LABEL_HINT_UPDATE_TH 1024 /*Update the \"hint\" if the label's y coordinates have changed more then this*/\n\n/**********************\n *      TYPEDEFS\n **********************/\nenum {\n    CMD_STATE_WAIT,\n    CMD_STATE_PAR,\n    CMD_STATE_IN,\n};\ntypedef uint8_t cmd_state_t;\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic uint8_t hex_char_to_num(char hex);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Write a text\n * @param coords coordinates of the label\n * @param mask the label will be drawn only in this area\n * @param style pointer to a style\n * @param opa_scale scale down all opacities by the factor\n * @param txt 0 terminated text to write\n * @param flag settings for the text from 'txt_flag_t' enum\n * @param offset text offset in x and y direction (NULL if unused)\n * @param sel_start start index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)\n * @param sel_end end index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)\n */\nvoid lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale,\n                   const char * txt, lv_txt_flag_t flag, lv_point_t * offset, uint16_t sel_start, uint16_t sel_end,\n                   lv_draw_label_hint_t * hint)\n{\n    const lv_font_t * font = style->text.font;\n    lv_coord_t w;\n    if((flag & LV_TXT_FLAG_EXPAND) == 0) {\n        /*Normally use the label's width as width*/\n        w = lv_area_get_width(coords);\n    } else {\n        /*If EXAPND is enabled then not limit the text's width to the object's width*/\n        lv_point_t p;\n        lv_txt_get_size(&p, txt, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX,\n                        flag);\n        w = p.x;\n    }\n\n    lv_coord_t line_height = lv_font_get_line_height(font) + style->text.line_space;\n\n    /*Init variables for the first line*/\n    lv_coord_t line_width = 0;\n    lv_point_t pos;\n    pos.x = coords->x1;\n    pos.y = coords->y1;\n\n    lv_coord_t x_ofs = 0;\n    lv_coord_t y_ofs = 0;\n    if(offset != NULL) {\n        x_ofs = offset->x;\n        y_ofs = offset->y;\n        pos.y += y_ofs;\n    }\n\n    uint32_t line_start     = 0;\n    int32_t last_line_start = -1;\n\n    /*Check the hint to use the cached info*/\n    if(hint && y_ofs == 0 && coords->y1 < 0) {\n        /*If the label changed too much recalculate the hint.*/\n        if(LV_MATH_ABS(hint->coord_y - coords->y1) > LV_LABEL_HINT_UPDATE_TH - 2 * line_height) {\n            hint->line_start = -1;\n        }\n        last_line_start = hint->line_start;\n    }\n\n    /*Use the hint if it's valid*/\n    if(hint && last_line_start >= 0) {\n        line_start = last_line_start;\n        pos.y += hint->y;\n    }\n\n    uint32_t line_end = line_start + lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, flag);\n\n    /*Go the first visible line*/\n    while(pos.y + line_height < mask->y1) {\n        /*Go to next line*/\n        line_start = line_end;\n        line_end += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, flag);\n        pos.y += line_height;\n\n        /*Save at the threshold coordinate*/\n        if(hint && pos.y >= -LV_LABEL_HINT_UPDATE_TH && hint->line_start < 0) {\n            hint->line_start = line_start;\n            hint->y          = pos.y - coords->y1;\n            hint->coord_y    = coords->y1;\n        }\n\n        if(txt[line_start] == '\\0') return;\n    }\n\n    /*Align to middle*/\n    if(flag & LV_TXT_FLAG_CENTER) {\n        line_width = lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);\n\n        pos.x += (lv_area_get_width(coords) - line_width) / 2;\n\n    }\n    /*Align to the right*/\n    else if(flag & LV_TXT_FLAG_RIGHT) {\n        line_width = lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);\n        pos.x += lv_area_get_width(coords) - line_width;\n    }\n\n    lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->text.opa : (uint16_t)((uint16_t)style->text.opa * opa_scale) >> 8;\n\n    cmd_state_t cmd_state = CMD_STATE_WAIT;\n    uint32_t i;\n    uint16_t par_start = 0;\n    lv_color_t recolor;\n    lv_coord_t letter_w;\n    lv_style_t sel_style;\n    lv_style_copy(&sel_style, &lv_style_plain_color);\n    sel_style.body.main_color = sel_style.body.grad_color = style->text.sel_color;\n\n    /*Write out all lines*/\n    while(txt[line_start] != '\\0') {\n        if(offset != NULL) {\n            pos.x += x_ofs;\n        }\n        /*Write all letter of a line*/\n        cmd_state = CMD_STATE_WAIT;\n        i         = line_start;\n        uint32_t letter;\n        uint32_t letter_next;\n        while(i < line_end) {\n            letter      = lv_txt_encoded_next(txt, &i);\n            letter_next = lv_txt_encoded_next(&txt[i], NULL);\n\n            /*Handle the re-color command*/\n            if((flag & LV_TXT_FLAG_RECOLOR) != 0) {\n                if(letter == (uint32_t)LV_TXT_COLOR_CMD[0]) {\n                    if(cmd_state == CMD_STATE_WAIT) { /*Start char*/\n                        par_start = i;\n                        cmd_state = CMD_STATE_PAR;\n                        continue;\n                    } else if(cmd_state == CMD_STATE_PAR) { /*Other start char in parameter escaped cmd. char */\n                        cmd_state = CMD_STATE_WAIT;\n                    } else if(cmd_state == CMD_STATE_IN) { /*Command end */\n                        cmd_state = CMD_STATE_WAIT;\n                        continue;\n                    }\n                }\n\n                /*Skip the color parameter and wait the space after it*/\n                if(cmd_state == CMD_STATE_PAR) {\n                    if(letter == ' ') {\n                        /*Get the parameter*/\n                        if(i - par_start == LABEL_RECOLOR_PAR_LENGTH + 1) {\n                            char buf[LABEL_RECOLOR_PAR_LENGTH + 1];\n                            memcpy(buf, &txt[par_start], LABEL_RECOLOR_PAR_LENGTH);\n                            buf[LABEL_RECOLOR_PAR_LENGTH] = '\\0';\n                            int r, g, b;\n                            r       = (hex_char_to_num(buf[0]) << 4) + hex_char_to_num(buf[1]);\n                            g       = (hex_char_to_num(buf[2]) << 4) + hex_char_to_num(buf[3]);\n                            b       = (hex_char_to_num(buf[4]) << 4) + hex_char_to_num(buf[5]);\n                            recolor = lv_color_make(r, g, b);\n                        } else {\n                            recolor.full = style->text.color.full;\n                        }\n                        cmd_state = CMD_STATE_IN; /*After the parameter the text is in the command*/\n                    }\n                    continue;\n                }\n            }\n\n            lv_color_t color = style->text.color;\n\n            if(cmd_state == CMD_STATE_IN) color = recolor;\n\n            letter_w = lv_font_get_glyph_width(font, letter, letter_next);\n\n            if(sel_start != 0xFFFF && sel_end != 0xFFFF) {\n                int char_ind = lv_encoded_get_char_id(txt, i);\n                /*Do not draw the rectangle on the character at `sel_start`.*/\n                if(char_ind > sel_start && char_ind <= sel_end) {\n                    lv_area_t sel_coords;\n                    sel_coords.x1 = pos.x;\n                    sel_coords.y1 = pos.y;\n                    sel_coords.x2 = pos.x + letter_w + style->text.letter_space - 1;\n                    sel_coords.y2 = pos.y + line_height - 1;\n                    lv_draw_rect(&sel_coords, mask, &sel_style, opa);\n                }\n            }\n            lv_draw_letter(&pos, mask, font, letter, color, opa);\n\n            if(letter_w > 0) {\n                pos.x += letter_w + style->text.letter_space;\n            }\n        }\n        /*Go to next line*/\n        line_start = line_end;\n        line_end += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, flag);\n\n        pos.x = coords->x1;\n        /*Align to middle*/\n        if(flag & LV_TXT_FLAG_CENTER) {\n            line_width =\n                lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);\n\n            pos.x += (lv_area_get_width(coords) - line_width) / 2;\n\n        }\n        /*Align to the right*/\n        else if(flag & LV_TXT_FLAG_RIGHT) {\n            line_width =\n                lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);\n            pos.x += lv_area_get_width(coords) - line_width;\n        }\n\n        /*Go the next line position*/\n        pos.y += line_height;\n\n        if(pos.y > mask->y2) return;\n    }\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Convert a hexadecimal characters to a number (0..15)\n * @param hex Pointer to a hexadecimal character (0..9, A..F)\n * @return the numerical value of `hex` or 0 on error\n */\nstatic uint8_t hex_char_to_num(char hex)\n{\n    uint8_t result = 0;\n\n    if(hex >= '0' && hex <= '9') {\n        result = hex - '0';\n    } else {\n        if(hex >= 'a') hex -= 'a' - 'A'; /*Convert to upper case*/\n\n        switch(hex) {\n            case 'A': result = 10; break;\n            case 'B': result = 11; break;\n            case 'C': result = 12; break;\n            case 'D': result = 13; break;\n            case 'E': result = 14; break;\n            case 'F': result = 15; break;\n            default: result = 0; break;\n        }\n    }\n\n    return result;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_draw/lv_draw_line.c",
    "content": "/**\n * @file lv_draw_line.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include <stdio.h>\n#include \"utils/types.h\"\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_core/lv_refr.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\ntypedef struct\n{\n    lv_point_t p1;\n    lv_point_t p2;\n    lv_point_t p_act;\n    lv_coord_t dx;\n    lv_coord_t sx; /*-1: x1 < x2; 1: x2 >= x1*/\n    lv_coord_t dy;\n    lv_coord_t sy; /*-1: y1 < y2; 1: y2 >= y1*/\n    lv_coord_t err;\n    lv_coord_t e2;\n    bool hor; /*Rather horizontal or vertical*/\n} line_draw_t;\n\ntypedef struct\n{\n    lv_coord_t width;\n    lv_coord_t width_1;\n    lv_coord_t width_half;\n} line_width_t;\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic void line_draw_hor(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style,\n                          lv_opa_t opa_scale);\nstatic void line_draw_ver(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style,\n                          lv_opa_t opa_scale);\nstatic void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_t * mask, const lv_style_t * style,\n                           lv_opa_t opa_scale);\nstatic void line_init(line_draw_t * line, const lv_point_t * p1, const lv_point_t * p2);\nstatic bool line_next(line_draw_t * line);\nstatic bool line_next_y(line_draw_t * line);\nstatic bool line_next_x(line_draw_t * line);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Draw a line\n * @param point1 first point of the line\n * @param point2 second point of the line\n * @param mask the line will be drawn only on this area\n * @param style pointer to a line's style\n * @param opa_scale scale down all opacities by the factor\n */\nvoid lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * mask,\n                  const lv_style_t * style, lv_opa_t opa_scale)\n{\n\n    if(style->line.width == 0) return;\n    if(point1->x == point2->x && point1->y == point2->y) return;\n\n    /*Return if the points are out of the mask*/\n    if(point1->x < mask->x1 - style->line.width && point2->x < mask->x1 - style->line.width) return;\n    if(point1->x > mask->x2 + style->line.width && point2->x > mask->x2 + style->line.width) return;\n    if(point1->y < mask->y1 - style->line.width && point2->y < mask->y1 - style->line.width) return;\n    if(point1->y > mask->y2 + style->line.width && point2->y > mask->y2 + style->line.width) return;\n\n    line_draw_t main_line;\n    lv_point_t p1;\n    lv_point_t p2;\n\n    /*If the line if rather vertical then be sure y1 < y2 else x1 < x2*/\n\n    if(LV_MATH_ABS(point1->x - point2->x) > LV_MATH_ABS(point1->y - point2->y)) {\n\n        /*Steps less in y then x -> rather horizontal*/\n        if(point1->x < point2->x) {\n            p1.x = point1->x;\n            p1.y = point1->y;\n            p2.x = point2->x;\n            p2.y = point2->y;\n        } else {\n            p1.x = point2->x;\n            p1.y = point2->y;\n            p2.x = point1->x;\n            p2.y = point1->y;\n        }\n    } else {\n        /*Steps less in x then y -> rather vertical*/\n        if(point1->y < point2->y) {\n            p1.x = point1->x;\n            p1.y = point1->y;\n            p2.x = point2->x;\n            p2.y = point2->y;\n        } else {\n            p1.x = point2->x;\n            p1.y = point2->y;\n            p2.x = point1->x;\n            p2.y = point1->y;\n        }\n    }\n\n    line_init(&main_line, &p1, &p2);\n\n    /*Special case draw a horizontal line*/\n    if(main_line.p1.y == main_line.p2.y) {\n        line_draw_hor(&main_line, mask, style, opa_scale);\n    }\n    /*Special case draw a vertical line*/\n    else if(main_line.p1.x == main_line.p2.x) {\n        line_draw_ver(&main_line, mask, style, opa_scale);\n    }\n    /*Arbitrary skew line*/\n    else {\n        bool dir_ori = false;\n#if LV_ANTIALIAS\n        bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());\n        if(aa) {\n            lv_point_t p_tmp;\n\n            if(main_line.hor) {\n                if(main_line.p1.y < main_line.p2.y) {\n                    dir_ori = true;\n                    p_tmp.x = main_line.p2.x;\n                    p_tmp.y = main_line.p2.y - 1;\n                    line_init(&main_line, &p1, &p_tmp);\n                    main_line.sy = LV_MATH_ABS(main_line.sy); /*The sign can change if the line becomes horizontal*/\n                } else if(main_line.p1.y > main_line.p2.y) {\n                    dir_ori = false;\n                    p_tmp.x = main_line.p2.x;\n                    p_tmp.y = main_line.p2.y + 1;\n                    line_init(&main_line, &p1, &p_tmp);\n                    main_line.sy = -LV_MATH_ABS(main_line.sy); /*The sign can change if the line becomes horizontal*/\n                }\n            } else {\n                if(main_line.p1.x < main_line.p2.x) {\n                    dir_ori = true;\n                    p_tmp.x = main_line.p2.x - 1;\n                    p_tmp.y = main_line.p2.y;\n                    line_init(&main_line, &p1, &p_tmp);\n                    main_line.sx = LV_MATH_ABS(main_line.sx); /*The sign can change if the line becomes vertical*/\n                } else if(main_line.p1.x > main_line.p2.x) {\n                    dir_ori = false;\n                    p_tmp.x = main_line.p2.x + 1;\n                    p_tmp.y = main_line.p2.y;\n                    line_init(&main_line, &p1, &p_tmp);\n                    main_line.sx = -LV_MATH_ABS(main_line.sx); /*The sign can change if the line becomes vertical*/\n                }\n            }\n        }\n#endif\n        line_draw_skew(&main_line, dir_ori, mask, style, opa_scale);\n    }\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\nstatic void line_draw_hor(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)\n{\n    lv_coord_t width      = style->line.width - 1;\n    lv_coord_t width_half = width >> 1;\n    lv_coord_t width_1    = width & 0x1;\n    lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->line.opa : (uint16_t)((uint16_t)style->line.opa * opa_scale) >> 8;\n\n    lv_area_t act_area;\n    act_area.x1 = main_line->p1.x;\n    act_area.x2 = main_line->p2.x;\n    act_area.y1 = main_line->p1.y - width_half - width_1;\n    act_area.y2 = main_line->p2.y + width_half;\n\n    lv_area_t draw_area;\n    draw_area.x1 = LV_MATH_MIN(act_area.x1, act_area.x2);\n    draw_area.x2 = LV_MATH_MAX(act_area.x1, act_area.x2);\n    draw_area.y1 = LV_MATH_MIN(act_area.y1, act_area.y2);\n    draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2);\n    lv_draw_fill(&draw_area, mask, style->line.color, opa);\n}\n\nstatic void line_draw_ver(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)\n{\n    lv_coord_t width      = style->line.width - 1;\n    lv_coord_t width_half = width >> 1;\n    lv_coord_t width_1    = width & 0x1;\n    lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->line.opa : (uint16_t)((uint16_t)style->line.opa * opa_scale) >> 8;\n\n    lv_area_t act_area;\n    act_area.x1 = main_line->p1.x - width_half;\n    act_area.x2 = main_line->p2.x + width_half + width_1;\n    act_area.y1 = main_line->p1.y;\n    act_area.y2 = main_line->p2.y;\n\n    lv_area_t draw_area;\n    draw_area.x1 = LV_MATH_MIN(act_area.x1, act_area.x2);\n    draw_area.x2 = LV_MATH_MAX(act_area.x1, act_area.x2);\n    draw_area.y1 = LV_MATH_MIN(act_area.y1, act_area.y2);\n    draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2);\n    lv_draw_fill(&draw_area, mask, style->line.color, opa);\n}\n\nstatic void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_t * mask, const lv_style_t * style,\n                           lv_opa_t opa_scale)\n{\n\n    lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->line.opa : (uint16_t)((uint16_t)style->line.opa * opa_scale) >> 8;\n#if LV_ANTIALIAS\n    bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());\n#endif\n    lv_point_t vect_main, vect_norm;\n    vect_main.x = main_line->p2.x - main_line->p1.x;\n    vect_main.y = main_line->p2.y - main_line->p1.y;\n\n    if(main_line->hor) {\n        if(main_line->p1.y < main_line->p2.y + dir_ori) {\n            vect_norm.x = -vect_main.y;\n            vect_norm.y = vect_main.x;\n        } else {\n            vect_norm.x = vect_main.y;\n            vect_norm.y = -vect_main.x;\n        }\n    } else {\n        if(main_line->p1.x < main_line->p2.x + dir_ori) {\n            vect_norm.x = vect_main.y;\n            vect_norm.y = -vect_main.x;\n        } else {\n            vect_norm.x = -vect_main.y;\n            vect_norm.y = vect_main.x;\n        }\n    }\n\n    /* In case of a short but tick line the perpendicular ending is longer then the real line.\n     * it would break the calculations so make the normal vector larger*/\n    vect_norm.x = vect_norm.x << 4;\n    vect_norm.y = vect_norm.y << 4;\n\n    lv_coord_t width;\n    width = style->line.width;\n\n    /* The pattern stores the points of the line ending. It has the good direction and length.\n     * The worth case is the 45° line where pattern can have 1.41 x `width` points*/\n\n    lv_coord_t pattern_size = width * 2;\n    lv_point_t * pattern = lv_draw_get_buf(pattern_size * sizeof(lv_point_t));\n    lv_coord_t i = 0;\n\n    /*Create a perpendicular pattern (a small line)*/\n    if(width != 0) {\n        line_draw_t pattern_line;\n        lv_point_t p0 = {0, 0};\n        line_init(&pattern_line, &p0, &vect_norm);\n\n        uint32_t width_sqr = width * width;\n        /* Run for a lot of times. Meanwhile the real width will be determined as well */\n        for(i = 0; i < (lv_coord_t)pattern_size - 1; i++) {\n            pattern[i].x = pattern_line.p_act.x;\n            pattern[i].y = pattern_line.p_act.y;\n\n            /*Finish the pattern line if it's length equal to the desired width (Use Pythagoras\n             * theorem)*/\n            uint32_t sqr = pattern_line.p_act.x * pattern_line.p_act.x + pattern_line.p_act.y * pattern_line.p_act.y;\n            if(sqr >= width_sqr) {\n                width = i;\n#if LV_ANTIALIAS\n                if(aa) width--;\n#endif\n                break;\n            }\n\n            line_next(&pattern_line);\n        }\n    }\n\n#if LV_ANTIALIAS\n    lv_coord_t aa_last_corner;\n    lv_coord_t width_safe = width;\n    if(aa) {\n        if(width == 0) width_safe = 1;\n\n        aa_last_corner = 0;\n    }\n#endif\n\n    lv_coord_t x_center_ofs = 0;\n    lv_coord_t y_center_ofs = 0;\n\n    if(width != 0) {\n        x_center_ofs = pattern[width - 1].x / 2;\n        y_center_ofs = pattern[width - 1].y / 2;\n    } else {\n        if(main_line->hor && main_line->p1.y >= main_line->p2.y + dir_ori) pattern[0].y--;\n        if(!main_line->hor && main_line->p1.x >= main_line->p2.x + dir_ori) pattern[0].x--;\n    }\n\n    /* Make the coordinates relative to the center */\n    for(i = 0; i < width; i++) {\n        pattern[i].x -= x_center_ofs;\n        pattern[i].y -= y_center_ofs;\n#if LV_ANTIALIAS\n        if(aa) {\n            if(i != 0) {\n                if(main_line->hor) {\n                    if(pattern[i - 1].x != pattern[i].x) {\n                        lv_coord_t seg_w = pattern[i].y - pattern[aa_last_corner].y;\n                        if(main_line->sy < 0) {\n                            lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1,\n                                               main_line->p1.y + pattern[aa_last_corner].y + seg_w + 1, seg_w, mask,\n                                               style->line.color, opa);\n\n                            lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1,\n                                               main_line->p2.y + pattern[aa_last_corner].y + seg_w + 1, -seg_w, mask,\n                                               style->line.color, opa);\n                        } else {\n                            lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1,\n                                               main_line->p1.y + pattern[aa_last_corner].y, seg_w, mask,\n                                               style->line.color, opa);\n\n                            lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1,\n                                               main_line->p2.y + pattern[aa_last_corner].y, -seg_w, mask,\n                                               style->line.color, opa);\n                        }\n                        aa_last_corner = i;\n                    }\n                } else {\n                    if(pattern[i - 1].y != pattern[i].y) {\n                        lv_coord_t seg_w = pattern[i].x - pattern[aa_last_corner].x;\n                        if(main_line->sx < 0) {\n                            lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x + seg_w + 1,\n                                               main_line->p1.y + pattern[aa_last_corner].y - 1, seg_w, mask,\n                                               style->line.color, opa);\n\n                            lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x + seg_w + 1,\n                                               main_line->p2.y + pattern[aa_last_corner].y + 1, -seg_w, mask,\n                                               style->line.color, opa);\n                        } else {\n                            lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x,\n                                               main_line->p1.y + pattern[aa_last_corner].y - 1, seg_w, mask,\n                                               style->line.color, opa);\n\n                            lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x,\n                                               main_line->p2.y + pattern[aa_last_corner].y + 1, -seg_w, mask,\n                                               style->line.color, opa);\n                        }\n                        aa_last_corner = i;\n                    }\n                }\n            }\n        }\n#endif\n    }\n\n#if LV_ANTIALIAS\n    /*Add the last part of anti-aliasing for the perpendicular ending*/\n    if(width != 0 && aa) { /*Due to rounding error with very thin lines it looks ugly*/\n        if(main_line->hor) {\n            lv_coord_t seg_w = pattern[width_safe - 1].y - pattern[aa_last_corner].y;\n            if(main_line->sy < 0) {\n                lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1,\n                                   main_line->p1.y + pattern[aa_last_corner].y + seg_w, seg_w + main_line->sy, mask,\n                                   style->line.color, opa);\n\n                lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1,\n                                   main_line->p2.y + pattern[aa_last_corner].y + seg_w, -(seg_w + main_line->sy), mask,\n                                   style->line.color, opa);\n\n            } else {\n                lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1,\n                                   main_line->p1.y + pattern[aa_last_corner].y, seg_w + main_line->sy, mask,\n                                   style->line.color, opa);\n\n                lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1,\n                                   main_line->p2.y + pattern[aa_last_corner].y, -(seg_w + main_line->sy), mask,\n                                   style->line.color, opa);\n            }\n        } else {\n            lv_coord_t seg_w = pattern[width_safe - 1].x - pattern[aa_last_corner].x;\n            if(main_line->sx < 0) {\n                lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x + seg_w,\n                                   main_line->p1.y + pattern[aa_last_corner].y - 1, seg_w + main_line->sx, mask,\n                                   style->line.color, opa);\n\n                lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x + seg_w,\n                                   main_line->p2.y + pattern[aa_last_corner].y + 1, -(seg_w + main_line->sx), mask,\n                                   style->line.color, opa);\n\n            } else {\n                lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x,\n                                   main_line->p1.y + pattern[aa_last_corner].y - 1, seg_w + main_line->sx, mask,\n                                   style->line.color, opa);\n\n                lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x,\n                                   main_line->p2.y + pattern[aa_last_corner].y + 1, -(seg_w + main_line->sx), mask,\n                                   style->line.color, opa);\n            }\n        }\n    }\n#endif\n\n#if LV_ANTIALIAS\n\n    /*Shift the anti aliasing on the edges (-1, 1 or 0 (zero only in case width == 0))*/\n    lv_coord_t aa_shift1 = 0;\n    lv_coord_t aa_shift2 = 0;\n    if(aa) {\n        if(main_line->hor == false) {\n            if(main_line->sx < 0) {\n                aa_shift1 = -1;\n                aa_shift2 = width == 0 ? 0 : aa_shift1;\n            } else {\n                aa_shift2 = 1;\n                aa_shift1 = width == 0 ? 0 : aa_shift2;\n            }\n        } else {\n            if(main_line->sy < 0) {\n                aa_shift1 = -1;\n                aa_shift2 = width == 0 ? 0 : aa_shift1;\n            } else {\n                aa_shift2 = 1;\n                aa_shift1 = width == 0 ? 0 : aa_shift2;\n            }\n        }\n    }\n#endif\n\n    volatile lv_point_t prev_p;\n    prev_p.x = main_line->p1.x;\n    prev_p.y = main_line->p1.y;\n    lv_area_t draw_area;\n    bool first_run = true;\n\n    if(main_line->hor) {\n        while(line_next_y(main_line)) {\n            for(i = 0; i < width; i++) {\n                draw_area.x1 = prev_p.x + pattern[i].x;\n                draw_area.y1 = prev_p.y + pattern[i].y;\n                draw_area.x2 = draw_area.x1 + main_line->p_act.x - prev_p.x - 1;\n                draw_area.y2 = draw_area.y1;\n                lv_draw_fill(&draw_area, mask, style->line.color, opa);\n\n                /* Fill the gaps\n                 * When stepping in y one pixel remains empty on every corner (don't do this on the\n                 * first segment ) */\n                if(i != 0 && pattern[i].x != pattern[i - 1].x && !first_run) {\n                    lv_draw_px(draw_area.x1, draw_area.y1 - main_line->sy, mask, style->line.color, opa);\n                }\n            }\n\n#if LV_ANTIALIAS\n            if(aa) {\n                lv_draw_aa_hor_seg(prev_p.x + pattern[0].x, prev_p.y + pattern[0].y - aa_shift1,\n                                   -(main_line->p_act.x - prev_p.x), mask, style->line.color, opa);\n                lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x,\n                                   prev_p.y + pattern[width_safe - 1].y + aa_shift2, main_line->p_act.x - prev_p.x,\n                                   mask, style->line.color, opa);\n            }\n#endif\n\n            first_run = false;\n\n            prev_p.x = main_line->p_act.x;\n            prev_p.y = main_line->p_act.y;\n        }\n\n        for(i = 0; i < width; i++) {\n            draw_area.x1 = prev_p.x + pattern[i].x;\n            draw_area.y1 = prev_p.y + pattern[i].y;\n            draw_area.x2 = draw_area.x1 + main_line->p_act.x - prev_p.x;\n            draw_area.y2 = draw_area.y1;\n            lv_draw_fill(&draw_area, mask, style->line.color, opa);\n\n            /* Fill the gaps\n             * When stepping in y one pixel remains empty on every corner */\n            if(i != 0 && pattern[i].x != pattern[i - 1].x && !first_run) {\n                lv_draw_px(draw_area.x1, draw_area.y1 - main_line->sy, mask, style->line.color, opa);\n            }\n        }\n\n#if LV_ANTIALIAS\n        if(aa) {\n            lv_draw_aa_hor_seg(prev_p.x + pattern[0].x, prev_p.y + pattern[0].y - aa_shift1,\n                               -(main_line->p_act.x - prev_p.x + 1), mask, style->line.color, opa);\n            lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x, prev_p.y + pattern[width_safe - 1].y + aa_shift2,\n                               main_line->p_act.x - prev_p.x + 1, mask, style->line.color, opa);\n        }\n#endif\n    }\n    /*Rather a vertical line*/\n    else {\n\n        while(line_next_x(main_line)) {\n            for(i = 0; i < width; i++) {\n                draw_area.x1 = prev_p.x + pattern[i].x;\n                draw_area.y1 = prev_p.y + pattern[i].y;\n                draw_area.x2 = draw_area.x1;\n                draw_area.y2 = draw_area.y1 + main_line->p_act.y - prev_p.y - 1;\n\n                lv_draw_fill(&draw_area, mask, style->line.color, opa);\n\n                /* Fill the gaps\n                 * When stepping in x one pixel remains empty on every corner (don't do this on the\n                 * first segment ) */\n                if(i != 0 && pattern[i].y != pattern[i - 1].y && !first_run) {\n                    lv_draw_px(draw_area.x1 - main_line->sx, draw_area.y1, mask, style->line.color, opa);\n                }\n            }\n\n#if LV_ANTIALIAS\n            if(aa) {\n                lv_draw_aa_ver_seg(prev_p.x + pattern[0].x - aa_shift1, prev_p.y + pattern[0].y,\n                                   -(main_line->p_act.y - prev_p.y), mask, style->line.color, opa);\n                lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2,\n                                   prev_p.y + pattern[width_safe - 1].y, main_line->p_act.y - prev_p.y, mask,\n                                   style->line.color, opa);\n            }\n#endif\n\n            first_run = false;\n\n            prev_p.x = main_line->p_act.x;\n            prev_p.y = main_line->p_act.y;\n        }\n\n        /*Draw the last part*/\n        for(i = 0; i < width; i++) {\n            draw_area.x1 = prev_p.x + pattern[i].x;\n            draw_area.y1 = prev_p.y + pattern[i].y;\n            draw_area.x2 = draw_area.x1;\n            draw_area.y2 = draw_area.y1 + main_line->p_act.y - prev_p.y;\n\n            lv_draw_fill(&draw_area, mask, style->line.color, opa);\n\n            /* Fill the gaps\n             * When stepping in x one pixel remains empty on every corner */\n            if(i != 0 && pattern[i].y != pattern[i - 1].y && !first_run) {\n                lv_draw_px(draw_area.x1 - main_line->sx, draw_area.y1, mask, style->line.color, opa);\n            }\n        }\n\n#if LV_ANTIALIAS\n        if(aa) {\n            lv_draw_aa_ver_seg(prev_p.x + pattern[0].x - aa_shift1, prev_p.y + pattern[0].y,\n                               -(main_line->p_act.y - prev_p.y + 1), mask, style->line.color, opa);\n            lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2, prev_p.y + pattern[width_safe - 1].y,\n                               main_line->p_act.y - prev_p.y + 1, mask, style->line.color, opa);\n        }\n#endif\n    }\n}\n\nstatic void line_init(line_draw_t * line, const lv_point_t * p1, const lv_point_t * p2)\n{\n    line->p1.x = p1->x;\n    line->p1.y = p1->y;\n    line->p2.x = p2->x;\n    line->p2.y = p2->y;\n\n    line->dx  = LV_MATH_ABS(line->p2.x - line->p1.x);\n    line->sx  = line->p1.x < line->p2.x ? 1 : -1;\n    line->dy  = LV_MATH_ABS(line->p2.y - line->p1.y);\n    line->sy  = line->p1.y < line->p2.y ? 1 : -1;\n    line->err = (line->dx > line->dy ? line->dx : -line->dy) / 2;\n    line->e2  = 0;\n    line->hor = line->dx > line->dy ? true : false; /*Rather horizontal or vertical*/\n\n    line->p_act.x = line->p1.x;\n    line->p_act.y = line->p1.y;\n}\n\nstatic bool line_next(line_draw_t * line)\n{\n    if(line->p_act.x == line->p2.x && line->p_act.y == line->p2.y) return false;\n    line->e2 = line->err;\n    if(line->e2 > -line->dx) {\n        line->err -= line->dy;\n        line->p_act.x += line->sx;\n    }\n    if(line->e2 < line->dy) {\n        line->err += line->dx;\n        line->p_act.y += line->sy;\n    }\n    return true;\n}\n\n/**\n * Iterate until step one in y direction.\n * @param line\n * @return\n */\nstatic bool line_next_y(line_draw_t * line)\n{\n    lv_coord_t last_y = line->p_act.y;\n\n    do {\n        if(!line_next(line)) return false;\n    } while(last_y == line->p_act.y);\n\n    return true;\n}\n\n/**\n * Iterate until step one in x direction.\n * @param line\n * @return\n */\nstatic bool line_next_x(line_draw_t * line)\n{\n    lv_coord_t last_x = line->p_act.x;\n\n    do {\n        if(!line_next(line)) return false;\n    } while(last_x == line->p_act.x);\n\n    return true;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_draw/lv_draw_rect.c",
    "content": "/**\n * @file lv_draw_rect.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_draw/lv_draw_rect.h\"\n#include \"libs/lvgl/lv_misc/lv_circ.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n#include \"libs/lvgl/lv_core/lv_refr.h\"\n\n/*********************\n *      DEFINES\n *********************/\n/*Circle segment greater then this value will be anti-aliased by a non-linear (cos) opacity\n * mapping*/\n#define CIRCLE_AA_NON_LINEAR_OPA_THRESHOLD 1\n\n/*Calculate with 2^x bigger shadow opacity values to avoid rounding errors*/\n#define SHADOW_OPA_EXTRA_PRECISION 8\n\n/*Add extra radius with LV_SHADOW_BOTTOM to cover anti-aliased corners*/\n#define SHADOW_BOTTOM_AA_EXTRA_RADIUS 3\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic void lv_draw_rect_main_mid(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,\n                                  lv_opa_t opa_scale);\nstatic void lv_draw_rect_main_corner(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,\n                                     lv_opa_t opa_scale);\nstatic void lv_draw_rect_border_straight(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,\n                                         lv_opa_t opa_scale);\nstatic void lv_draw_rect_border_corner(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,\n                                       lv_opa_t opa_scale);\n\n#if LV_USE_SHADOW\nstatic void lv_draw_shadow(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,\n                           lv_opa_t opa_scale);\nstatic void lv_draw_shadow_full(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,\n                                lv_opa_t opa_scale);\nstatic void lv_draw_shadow_bottom(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,\n                                  lv_opa_t opa_scale);\nstatic void lv_draw_shadow_full_straight(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,\n                                         const lv_opa_t * map);\n#endif\n\nstatic uint16_t lv_draw_cont_radius_corr(uint16_t r, lv_coord_t w, lv_coord_t h);\n\n#if LV_ANTIALIAS\nstatic lv_opa_t antialias_get_opa_circ(lv_coord_t seg, lv_coord_t px_id, lv_opa_t opa);\n#endif\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Draw a rectangle\n * @param coords the coordinates of the rectangle\n * @param mask the rectangle will be drawn only in this mask\n * @param style pointer to a style\n * @param opa_scale scale down all opacities by the factor\n */\nvoid lv_draw_rect(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)\n{\n    if(lv_area_get_height(coords) < 1 || lv_area_get_width(coords) < 1) return;\n\n#if LV_USE_SHADOW\n    if(style->body.shadow.width != 0) {\n        lv_draw_shadow(coords, mask, style, opa_scale);\n    }\n#endif\n\n    /* If the object is out of the mask there is nothing to draw.\n     * Draw shadow before it because the shadow is out of `coords`*/\n    if(lv_area_is_on(coords, mask) == false) return;\n\n    if(style->body.opa > LV_OPA_MIN) {\n        lv_draw_rect_main_mid(coords, mask, style, opa_scale);\n\n        if(style->body.radius != 0) {\n            lv_draw_rect_main_corner(coords, mask, style, opa_scale);\n        }\n    }\n\n    if(style->body.border.width != 0 && style->body.border.part != LV_BORDER_NONE &&\n       style->body.border.opa >= LV_OPA_MIN) {\n        lv_draw_rect_border_straight(coords, mask, style, opa_scale);\n\n        if(style->body.radius != 0) {\n            lv_draw_rect_border_corner(coords, mask, style, opa_scale);\n        }\n    }\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Draw the middle part (rectangular) of a rectangle\n * @param coords the coordinates of the original rectangle\n * @param mask the rectangle will be drawn only  on this area\n * @param rects_p pointer to a rectangle style\n * @param opa_scale scale down all opacities by the factor\n */\nstatic void lv_draw_rect_main_mid(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,\n                                  lv_opa_t opa_scale)\n{\n    uint16_t radius = style->body.radius;\n    bool aa         = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());\n\n    lv_color_t mcolor = style->body.main_color;\n    lv_color_t gcolor = style->body.grad_color;\n    uint8_t mix;\n    lv_coord_t height = lv_area_get_height(coords);\n    lv_coord_t width  = lv_area_get_width(coords);\n    lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->body.opa : (uint16_t)((uint16_t)style->body.opa * opa_scale) >> 8;\n\n    radius = lv_draw_cont_radius_corr(radius, width, height);\n\n    /*If the radius is too big then there is no body*/\n    if(radius > height / 2) return;\n\n    lv_area_t work_area;\n    work_area.x1 = coords->x1;\n    work_area.x2 = coords->x2;\n\n    if(mcolor.full == gcolor.full) {\n        work_area.y1 = coords->y1 + radius;\n        work_area.y2 = coords->y2 - radius;\n\n        if(style->body.radius != 0) {\n\n            if(aa) {\n                work_area.y1 += 2;\n                work_area.y2 -= 2;\n            } else {\n                work_area.y1 += 1;\n                work_area.y2 -= 1;\n            }\n        }\n\n        lv_draw_fill(&work_area, mask, mcolor, opa);\n    } else {\n        lv_coord_t row;\n        lv_coord_t row_start = coords->y1 + radius;\n        lv_coord_t row_end   = coords->y2 - radius;\n        lv_color_t act_color;\n\n        if(style->body.radius != 0) {\n            if(aa) {\n                row_start += 2;\n                row_end -= 2;\n            } else {\n                row_start += 1;\n                row_end -= 1;\n            }\n        }\n        if(row_start < 0) row_start = 0;\n\n        for(row = row_start; row <= row_end; row++) {\n            work_area.y1 = row;\n            work_area.y2 = row;\n            mix          = (uint32_t)((uint32_t)(coords->y2 - work_area.y1) * 255) / height;\n            act_color    = lv_color_mix(mcolor, gcolor, mix);\n\n            lv_draw_fill(&work_area, mask, act_color, opa);\n        }\n    }\n}\n/**\n * Draw the top and bottom parts (corners) of a rectangle\n * @param coords the coordinates of the original rectangle\n * @param mask the rectangle will be drawn only  on this area\n * @param rects_p pointer to a rectangle style\n * @param opa_scale scale down all opacities by the factor\n */\nstatic void lv_draw_rect_main_corner(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,\n                                     lv_opa_t opa_scale)\n{\n    uint16_t radius = style->body.radius;\n    bool aa         = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());\n\n    lv_color_t mcolor = style->body.main_color;\n    lv_color_t gcolor = style->body.grad_color;\n    lv_color_t act_color;\n    lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->body.opa : (uint16_t)((uint16_t)style->body.opa * opa_scale) >> 8;\n    uint8_t mix;\n    lv_coord_t height = lv_area_get_height(coords);\n    lv_coord_t width  = lv_area_get_width(coords);\n\n    radius = lv_draw_cont_radius_corr(radius, width, height);\n\n    lv_point_t lt_origo; /*Left  Top    origo*/\n    lv_point_t lb_origo; /*Left  Bottom origo*/\n    lv_point_t rt_origo; /*Right Top    origo*/\n    lv_point_t rb_origo; /*Left  Bottom origo*/\n\n    lt_origo.x = coords->x1 + radius + aa;\n    lt_origo.y = coords->y1 + radius + aa;\n\n    lb_origo.x = coords->x1 + radius + aa;\n    lb_origo.y = coords->y2 - radius - aa;\n\n    rt_origo.x = coords->x2 - radius - aa;\n    rt_origo.y = coords->y1 + radius + aa;\n\n    rb_origo.x = coords->x2 - radius - aa;\n    rb_origo.y = coords->y2 - radius - aa;\n\n    lv_area_t edge_top_area;\n    lv_area_t mid_top_area;\n    lv_area_t mid_bot_area;\n    lv_area_t edge_bot_area;\n\n    lv_point_t cir;\n    lv_coord_t cir_tmp;\n    lv_circ_init(&cir, &cir_tmp, radius);\n\n    /*Init the areas*/\n    lv_area_set(&mid_bot_area, lb_origo.x + LV_CIRC_OCT4_X(cir), lb_origo.y + LV_CIRC_OCT4_Y(cir),\n                rb_origo.x + LV_CIRC_OCT1_X(cir), rb_origo.y + LV_CIRC_OCT1_Y(cir));\n\n    lv_area_set(&edge_bot_area, lb_origo.x + LV_CIRC_OCT3_X(cir), lb_origo.y + LV_CIRC_OCT3_Y(cir),\n                rb_origo.x + LV_CIRC_OCT2_X(cir), rb_origo.y + LV_CIRC_OCT2_Y(cir));\n\n    lv_area_set(&mid_top_area, lt_origo.x + LV_CIRC_OCT5_X(cir), lt_origo.y + LV_CIRC_OCT5_Y(cir),\n                rt_origo.x + LV_CIRC_OCT8_X(cir), rt_origo.y + LV_CIRC_OCT8_Y(cir));\n\n    lv_area_set(&edge_top_area, lt_origo.x + LV_CIRC_OCT6_X(cir), lt_origo.y + LV_CIRC_OCT6_Y(cir),\n                rt_origo.x + LV_CIRC_OCT7_X(cir), rt_origo.y + LV_CIRC_OCT7_Y(cir));\n#if LV_ANTIALIAS\n    /*Store some internal states for anti-aliasing*/\n    lv_coord_t out_y_seg_start = 0;\n    lv_coord_t out_y_seg_end   = 0;\n    lv_coord_t out_x_last      = radius;\n\n    lv_color_t aa_color_hor_top;\n    lv_color_t aa_color_hor_bottom;\n    lv_color_t aa_color_ver;\n#endif\n\n    while(lv_circ_cont(&cir)) {\n#if LV_ANTIALIAS\n        if(aa) {\n            /*New step in y on the outter circle*/\n            if(out_x_last != cir.x) {\n                out_y_seg_end       = cir.y;\n                lv_coord_t seg_size = out_y_seg_end - out_y_seg_start;\n                lv_point_t aa_p;\n\n                aa_p.x = out_x_last;\n                aa_p.y = out_y_seg_start;\n\n                mix                 = (uint32_t)((uint32_t)(radius - out_x_last) * 255) / height;\n                aa_color_hor_top    = lv_color_mix(gcolor, mcolor, mix);\n                aa_color_hor_bottom = lv_color_mix(mcolor, gcolor, mix);\n\n                lv_coord_t i;\n                for(i = 0; i < seg_size; i++) {\n                    lv_opa_t aa_opa;\n                    if(seg_size > CIRCLE_AA_NON_LINEAR_OPA_THRESHOLD) { /*Use non-linear opa mapping\n                                                                           on the first segment*/\n                        aa_opa = antialias_get_opa_circ(seg_size, i, opa);\n                    } else {\n                        aa_opa = opa - lv_draw_aa_get_opa(seg_size, i, opa);\n                    }\n\n                    lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) + 1, mask,\n                               aa_color_hor_bottom, aa_opa);\n                    lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) + 1, mask,\n                               aa_color_hor_bottom, aa_opa);\n                    lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) - 1, mask,\n                               aa_color_hor_top, aa_opa);\n                    lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) - 1, mask,\n                               aa_color_hor_top, aa_opa);\n\n                    mix          = (uint32_t)((uint32_t)(radius - out_y_seg_start + i) * 255) / height;\n                    aa_color_ver = lv_color_mix(mcolor, gcolor, mix);\n                    lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) + 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask,\n                               aa_color_ver, aa_opa);\n                    lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) - 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i, mask,\n                               aa_color_ver, aa_opa);\n\n                    aa_color_ver = lv_color_mix(gcolor, mcolor, mix);\n                    lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) - 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask,\n                               aa_color_ver, aa_opa);\n                    lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) + 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i, mask,\n                               aa_color_ver, aa_opa);\n                }\n\n                out_x_last      = cir.x;\n                out_y_seg_start = out_y_seg_end;\n            }\n        }\n#endif\n        uint8_t edge_top_refr = 0;\n        uint8_t mid_top_refr  = 0;\n        uint8_t mid_bot_refr  = 0;\n        uint8_t edge_bot_refr = 0;\n\n        /* If a new row coming draw the previous\n         * The y coordinate can remain the same so wait for a new*/\n        if(mid_bot_area.y1 != LV_CIRC_OCT4_Y(cir) + lb_origo.y) mid_bot_refr = 1;\n\n        if(edge_bot_area.y1 != LV_CIRC_OCT2_Y(cir) + lb_origo.y) edge_bot_refr = 1;\n\n        if(mid_top_area.y1 != LV_CIRC_OCT8_Y(cir) + lt_origo.y) mid_top_refr = 1;\n\n        if(edge_top_area.y1 != LV_CIRC_OCT7_Y(cir) + lt_origo.y) edge_top_refr = 1;\n\n        /*Draw the areas which are not disabled*/\n        if(edge_top_refr != 0) {\n            if(mcolor.full == gcolor.full)\n                act_color = mcolor;\n            else {\n                mix       = (uint32_t)((uint32_t)(coords->y2 - edge_top_area.y1) * 255) / height;\n                act_color = lv_color_mix(mcolor, gcolor, mix);\n            }\n            lv_draw_fill(&edge_top_area, mask, act_color, opa);\n        }\n\n        if(mid_top_refr != 0) {\n            if(mcolor.full == gcolor.full)\n                act_color = mcolor;\n            else {\n                mix       = (uint32_t)((uint32_t)(coords->y2 - mid_top_area.y1) * 255) / height;\n                act_color = lv_color_mix(mcolor, gcolor, mix);\n            }\n            lv_draw_fill(&mid_top_area, mask, act_color, opa);\n        }\n\n        if(mid_bot_refr != 0) {\n            if(mcolor.full == gcolor.full)\n                act_color = mcolor;\n            else {\n                mix       = (uint32_t)((uint32_t)(coords->y2 - mid_bot_area.y1) * 255) / height;\n                act_color = lv_color_mix(mcolor, gcolor, mix);\n            }\n            lv_draw_fill(&mid_bot_area, mask, act_color, opa);\n        }\n\n        if(edge_bot_refr != 0) {\n\n            if(mcolor.full == gcolor.full)\n                act_color = mcolor;\n            else {\n                mix       = (uint32_t)((uint32_t)(coords->y2 - edge_bot_area.y1) * 255) / height;\n                act_color = lv_color_mix(mcolor, gcolor, mix);\n            }\n            lv_draw_fill(&edge_bot_area, mask, act_color, opa);\n        }\n\n        /*Save the current coordinates*/\n        lv_area_set(&mid_bot_area, lb_origo.x + LV_CIRC_OCT4_X(cir), lb_origo.y + LV_CIRC_OCT4_Y(cir),\n                    rb_origo.x + LV_CIRC_OCT1_X(cir), rb_origo.y + LV_CIRC_OCT1_Y(cir));\n\n        lv_area_set(&edge_bot_area, lb_origo.x + LV_CIRC_OCT3_X(cir), lb_origo.y + LV_CIRC_OCT3_Y(cir),\n                    rb_origo.x + LV_CIRC_OCT2_X(cir), rb_origo.y + LV_CIRC_OCT2_Y(cir));\n\n        lv_area_set(&mid_top_area, lt_origo.x + LV_CIRC_OCT5_X(cir), lt_origo.y + LV_CIRC_OCT5_Y(cir),\n                    rt_origo.x + LV_CIRC_OCT8_X(cir), rt_origo.y + LV_CIRC_OCT8_Y(cir));\n\n        lv_area_set(&edge_top_area, lt_origo.x + LV_CIRC_OCT6_X(cir), lt_origo.y + LV_CIRC_OCT6_Y(cir),\n                    rt_origo.x + LV_CIRC_OCT7_X(cir), rt_origo.y + LV_CIRC_OCT7_Y(cir));\n\n        lv_circ_next(&cir, &cir_tmp);\n    }\n\n    if(mcolor.full == gcolor.full)\n        act_color = mcolor;\n    else {\n        mix       = (uint32_t)((uint32_t)(coords->y2 - edge_top_area.y1) * 255) / height;\n        act_color = lv_color_mix(mcolor, gcolor, mix);\n    }\n    lv_draw_fill(&edge_top_area, mask, act_color, opa);\n\n    if(edge_top_area.y1 != mid_top_area.y1) {\n\n        if(mcolor.full == gcolor.full)\n            act_color = mcolor;\n        else {\n            mix       = (uint32_t)((uint32_t)(coords->y2 - mid_top_area.y1) * 255) / height;\n            act_color = lv_color_mix(mcolor, gcolor, mix);\n        }\n        lv_draw_fill(&mid_top_area, mask, act_color, opa);\n    }\n\n    if(mcolor.full == gcolor.full)\n        act_color = mcolor;\n    else {\n        mix       = (uint32_t)((uint32_t)(coords->y2 - mid_bot_area.y1) * 255) / height;\n        act_color = lv_color_mix(mcolor, gcolor, mix);\n    }\n    lv_draw_fill(&mid_bot_area, mask, act_color, opa);\n\n    if(edge_bot_area.y1 != mid_bot_area.y1) {\n\n        if(mcolor.full == gcolor.full)\n            act_color = mcolor;\n        else {\n            mix       = (uint32_t)((uint32_t)(coords->y2 - edge_bot_area.y1) * 255) / height;\n            act_color = lv_color_mix(mcolor, gcolor, mix);\n        }\n        lv_draw_fill(&edge_bot_area, mask, act_color, opa);\n    }\n\n#if LV_ANTIALIAS\n    if(aa) {\n        /*The first and the last line is not drawn*/\n        edge_top_area.x1 = coords->x1 + radius + 2;\n        edge_top_area.x2 = coords->x2 - radius - 2;\n        edge_top_area.y1 = coords->y1;\n        edge_top_area.y2 = coords->y1;\n        lv_draw_fill(&edge_top_area, mask, style->body.main_color, opa);\n\n        edge_top_area.y1 = coords->y2;\n        edge_top_area.y2 = coords->y2;\n        lv_draw_fill(&edge_top_area, mask, style->body.grad_color, opa);\n\n        /*Last parts of the anti-alias*/\n        out_y_seg_end       = cir.y;\n        lv_coord_t seg_size = out_y_seg_end - out_y_seg_start;\n        lv_point_t aa_p;\n\n        aa_p.x = out_x_last;\n        aa_p.y = out_y_seg_start;\n\n        mix                 = (uint32_t)((uint32_t)(radius - out_x_last) * 255) / height;\n        aa_color_hor_bottom = lv_color_mix(gcolor, mcolor, mix);\n        aa_color_hor_top    = lv_color_mix(mcolor, gcolor, mix);\n\n        lv_coord_t i;\n        for(i = 0; i < seg_size; i++) {\n            lv_opa_t aa_opa = opa - lv_draw_aa_get_opa(seg_size, i, opa);\n            lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) + 1, mask,\n                       aa_color_hor_top, aa_opa);\n            lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) + 1, mask,\n                       aa_color_hor_top, aa_opa);\n            lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) - 1, mask,\n                       aa_color_hor_bottom, aa_opa);\n            lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) - 1, mask,\n                       aa_color_hor_bottom, aa_opa);\n\n            mix          = (uint32_t)((uint32_t)(radius - out_y_seg_start + i) * 255) / height;\n            aa_color_ver = lv_color_mix(mcolor, gcolor, mix);\n            lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) + 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask, aa_color_ver,\n                       aa_opa);\n            lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) - 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i, mask, aa_color_ver,\n                       aa_opa);\n\n            aa_color_ver = lv_color_mix(gcolor, mcolor, mix);\n            lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) - 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask, aa_color_ver,\n                       aa_opa);\n            lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) + 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i, mask, aa_color_ver,\n                       aa_opa);\n        }\n\n        /*In some cases the last pixel is not drawn*/\n        if(LV_MATH_ABS(aa_p.x - aa_p.y) == seg_size) {\n            aa_p.x = out_x_last;\n            aa_p.y = out_x_last;\n\n            mix                 = (uint32_t)((uint32_t)(out_x_last)*255) / height;\n            aa_color_hor_top    = lv_color_mix(gcolor, mcolor, mix);\n            aa_color_hor_bottom = lv_color_mix(mcolor, gcolor, mix);\n\n            lv_opa_t aa_opa = opa >> 1;\n            lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p), rb_origo.y + LV_CIRC_OCT2_Y(aa_p), mask, aa_color_hor_bottom,\n                       aa_opa);\n            lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p), lb_origo.y + LV_CIRC_OCT4_Y(aa_p), mask, aa_color_hor_bottom,\n                       aa_opa);\n            lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p), lt_origo.y + LV_CIRC_OCT6_Y(aa_p), mask, aa_color_hor_top,\n                       aa_opa);\n            lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p), rt_origo.y + LV_CIRC_OCT8_Y(aa_p), mask, aa_color_hor_top,\n                       aa_opa);\n        }\n    }\n#endif\n}\n\n/**\n * Draw the straight parts of a rectangle border\n * @param coords the coordinates of the original rectangle\n * @param mask_ the rectangle will be drawn only  on this area\n * @param rstyle pointer to a rectangle style\n * @param opa_scale scale down all opacities by the factor\n */\nstatic void lv_draw_rect_border_straight(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,\n                                         lv_opa_t opa_scale)\n{\n    uint16_t radius = style->body.radius;\n    bool aa         = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());\n\n    lv_coord_t width  = lv_area_get_width(coords);\n    lv_coord_t height = lv_area_get_height(coords);\n    lv_coord_t bwidth = style->body.border.width;\n    lv_opa_t opa      = opa_scale == LV_OPA_COVER ? style->body.border.opa\n                                             : (uint16_t)((uint16_t)style->body.border.opa * opa_scale) >> 8;\n    lv_border_part_t part = style->body.border.part;\n    lv_color_t color      = style->body.border.color;\n    lv_area_t work_area;\n    lv_coord_t length_corr = 0;\n    lv_coord_t corner_size = 0;\n\n    /*the 0 px border width drawn as 1 px, so decrement the b_width*/\n    bwidth--;\n\n    radius = lv_draw_cont_radius_corr(radius, width, height);\n\n    if(radius < bwidth) {\n        length_corr = bwidth - radius - aa;\n        corner_size = bwidth;\n    } else {\n        corner_size = radius + aa;\n    }\n\n    /*If radius == 0 is a special case*/\n    if(style->body.radius == 0) {\n        /*Left top corner*/\n        if(part & LV_BORDER_TOP) {\n            work_area.x1 = coords->x1;\n            work_area.x2 = coords->x2;\n            work_area.y1 = coords->y1;\n            work_area.y2 = coords->y1 + bwidth;\n            lv_draw_fill(&work_area, mask, color, opa);\n        }\n\n        /*Right top corner*/\n        if(part & LV_BORDER_RIGHT) {\n            work_area.x1 = coords->x2 - bwidth;\n            work_area.x2 = coords->x2;\n            work_area.y1 = coords->y1 + (part & LV_BORDER_TOP ? bwidth + 1 : 0);\n            work_area.y2 = coords->y2 - (part & LV_BORDER_BOTTOM ? bwidth + 1 : 0);\n            lv_draw_fill(&work_area, mask, color, opa);\n        }\n\n        /*Left bottom corner*/\n        if(part & LV_BORDER_LEFT) {\n            work_area.x1 = coords->x1;\n            work_area.x2 = coords->x1 + bwidth;\n            work_area.y1 = coords->y1 + (part & LV_BORDER_TOP ? bwidth + 1 : 0);\n            work_area.y2 = coords->y2 - (part & LV_BORDER_BOTTOM ? bwidth + 1 : 0);\n            lv_draw_fill(&work_area, mask, color, opa);\n        }\n\n        /*Right bottom corner*/\n        if(part & LV_BORDER_BOTTOM) {\n            work_area.x1 = coords->x1;\n            work_area.x2 = coords->x2;\n            work_area.y1 = coords->y2 - bwidth;\n            work_area.y2 = coords->y2;\n            lv_draw_fill(&work_area, mask, color, opa);\n        }\n        return;\n    }\n\n    /* Modify the corner_size if corner is drawn */\n    corner_size++;\n\n    /*Depending one which part's are drawn modify the area lengths */\n    if(part & LV_BORDER_TOP)\n        work_area.y1 = coords->y1 + corner_size;\n    else\n        work_area.y1 = coords->y1 + radius;\n\n    if(part & LV_BORDER_BOTTOM)\n        work_area.y2 = coords->y2 - corner_size;\n    else\n        work_area.y2 = coords->y2 - radius;\n\n    /*Left border*/\n    if(part & LV_BORDER_LEFT) {\n        work_area.x1 = coords->x1;\n        work_area.x2 = work_area.x1 + bwidth;\n        lv_draw_fill(&work_area, mask, color, opa);\n    }\n\n    /*Right border*/\n    if(part & LV_BORDER_RIGHT) {\n        work_area.x2 = coords->x2;\n        work_area.x1 = work_area.x2 - bwidth;\n        lv_draw_fill(&work_area, mask, color, opa);\n    }\n\n    work_area.x1 = coords->x1 + corner_size - length_corr;\n    work_area.x2 = coords->x2 - corner_size + length_corr;\n\n    /*Upper border*/\n    if(part & LV_BORDER_TOP) {\n        work_area.y1 = coords->y1;\n        work_area.y2 = coords->y1 + bwidth;\n        lv_draw_fill(&work_area, mask, color, opa);\n    }\n\n    /*Lower border*/\n    if(part & LV_BORDER_BOTTOM) {\n        work_area.y2 = coords->y2;\n        work_area.y1 = work_area.y2 - bwidth;\n        lv_draw_fill(&work_area, mask, color, opa);\n    }\n\n    /*Draw the a remaining rectangles if the radius is smaller then bwidth */\n    if(length_corr != 0) {\n        /*Left top correction*/\n        if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {\n            work_area.x1 = coords->x1;\n            work_area.x2 = coords->x1 + radius + aa;\n            work_area.y1 = coords->y1 + radius + 1 + aa;\n            work_area.y2 = coords->y1 + bwidth;\n            lv_draw_fill(&work_area, mask, color, opa);\n        }\n\n        /*Right top correction*/\n        if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {\n            work_area.x1 = coords->x2 - radius - aa;\n            work_area.x2 = coords->x2;\n            work_area.y1 = coords->y1 + radius + 1 + aa;\n            work_area.y2 = coords->y1 + bwidth;\n            lv_draw_fill(&work_area, mask, color, opa);\n        }\n\n        /*Left bottom correction*/\n        if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {\n            work_area.x1 = coords->x1;\n            work_area.x2 = coords->x1 + radius + aa;\n            work_area.y1 = coords->y2 - bwidth;\n            work_area.y2 = coords->y2 - radius - 1 - aa;\n            lv_draw_fill(&work_area, mask, color, opa);\n        }\n\n        /*Right bottom correction*/\n        if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {\n            work_area.x1 = coords->x2 - radius - aa;\n            work_area.x2 = coords->x2;\n            work_area.y1 = coords->y2 - bwidth;\n            work_area.y2 = coords->y2 - radius - 1 - aa;\n            lv_draw_fill(&work_area, mask, color, opa);\n        }\n    }\n\n    /*If radius == 0 one px on the corners are not drawn by main drawer*/\n    if(style->body.radius == 0) {\n        /*Left top corner*/\n        if(part & (LV_BORDER_TOP | LV_BORDER_LEFT)) {\n            work_area.x1 = coords->x1;\n            work_area.x2 = coords->x1 + aa;\n            work_area.y1 = coords->y1;\n            work_area.y2 = coords->y1 + aa;\n            lv_draw_fill(&work_area, mask, color, opa);\n        }\n\n        /*Right top corner*/\n        if(part & (LV_BORDER_TOP | LV_BORDER_RIGHT)) {\n            work_area.x1 = coords->x2 - aa;\n            work_area.x2 = coords->x2;\n            work_area.y1 = coords->y1;\n            work_area.y2 = coords->y1 + aa;\n            lv_draw_fill(&work_area, mask, color, opa);\n        }\n\n        /*Left bottom corner*/\n        if(part & (LV_BORDER_BOTTOM | LV_BORDER_LEFT)) {\n            work_area.x1 = coords->x1;\n            work_area.x2 = coords->x1 + aa;\n            work_area.y1 = coords->y2 - aa;\n            work_area.y2 = coords->y2;\n            lv_draw_fill(&work_area, mask, color, opa);\n        }\n\n        /*Right bottom corner*/\n        if(part & (LV_BORDER_BOTTOM | LV_BORDER_RIGHT)) {\n            work_area.x1 = coords->x2 - aa;\n            work_area.x2 = coords->x2;\n            work_area.y1 = coords->y2 - aa;\n            work_area.y2 = coords->y2;\n            lv_draw_fill(&work_area, mask, color, opa);\n        }\n    }\n}\n\n/**\n * Draw the corners of a rectangle border\n * @param coords the coordinates of the original rectangle\n * @param mask the rectangle will be drawn only  on this area\n * @param style pointer to a style\n * @param opa_scale scale down all opacities by the factor\n */\nstatic void lv_draw_rect_border_corner(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,\n                                       lv_opa_t opa_scale)\n{\n    uint16_t radius       = style->body.radius;\n    bool aa               = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());\n    lv_coord_t bwidth     = style->body.border.width;\n    lv_color_t color      = style->body.border.color;\n    lv_border_part_t part = style->body.border.part;\n    lv_opa_t opa          = opa_scale == LV_OPA_COVER ? style->body.border.opa\n                                             : (uint16_t)((uint16_t)style->body.border.opa * opa_scale) >> 8;\n    /*0 px border width drawn as 1 px, so decrement the bwidth*/\n    bwidth--;\n\n#if LV_ANTIALIAS\n    if(aa) bwidth--; /*Because of anti-aliasing the border seems one pixel ticker*/\n#endif\n\n    lv_coord_t width  = lv_area_get_width(coords);\n    lv_coord_t height = lv_area_get_height(coords);\n\n    radius = lv_draw_cont_radius_corr(radius, width, height);\n\n    lv_point_t lt_origo; /*Left  Top    origo*/\n    lv_point_t lb_origo; /*Left  Bottom origo*/\n    lv_point_t rt_origo; /*Right Top    origo*/\n    lv_point_t rb_origo; /*Left  Bottom origo*/\n\n    lt_origo.x = coords->x1 + radius + aa;\n    lt_origo.y = coords->y1 + radius + aa;\n\n    lb_origo.x = coords->x1 + radius + aa;\n    lb_origo.y = coords->y2 - radius - aa;\n\n    rt_origo.x = coords->x2 - radius - aa;\n    rt_origo.y = coords->y1 + radius + aa;\n\n    rb_origo.x = coords->x2 - radius - aa;\n    rb_origo.y = coords->y2 - radius - aa;\n\n    lv_point_t cir_out;\n    lv_coord_t tmp_out;\n    lv_circ_init(&cir_out, &tmp_out, radius);\n\n    lv_point_t cir_in;\n    lv_coord_t tmp_in;\n    lv_coord_t radius_in = radius - bwidth;\n\n    if(radius_in < 0) {\n        radius_in = 0;\n    }\n\n    lv_circ_init(&cir_in, &tmp_in, radius_in);\n\n    lv_area_t circ_area;\n    lv_coord_t act_w1;\n    lv_coord_t act_w2;\n\n#if LV_ANTIALIAS\n    /*Store some internal states for anti-aliasing*/\n    lv_coord_t out_y_seg_start = 0;\n    lv_coord_t out_y_seg_end   = 0;\n    lv_coord_t out_x_last      = radius;\n\n    lv_coord_t in_y_seg_start = 0;\n    lv_coord_t in_y_seg_end   = 0;\n    lv_coord_t in_x_last      = radius - bwidth;\n#endif\n\n    while(cir_out.y <= cir_out.x) {\n\n        /*Calculate the actual width to avoid overwriting pixels*/\n        if(cir_in.y < cir_in.x) {\n            act_w1 = cir_out.x - cir_in.x;\n            act_w2 = act_w1;\n        } else {\n            act_w1 = cir_out.x - cir_out.y;\n            act_w2 = act_w1 - 1;\n        }\n\n#if LV_ANTIALIAS\n        if(aa) {\n            /*New step in y on the outter circle*/\n            if(out_x_last != cir_out.x) {\n                out_y_seg_end       = cir_out.y;\n                lv_coord_t seg_size = out_y_seg_end - out_y_seg_start;\n                lv_point_t aa_p;\n\n                aa_p.x = out_x_last;\n                aa_p.y = out_y_seg_start;\n\n                lv_coord_t i;\n                for(i = 0; i < seg_size; i++) {\n                    lv_opa_t aa_opa;\n\n                    if(seg_size > CIRCLE_AA_NON_LINEAR_OPA_THRESHOLD) { /*Use non-linear opa mapping\n                                                                           on the first segment*/\n                        aa_opa = antialias_get_opa_circ(seg_size, i, opa);\n                    } else {\n                        aa_opa = opa - lv_draw_aa_get_opa(seg_size, i, opa);\n                    }\n\n                    if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {\n                        lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) + 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask,\n                                   style->body.border.color, aa_opa);\n                        lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) + 1, mask,\n                                   style->body.border.color, aa_opa);\n                    }\n\n                    if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {\n                        lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) + 1, mask,\n                                   style->body.border.color, aa_opa);\n                        lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) - 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i, mask,\n                                   style->body.border.color, aa_opa);\n                    }\n\n                    if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {\n                        lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) - 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask,\n                                   style->body.border.color, aa_opa);\n                        lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) - 1, mask,\n                                   style->body.border.color, aa_opa);\n                    }\n\n                    if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {\n                        lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) - 1, mask,\n                                   style->body.border.color, aa_opa);\n                        lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) + 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i, mask,\n                                   style->body.border.color, aa_opa);\n                    }\n                }\n\n                out_x_last      = cir_out.x;\n                out_y_seg_start = out_y_seg_end;\n            }\n\n            /*New step in y on the inner circle*/\n            if(in_x_last != cir_in.x) {\n                in_y_seg_end        = cir_out.y;\n                lv_coord_t seg_size = in_y_seg_end - in_y_seg_start;\n                lv_point_t aa_p;\n\n                aa_p.x = in_x_last;\n                aa_p.y = in_y_seg_start;\n\n                lv_coord_t i;\n                for(i = 0; i < seg_size; i++) {\n                    lv_opa_t aa_opa;\n\n                    if(seg_size > CIRCLE_AA_NON_LINEAR_OPA_THRESHOLD) { /*Use non-linear opa mapping\n                                                                           on the first segment*/\n                        aa_opa = opa - antialias_get_opa_circ(seg_size, i, opa);\n                    } else {\n                        aa_opa = lv_draw_aa_get_opa(seg_size, i, opa);\n                    }\n\n                    if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {\n                        lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) - 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask,\n                                   style->body.border.color, aa_opa);\n                    }\n\n                    if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {\n                        lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) - 1, mask,\n                                   style->body.border.color, aa_opa);\n                    }\n\n                    if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {\n                        lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) + 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask,\n                                   style->body.border.color, aa_opa);\n                    }\n\n                    if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {\n                        lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) + 1, mask,\n                                   style->body.border.color, aa_opa);\n                    }\n\n                    /*Be sure the pixels on the middle are not drawn twice*/\n                    if(LV_CIRC_OCT1_X(aa_p) - 1 != LV_CIRC_OCT2_X(aa_p) + i) {\n                        if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {\n                            lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) - 1,\n                                       mask, style->body.border.color, aa_opa);\n                        }\n\n                        if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {\n                            lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) + 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i,\n                                       mask, style->body.border.color, aa_opa);\n                        }\n\n                        if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {\n                            lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) + 1,\n                                       mask, style->body.border.color, aa_opa);\n                        }\n\n                        if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {\n                            lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) - 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i,\n                                       mask, style->body.border.color, aa_opa);\n                        }\n                    }\n                }\n\n                in_x_last      = cir_in.x;\n                in_y_seg_start = in_y_seg_end;\n            }\n        }\n#endif\n\n        /*Draw the octets to the right bottom corner*/\n        if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {\n            circ_area.x1 = rb_origo.x + LV_CIRC_OCT1_X(cir_out) - act_w2;\n            circ_area.x2 = rb_origo.x + LV_CIRC_OCT1_X(cir_out);\n            circ_area.y1 = rb_origo.y + LV_CIRC_OCT1_Y(cir_out);\n            circ_area.y2 = rb_origo.y + LV_CIRC_OCT1_Y(cir_out);\n            lv_draw_fill(&circ_area, mask, color, opa);\n\n            circ_area.x1 = rb_origo.x + LV_CIRC_OCT2_X(cir_out);\n            circ_area.x2 = rb_origo.x + LV_CIRC_OCT2_X(cir_out);\n            circ_area.y1 = rb_origo.y + LV_CIRC_OCT2_Y(cir_out) - act_w1;\n            circ_area.y2 = rb_origo.y + LV_CIRC_OCT2_Y(cir_out);\n            lv_draw_fill(&circ_area, mask, color, opa);\n        }\n\n        /*Draw the octets to the left bottom corner*/\n        if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {\n            circ_area.x1 = lb_origo.x + LV_CIRC_OCT3_X(cir_out);\n            circ_area.x2 = lb_origo.x + LV_CIRC_OCT3_X(cir_out);\n            circ_area.y1 = lb_origo.y + LV_CIRC_OCT3_Y(cir_out) - act_w2;\n            circ_area.y2 = lb_origo.y + LV_CIRC_OCT3_Y(cir_out);\n            lv_draw_fill(&circ_area, mask, color, opa);\n\n            circ_area.x1 = lb_origo.x + LV_CIRC_OCT4_X(cir_out);\n            circ_area.x2 = lb_origo.x + LV_CIRC_OCT4_X(cir_out) + act_w1;\n            circ_area.y1 = lb_origo.y + LV_CIRC_OCT4_Y(cir_out);\n            circ_area.y2 = lb_origo.y + LV_CIRC_OCT4_Y(cir_out);\n            lv_draw_fill(&circ_area, mask, color, opa);\n        }\n\n        /*Draw the octets to the left top corner*/\n        if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {\n            if(lb_origo.y + LV_CIRC_OCT4_Y(cir_out) > lt_origo.y + LV_CIRC_OCT5_Y(cir_out)) {\n                /*Don't draw if the lines are common in the middle*/\n                circ_area.x1 = lt_origo.x + LV_CIRC_OCT5_X(cir_out);\n                circ_area.x2 = lt_origo.x + LV_CIRC_OCT5_X(cir_out) + act_w2;\n                circ_area.y1 = lt_origo.y + LV_CIRC_OCT5_Y(cir_out);\n                circ_area.y2 = lt_origo.y + LV_CIRC_OCT5_Y(cir_out);\n                lv_draw_fill(&circ_area, mask, color, opa);\n            }\n\n            circ_area.x1 = lt_origo.x + LV_CIRC_OCT6_X(cir_out);\n            circ_area.x2 = lt_origo.x + LV_CIRC_OCT6_X(cir_out);\n            circ_area.y1 = lt_origo.y + LV_CIRC_OCT6_Y(cir_out);\n            circ_area.y2 = lt_origo.y + LV_CIRC_OCT6_Y(cir_out) + act_w1;\n            lv_draw_fill(&circ_area, mask, color, opa);\n        }\n\n        /*Draw the octets to the right top corner*/\n        if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {\n            circ_area.x1 = rt_origo.x + LV_CIRC_OCT7_X(cir_out);\n            circ_area.x2 = rt_origo.x + LV_CIRC_OCT7_X(cir_out);\n            circ_area.y1 = rt_origo.y + LV_CIRC_OCT7_Y(cir_out);\n            circ_area.y2 = rt_origo.y + LV_CIRC_OCT7_Y(cir_out) + act_w2;\n            lv_draw_fill(&circ_area, mask, color, opa);\n\n            /*Don't draw if the lines are common in the middle*/\n            if(rb_origo.y + LV_CIRC_OCT1_Y(cir_out) > rt_origo.y + LV_CIRC_OCT8_Y(cir_out)) {\n                circ_area.x1 = rt_origo.x + LV_CIRC_OCT8_X(cir_out) - act_w1;\n                circ_area.x2 = rt_origo.x + LV_CIRC_OCT8_X(cir_out);\n                circ_area.y1 = rt_origo.y + LV_CIRC_OCT8_Y(cir_out);\n                circ_area.y2 = rt_origo.y + LV_CIRC_OCT8_Y(cir_out);\n                lv_draw_fill(&circ_area, mask, color, opa);\n            }\n        }\n        lv_circ_next(&cir_out, &tmp_out);\n\n        /*The internal circle will be ready faster\n         * so check it! */\n        if(cir_in.y < cir_in.x) {\n            lv_circ_next(&cir_in, &tmp_in);\n        }\n    }\n\n#if LV_ANTIALIAS\n    if(aa) {\n        /*Last parts of the outer anti-alias*/\n        out_y_seg_end       = cir_out.y;\n        lv_coord_t seg_size = out_y_seg_end - out_y_seg_start;\n        lv_point_t aa_p;\n\n        aa_p.x = out_x_last;\n        aa_p.y = out_y_seg_start;\n\n        lv_coord_t i;\n        for(i = 0; i < seg_size; i++) {\n            lv_opa_t aa_opa = opa - lv_draw_aa_get_opa(seg_size, i, opa);\n            if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {\n                lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) + 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask,\n                           style->body.border.color, aa_opa);\n                lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) + 1, mask,\n                           style->body.border.color, aa_opa);\n            }\n\n            if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {\n                lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) + 1, mask,\n                           style->body.border.color, aa_opa);\n                lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) - 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i, mask,\n                           style->body.border.color, aa_opa);\n            }\n\n            if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {\n                lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) - 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask,\n                           style->body.border.color, aa_opa);\n                lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) - 1, mask,\n                           style->body.border.color, aa_opa);\n            }\n\n            if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {\n                lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) - 1, mask,\n                           style->body.border.color, aa_opa);\n                lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) + 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i, mask,\n                           style->body.border.color, aa_opa);\n            }\n        }\n\n        /*In some cases the last pixel in the outer middle is not drawn*/\n        if(LV_MATH_ABS(aa_p.x - aa_p.y) == seg_size) {\n            aa_p.x = out_x_last;\n            aa_p.y = out_x_last;\n\n            lv_opa_t aa_opa = opa >> 1;\n\n            if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {\n                lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p), rb_origo.y + LV_CIRC_OCT2_Y(aa_p), mask,\n                           style->body.border.color, aa_opa);\n            }\n\n            if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {\n                lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p), lb_origo.y + LV_CIRC_OCT4_Y(aa_p), mask,\n                           style->body.border.color, aa_opa);\n            }\n\n            if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {\n                lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p), lt_origo.y + LV_CIRC_OCT6_Y(aa_p), mask,\n                           style->body.border.color, aa_opa);\n            }\n\n            if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {\n                lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p), rt_origo.y + LV_CIRC_OCT8_Y(aa_p), mask,\n                           style->body.border.color, aa_opa);\n            }\n        }\n\n        /*Last parts of the inner anti-alias*/\n        in_y_seg_end = cir_in.y;\n        aa_p.x       = in_x_last;\n        aa_p.y       = in_y_seg_start;\n        seg_size     = in_y_seg_end - in_y_seg_start;\n\n        for(i = 0; i < seg_size; i++) {\n            lv_opa_t aa_opa = lv_draw_aa_get_opa(seg_size, i, opa);\n            if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {\n                lv_draw_px(rb_origo.x + LV_CIRC_OCT1_X(aa_p) - 1, rb_origo.y + LV_CIRC_OCT1_Y(aa_p) + i, mask,\n                           style->body.border.color, aa_opa);\n            }\n\n            if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {\n                lv_draw_px(lb_origo.x + LV_CIRC_OCT3_X(aa_p) - i, lb_origo.y + LV_CIRC_OCT3_Y(aa_p) - 1, mask,\n                           style->body.border.color, aa_opa);\n            }\n\n            if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {\n                lv_draw_px(lt_origo.x + LV_CIRC_OCT5_X(aa_p) + 1, lt_origo.y + LV_CIRC_OCT5_Y(aa_p) - i, mask,\n                           style->body.border.color, aa_opa);\n            }\n\n            if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {\n                lv_draw_px(rt_origo.x + LV_CIRC_OCT7_X(aa_p) + i, rt_origo.y + LV_CIRC_OCT7_Y(aa_p) + 1, mask,\n                           style->body.border.color, aa_opa);\n            }\n\n            if(LV_CIRC_OCT1_X(aa_p) - 1 != LV_CIRC_OCT2_X(aa_p) + i) {\n                if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_RIGHT)) {\n                    lv_draw_px(rb_origo.x + LV_CIRC_OCT2_X(aa_p) + i, rb_origo.y + LV_CIRC_OCT2_Y(aa_p) - 1, mask,\n                               style->body.border.color, aa_opa);\n                }\n\n                if((part & LV_BORDER_BOTTOM) && (part & LV_BORDER_LEFT)) {\n                    lv_draw_px(lb_origo.x + LV_CIRC_OCT4_X(aa_p) + 1, lb_origo.y + LV_CIRC_OCT4_Y(aa_p) + i, mask,\n                               style->body.border.color, aa_opa);\n                }\n\n                if((part & LV_BORDER_TOP) && (part & LV_BORDER_LEFT)) {\n                    lv_draw_px(lt_origo.x + LV_CIRC_OCT6_X(aa_p) - i, lt_origo.y + LV_CIRC_OCT6_Y(aa_p) + 1, mask,\n                               style->body.border.color, aa_opa);\n                }\n\n                if((part & LV_BORDER_TOP) && (part & LV_BORDER_RIGHT)) {\n                    lv_draw_px(rt_origo.x + LV_CIRC_OCT8_X(aa_p) - 1, rt_origo.y + LV_CIRC_OCT8_Y(aa_p) - i, mask,\n                               style->body.border.color, aa_opa);\n                }\n            }\n        }\n    }\n#endif\n}\n\n#if LV_USE_SHADOW\n\n/**\n * Draw a shadow\n * @param rect pointer to rectangle object\n * @param mask pointer to a mask area (from the design functions)\n * @param opa_scale scale down all opacities by the factor\n */\nstatic void lv_draw_shadow(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,\n                           lv_opa_t opa_scale)\n{\n    /* If mask is in the middle of cords do not draw shadow*/\n    lv_coord_t radius = style->body.radius;\n    lv_coord_t width  = lv_area_get_width(coords);\n    lv_coord_t height = lv_area_get_height(coords);\n    radius            = lv_draw_cont_radius_corr(radius, width, height);\n    lv_area_t area_tmp;\n\n    /*Check horizontally without radius*/\n    lv_area_copy(&area_tmp, coords);\n    area_tmp.x1 += radius;\n    area_tmp.x2 -= radius;\n    if(lv_area_is_in(mask, &area_tmp) != false) return;\n\n    /*Check vertically without radius*/\n    lv_area_copy(&area_tmp, coords);\n    area_tmp.y1 += radius;\n    area_tmp.y2 -= radius;\n    if(lv_area_is_in(mask, &area_tmp) != false) return;\n\n    if(style->body.shadow.type == LV_SHADOW_FULL) {\n        lv_draw_shadow_full(coords, mask, style, opa_scale);\n    } else if(style->body.shadow.type == LV_SHADOW_BOTTOM) {\n        lv_draw_shadow_bottom(coords, mask, style, opa_scale);\n    }\n}\n\nstatic void lv_draw_shadow_full(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,\n                                lv_opa_t opa_scale)\n{\n\n    /* KNOWN ISSUE\n     * The algorithm calculates the shadow only above the middle point of the radius (speaking about\n     * the left top corner). It causes an error because it doesn't consider how long the straight\n     * edge is which effects the value of bottom of the corner shadow. In addition the straight\n     * shadow is drawn from the middles point of the radius however the ends of the straight parts\n     * still should be effected by the corner shadow. It also causes an issue in opacity. A smaller\n     * radius means smaller average shadow opacity. The solution should be to start `line` from `-\n     * swidth` and handle if the straight part is short (or zero) and the value is taken from the\n     * other corner. `col` also should start from `- swidth`\n     */\n\n    bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());\n\n    lv_coord_t radius = style->body.radius;\n    lv_coord_t swidth = style->body.shadow.width;\n\n    lv_coord_t width  = lv_area_get_width(coords);\n    lv_coord_t height = lv_area_get_height(coords);\n\n    radius = lv_draw_cont_radius_corr(radius, width, height);\n\n    radius += aa;\n\n    /*Allocate a draw buffer the buffer required to draw the shadow*/\n    int16_t filter_width = 2 * swidth + 1;\n    uint32_t curve_x_size = ((radius + swidth + 1) + 3) & ~0x3; /*Round to 4*/\n    curve_x_size *= sizeof(lv_coord_t);\n    uint32_t line_1d_blur_size = (filter_width + 3) & ~0x3;     /*Round to 4*/\n    line_1d_blur_size *= sizeof(uint32_t);\n    uint32_t line_2d_blur_size = ((radius + swidth + 1) + 3) & ~0x3;     /*Round to 4*/\n    line_2d_blur_size *= sizeof(lv_opa_t);\n\n    uint8_t * draw_buf = lv_draw_get_buf(curve_x_size + line_1d_blur_size + line_2d_blur_size);\n\n    /*Divide the draw buffer*/\n    lv_coord_t  * curve_x = (lv_coord_t *)&draw_buf[0]; /*Stores the 'x' coordinates of a quarter circle.*/\n    uint32_t * line_1d_blur = (uint32_t *)&draw_buf[curve_x_size];\n    lv_opa_t * line_2d_blur = (lv_opa_t *)&draw_buf[curve_x_size + line_1d_blur_size];\n\n    memset(curve_x, 0, curve_x_size);\n    lv_point_t circ;\n    lv_coord_t circ_tmp;\n    lv_circ_init(&circ, &circ_tmp, radius);\n    while(lv_circ_cont(&circ)) {\n        curve_x[LV_CIRC_OCT1_Y(circ)] = LV_CIRC_OCT1_X(circ);\n        curve_x[LV_CIRC_OCT2_Y(circ)] = LV_CIRC_OCT2_X(circ);\n        lv_circ_next(&circ, &circ_tmp);\n    }\n    int16_t line;\n    /*1D Blur horizontally*/\n    lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->body.opa : (uint16_t)((uint16_t)style->body.opa * opa_scale) >> 8;\n    for(line = 0; line < filter_width; line++) {\n        line_1d_blur[line] = (uint32_t)((uint32_t)(filter_width - line) * (opa * 2) << SHADOW_OPA_EXTRA_PRECISION) /\n                             (filter_width * filter_width);\n    }\n\n    uint16_t col;\n\n    lv_point_t point_rt;\n    lv_point_t point_rb;\n    lv_point_t point_lt;\n    lv_point_t point_lb;\n    lv_point_t ofs_rb;\n    lv_point_t ofs_rt;\n    lv_point_t ofs_lb;\n    lv_point_t ofs_lt;\n    ofs_rb.x = coords->x2 - radius - aa;\n    ofs_rb.y = coords->y2 - radius - aa;\n\n    ofs_rt.x = coords->x2 - radius - aa;\n    ofs_rt.y = coords->y1 + radius + aa;\n\n    ofs_lb.x = coords->x1 + radius + aa;\n    ofs_lb.y = coords->y2 - radius - aa;\n\n    ofs_lt.x = coords->x1 + radius + aa;\n    ofs_lt.y = coords->y1 + radius + aa;\n    bool line_ready;\n    for(line = 0; line <= radius + swidth; line++) { /*Check all rows and make the 1D blur to 2D*/\n        line_ready = false;\n        for(col = 0; col <= radius + swidth; col++) { /*Check all pixels in a 1D blur line (from the origo to last\n                                                         shadow pixel (radius + swidth))*/\n\n            /*Sum the opacities from the lines above and below this 'row'*/\n            int16_t line_rel;\n            uint32_t px_opa_sum = 0;\n            for(line_rel = -swidth; line_rel <= swidth; line_rel++) {\n                /*Get the relative x position of the 'line_rel' to 'line'*/\n                int16_t col_rel;\n                if(line + line_rel < 0) { /*Below the radius, here is the blur of the edge */\n                    col_rel = radius - curve_x[line] - col;\n                } else if(line + line_rel > radius) { /*Above the radius, here won't be more 1D blur*/\n                    break;\n                } else { /*Blur from the curve*/\n                    col_rel = curve_x[line + line_rel] - curve_x[line] - col;\n                }\n\n                /*Add the value of the 1D blur on 'col_rel' position*/\n                if(col_rel < -swidth) { /*Outside of the blurred area. */\n                    if(line_rel == -swidth)\n                        line_ready = true; /*If no data even on the very first line then it wont't\n                                              be anything else in this line*/\n                    break;                 /*Break anyway because only smaller 'col_rel' values will come */\n                } else if(col_rel > swidth)\n                    px_opa_sum += line_1d_blur[0]; /*Inside the not blurred area*/\n                else\n                    px_opa_sum += line_1d_blur[swidth - col_rel]; /*On the 1D blur (+ swidth to align to the center)*/\n            }\n\n            line_2d_blur[col] = px_opa_sum >> SHADOW_OPA_EXTRA_PRECISION;\n            if(line_ready) {\n                col++; /*To make this line to the last one ( drawing will go to '< col')*/\n                break;\n            }\n        }\n\n        /*Flush the line*/\n        point_rt.x = curve_x[line] + ofs_rt.x + 1;\n        point_rt.y = ofs_rt.y - line;\n\n        point_rb.x = curve_x[line] + ofs_rb.x + 1;\n        point_rb.y = ofs_rb.y + line;\n\n        point_lt.x = ofs_lt.x - curve_x[line] - 1;\n        point_lt.y = ofs_lt.y - line;\n\n        point_lb.x = ofs_lb.x - curve_x[line] - 1;\n        point_lb.y = ofs_lb.y + line;\n\n        uint16_t d;\n        for(d = 1; d < col; d++) {\n\n            if(point_lt.x < ofs_lt.x && point_lt.y < ofs_lt.y) {\n                lv_draw_px(point_lt.x, point_lt.y, mask, style->body.shadow.color, line_2d_blur[d]);\n            }\n\n            if(point_lb.x < ofs_lb.x && point_lb.y > ofs_lb.y) {\n                lv_draw_px(point_lb.x, point_lb.y, mask, style->body.shadow.color, line_2d_blur[d]);\n            }\n\n            if(point_rt.x > ofs_rt.x && point_rt.y < ofs_rt.y) {\n                lv_draw_px(point_rt.x, point_rt.y, mask, style->body.shadow.color, line_2d_blur[d]);\n            }\n\n            if(point_rb.x > ofs_rb.x && point_rb.y > ofs_rb.y) {\n                lv_draw_px(point_rb.x, point_rb.y, mask, style->body.shadow.color, line_2d_blur[d]);\n            }\n\n            point_rb.x++;\n            point_lb.x--;\n\n            point_rt.x++;\n            point_lt.x--;\n        }\n\n        /* Put the first line to the edges too.\n         * It is not correct because blur should be done below the corner too\n         * but is is simple, fast and gives a good enough result*/\n        if(line == 0) lv_draw_shadow_full_straight(coords, mask, style, line_2d_blur);\n    }\n}\n\nstatic void lv_draw_shadow_bottom(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,\n                                  lv_opa_t opa_scale)\n{\n    bool aa           = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());\n    lv_coord_t radius = style->body.radius;\n    lv_coord_t swidth = style->body.shadow.width;\n    lv_coord_t width  = lv_area_get_width(coords);\n    lv_coord_t height = lv_area_get_height(coords);\n\n    radius = lv_draw_cont_radius_corr(radius, width, height);\n    radius += aa * SHADOW_BOTTOM_AA_EXTRA_RADIUS;\n    swidth += aa;\n\n    uint32_t curve_x_size = ((radius + 1) + 3) & ~0x3; /*Round to 4*/\n    curve_x_size *= sizeof(lv_coord_t);\n    lv_opa_t line_1d_blur_size = (swidth + 3) & ~0x3;     /*Round to 4*/\n    line_1d_blur_size *= sizeof(lv_opa_t);\n\n    uint8_t * draw_buf = lv_draw_get_buf(curve_x_size + line_1d_blur_size);\n\n    /*Divide the draw buffer*/\n    lv_coord_t  * curve_x = (lv_coord_t *)&draw_buf[0]; /*Stores the 'x' coordinates of a quarter circle.*/\n    lv_opa_t * line_1d_blur = (lv_opa_t *)&draw_buf[curve_x_size];\n\n    lv_point_t circ;\n    lv_coord_t circ_tmp;\n    lv_circ_init(&circ, &circ_tmp, radius);\n    while(lv_circ_cont(&circ)) {\n        curve_x[LV_CIRC_OCT1_Y(circ)] = LV_CIRC_OCT1_X(circ);\n        curve_x[LV_CIRC_OCT2_Y(circ)] = LV_CIRC_OCT2_X(circ);\n        lv_circ_next(&circ, &circ_tmp);\n    }\n\n    int16_t col;\n\n    lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->body.opa : (uint16_t)((uint16_t)style->body.opa * opa_scale) >> 8;\n    for(col = 0; col < swidth; col++) {\n        line_1d_blur[col] = (uint32_t)((uint32_t)(swidth - col) * opa / 2) / (swidth);\n    }\n\n    lv_point_t point_l;\n    lv_point_t point_r;\n    lv_area_t area_mid;\n    lv_point_t ofs_l;\n    lv_point_t ofs_r;\n\n    ofs_l.x = coords->x1 + radius;\n    ofs_l.y = coords->y2 - radius + 1 - aa;\n\n    ofs_r.x = coords->x2 - radius;\n    ofs_r.y = coords->y2 - radius + 1 - aa;\n\n    for(col = 0; col <= radius; col++) {\n        point_l.x = ofs_l.x - col;\n        point_l.y = ofs_l.y + curve_x[col];\n\n        point_r.x = ofs_r.x + col;\n        point_r.y = ofs_r.y + curve_x[col];\n\n        lv_opa_t px_opa;\n        int16_t diff = col == 0 ? 0 : curve_x[col - 1] - curve_x[col];\n        uint16_t d;\n        for(d = 0; d < swidth; d++) {\n            /*When stepping a pixel in y calculate the average with the pixel from the prev. column\n             * to make a blur */\n            if(diff == 0) {\n                px_opa = line_1d_blur[d];\n            } else {\n                px_opa = (uint16_t)((uint16_t)line_1d_blur[d] + line_1d_blur[d - diff]) >> 1;\n            }\n            lv_draw_px(point_l.x, point_l.y, mask, style->body.shadow.color, px_opa);\n            point_l.y++;\n\n            /*Don't overdraw the pixel on the middle*/\n            if(point_r.x > ofs_l.x) {\n                lv_draw_px(point_r.x, point_r.y, mask, style->body.shadow.color, px_opa);\n            }\n            point_r.y++;\n        }\n    }\n\n    area_mid.x1 = ofs_l.x + 1;\n    area_mid.y1 = ofs_l.y + radius;\n    area_mid.x2 = ofs_r.x - 1;\n    area_mid.y2 = area_mid.y1;\n\n    uint16_t d;\n    for(d = 0; d < swidth; d++) {\n        lv_draw_fill(&area_mid, mask, style->body.shadow.color, line_1d_blur[d]);\n        area_mid.y1++;\n        area_mid.y2++;\n    }\n}\n\nstatic void lv_draw_shadow_full_straight(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style,\n                                         const lv_opa_t * map)\n{\n    bool aa           = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());\n    lv_coord_t radius = style->body.radius;\n    lv_coord_t swidth = style->body.shadow.width;\n    lv_coord_t width  = lv_area_get_width(coords);\n    lv_coord_t height = lv_area_get_height(coords);\n\n    radius = lv_draw_cont_radius_corr(radius, width, height);\n    radius += aa;\n\n    lv_area_t right_area;\n    right_area.x1 = coords->x2 + 1 - aa;\n    right_area.y1 = coords->y1 + radius + aa;\n    right_area.x2 = right_area.x1;\n    right_area.y2 = coords->y2 - radius - aa;\n\n    lv_area_t left_area;\n    left_area.x1 = coords->x1 - 1 + aa;\n    left_area.y1 = coords->y1 + radius + aa;\n    left_area.x2 = left_area.x1;\n    left_area.y2 = coords->y2 - radius - aa;\n\n    lv_area_t top_area;\n    top_area.x1 = coords->x1 + radius + aa;\n    top_area.y1 = coords->y1 - 1 + aa;\n    top_area.x2 = coords->x2 - radius - aa;\n    top_area.y2 = top_area.y1;\n\n    lv_area_t bottom_area;\n    bottom_area.x1 = coords->x1 + radius + aa;\n    bottom_area.y1 = coords->y2 + 1 - aa;\n    bottom_area.x2 = coords->x2 - radius - aa;\n    bottom_area.y2 = bottom_area.y1;\n\n    lv_opa_t opa_act;\n    int16_t d;\n    for(d = 1 /*+ LV_ANTIALIAS*/; d <= swidth /* - LV_ANTIALIAS*/; d++) {\n        opa_act = map[d];\n\n        lv_draw_fill(&right_area, mask, style->body.shadow.color, opa_act);\n        right_area.x1++;\n        right_area.x2++;\n\n        lv_draw_fill(&left_area, mask, style->body.shadow.color, opa_act);\n        left_area.x1--;\n        left_area.x2--;\n\n        lv_draw_fill(&top_area, mask, style->body.shadow.color, opa_act);\n        top_area.y1--;\n        top_area.y2--;\n\n        lv_draw_fill(&bottom_area, mask, style->body.shadow.color, opa_act);\n        bottom_area.y1++;\n        bottom_area.y2++;\n    }\n}\n\n#endif\n\nstatic uint16_t lv_draw_cont_radius_corr(uint16_t r, lv_coord_t w, lv_coord_t h)\n{\n    bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());\n\n    if(r >= (w >> 1)) {\n        r = (w >> 1);\n        if(r != 0) r--;\n    }\n    if(r >= (h >> 1)) {\n        r = (h >> 1);\n        if(r != 0) r--;\n    }\n\n    if(r > 0) r -= aa;\n\n    return r;\n}\n\n#if LV_ANTIALIAS\n\n/**\n * Approximate the opacity for anti-aliasing.\n * Used  the first segment of a circle which is the longest and have the most non-linearity (cos)\n * @param seg length of the line segment\n * @param px_id index of pixel on the line segment\n * @param line_opa opacity of the lien (it will be the max opacity)\n * @return the desired opacity of the pixel\n */\nstatic lv_opa_t antialias_get_opa_circ(lv_coord_t seg, lv_coord_t px_id, lv_opa_t opa)\n{\n    /*Empirical non-linear values anti-aliasing values*/\n    static const lv_opa_t opa_map2[2] = {210, 80};\n    static const lv_opa_t opa_map3[3] = {230, 150, 60};\n    static const lv_opa_t opa_map4[4] = {235, 185, 125, 50};\n    static const lv_opa_t opa_map8[8] = {250, 242, 219, 191, 158, 117, 76, 40};\n\n#if CIRCLE_AA_NON_LINEAR_OPA_THRESHOLD < 1\n    if(seg == 1) return 170;\n#endif\n\n#if CIRCLE_AA_NON_LINEAR_OPA_THRESHOLD < 2\n    if(seg == 2) return (opa_map2[px_id] * opa) >> 8;\n#endif\n\n#if CIRCLE_AA_NON_LINEAR_OPA_THRESHOLD < 3\n    if(seg == 3) return (opa_map3[px_id] * opa) >> 8;\n#endif\n\n#if CIRCLE_AA_NON_LINEAR_OPA_THRESHOLD < 4\n    if(seg == 4) return (opa_map4[px_id] * opa) >> 8;\n#endif\n\n    uint8_t id = (uint32_t)((uint32_t)px_id * (sizeof(opa_map8) - 1)) / (seg - 1);\n    return (uint32_t)((uint32_t)opa_map8[id] * opa) >> 8;\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_draw/lv_draw_triangle.c",
    "content": "/**\n * @file lv_draw_triangle.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_draw/lv_draw_triangle.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nvoid tri_draw_flat(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa);\nvoid tri_draw_tall(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa);\nstatic void point_swap(lv_point_t * p1, lv_point_t * p2);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n *\n * @param points pointer to an array with 3 points\n * @param mask the triangle will be drawn only in this mask\n * @param style style for of the triangle\n * @param opa_scale scale down all opacities by the factor (0..255)\n */\nvoid lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)\n{\n\n    /*Return is the triangle is degenerated*/\n    if(points[0].x == points[1].x && points[0].y == points[1].y) return;\n    if(points[1].x == points[2].x && points[1].y == points[2].y) return;\n    if(points[0].x == points[2].x && points[0].y == points[2].y) return;\n\n    if(points[0].x == points[1].x && points[1].x == points[2].x) return;\n    if(points[0].y == points[1].y && points[1].y == points[2].y) return;\n\n    lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->body.opa : (uint16_t)((uint16_t)style->body.opa * opa_scale) >> 8;\n\n    /*Is the triangle flat or tall?*/\n    lv_coord_t x_min = LV_MATH_MIN(LV_MATH_MIN(points[0].x, points[1].x), points[2].x);\n    lv_coord_t x_max = LV_MATH_MAX(LV_MATH_MAX(points[0].x, points[1].x), points[2].x);\n    lv_coord_t y_min = LV_MATH_MIN(LV_MATH_MIN(points[0].y, points[1].y), points[2].y);\n    lv_coord_t y_max = LV_MATH_MAX(LV_MATH_MAX(points[0].y, points[1].y), points[2].y);\n\n    /* Draw the tall rectangles from vertical lines\n     * and from the flat triangles from horizontal lines\n     * to minimize the number of lines.\n     * Some pixels are overdrawn on the common edges of the triangles\n     * so use it only if the triangle has no opacity*/\n\n    /* Draw from horizontal lines*/\n    if(x_max - x_min < y_max - y_min) {\n        tri_draw_tall(points, mask, style, opa);\n    }\n    /*Else flat so draw from vertical lines*/\n    else {\n        tri_draw_flat(points, mask, style, opa);\n    }\n}\n\n/**\n * Draw a polygon from triangles. Only convex polygons are supported\n * @param points an array of points\n * @param point_cnt number of points\n * @param mask polygon will be drawn only in this mask\n * @param style style of the polygon\n * @param opa_scale scale down all opacities by the factor (0..255)\n */\nvoid lv_draw_polygon(const lv_point_t * points, uint32_t point_cnt, const lv_area_t * mask, const lv_style_t * style,\n                     lv_opa_t opa_scale)\n{\n    if(point_cnt < 3) return;\n    if(points == NULL) return;\n\n    uint32_t i;\n    lv_point_t tri[3];\n    tri[0].x = points[0].x;\n    tri[0].y = points[0].y;\n    for(i = 0; i < point_cnt - 1; i++) {\n        tri[1].x = points[i].x;\n        tri[1].y = points[i].y;\n        tri[2].x = points[i + 1].x;\n        tri[2].y = points[i + 1].y;\n        lv_draw_triangle(tri, mask, style, opa_scale);\n    }\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\nvoid tri_draw_flat(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa)\n{\n    /*Return if the points are out of the mask*/\n    if(points[0].x < mask->x1 && points[1].x < mask->x1 && points[2].x < mask->x1) {\n        return;\n    }\n\n    if(points[0].x > mask->x2 && points[1].x > mask->x2 && points[2].x > mask->x2) {\n        return;\n    }\n\n    if(points[0].y < mask->y1 && points[1].y < mask->y1 && points[2].y < mask->y1) {\n        return;\n    }\n\n    if(points[0].y > mask->y2 && points[1].y > mask->y2 && points[2].y > mask->y2) {\n        return;\n    }\n\n    lv_point_t tri[3];\n\n    memcpy(tri, points, sizeof(tri));\n\n    /*Sort the vertices according to their y coordinate (0: y max, 1: y mid, 2:y min)*/\n    if(tri[1].y < tri[0].y) point_swap(&tri[1], &tri[0]);\n    if(tri[2].y < tri[1].y) point_swap(&tri[2], &tri[1]);\n    if(tri[1].y < tri[0].y) point_swap(&tri[1], &tri[0]);\n\n    /*Draw the triangle*/\n    lv_point_t edge1;\n    lv_coord_t dx1  = LV_MATH_ABS(tri[0].x - tri[1].x);\n    lv_coord_t sx1  = tri[0].x < tri[1].x ? 1 : -1;\n    lv_coord_t dy1  = LV_MATH_ABS(tri[0].y - tri[1].y);\n    lv_coord_t sy1  = tri[0].y < tri[1].y ? 1 : -1;\n    lv_coord_t err1 = (dx1 > dy1 ? dx1 : -dy1) / 2;\n    lv_coord_t err_tmp1;\n\n    lv_point_t edge2;\n    lv_coord_t dx2  = LV_MATH_ABS(tri[0].x - tri[2].x);\n    lv_coord_t sx2  = tri[0].x < tri[2].x ? 1 : -1;\n    lv_coord_t dy2  = LV_MATH_ABS(tri[0].y - tri[2].y);\n    lv_coord_t sy2  = tri[0].y < tri[2].y ? 1 : -1;\n    lv_coord_t err2 = (dx1 > dy2 ? dx2 : -dy2) / 2;\n    lv_coord_t err_tmp2;\n\n    lv_coord_t y1_tmp;\n    lv_coord_t y2_tmp;\n\n    edge1.x = tri[0].x;\n    edge1.y = tri[0].y;\n    edge2.x = tri[0].x;\n    edge2.y = tri[0].y;\n    lv_area_t act_area;\n    lv_area_t draw_area;\n\n    while(1) {\n        act_area.x1 = edge1.x;\n        act_area.x2 = edge2.x;\n        act_area.y1 = edge1.y;\n        act_area.y2 = edge2.y;\n\n        /* Get the area of a line.\n         * Adjust it a little bit to perfectly match (no redrawn pixels) with the adjacent triangles*/\n        draw_area.x1 = LV_MATH_MIN(act_area.x1, act_area.x2) + 1;\n        draw_area.x2 = LV_MATH_MAX(act_area.x1, act_area.x2);\n        draw_area.y1 = LV_MATH_MIN(act_area.y1, act_area.y2) - 1;\n        draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2) - 1;\n\n        lv_draw_fill(&draw_area, mask, style->body.main_color, opa);\n\n        /*Calc. the next point of edge1*/\n        y1_tmp = edge1.y;\n        do {\n            if(edge1.x == tri[1].x && edge1.y == tri[1].y) {\n\n                dx1  = LV_MATH_ABS(tri[1].x - tri[2].x);\n                sx1  = tri[1].x < tri[2].x ? 1 : -1;\n                dy1  = LV_MATH_ABS(tri[1].y - tri[2].y);\n                sy1  = tri[1].y < tri[2].y ? 1 : -1;\n                err1 = (dx1 > dy1 ? dx1 : -dy1) / 2;\n            } else if(edge1.x == tri[2].x && edge1.y == tri[2].y) {\n                return;\n            }\n            err_tmp1 = err1;\n            if(err_tmp1 > -dx1) {\n                err1 -= dy1;\n                edge1.x += sx1;\n            }\n            if(err_tmp1 < dy1) {\n                err1 += dx1;\n                edge1.y += sy1;\n            }\n        } while(edge1.y == y1_tmp);\n\n        /*Calc. the next point of edge2*/\n        y2_tmp = edge2.y;\n        do {\n            if(edge2.x == tri[2].x && edge2.y == tri[2].y) return;\n            err_tmp2 = err2;\n            if(err_tmp2 > -dx2) {\n                err2 -= dy2;\n                edge2.x += sx2;\n            }\n            if(err_tmp2 < dy2) {\n                err2 += dx2;\n                edge2.y += sy2;\n            }\n        } while(edge2.y == y2_tmp);\n    }\n}\n\nvoid tri_draw_tall(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa)\n{\n    /*\n     * Better to draw from vertical lines\n     * |\\\n     * | |\n     * | |\n     * |  \\\n     * |   |\n     * |___|\n     */\n\n    lv_point_t tri[3];\n\n    memcpy(tri, points, sizeof(tri));\n\n    /*Sort the vertices according to their x coordinate (0: x max, 1: x mid, 2:x min)*/\n    if(tri[1].x < tri[0].x) point_swap(&tri[1], &tri[0]);\n    if(tri[2].x < tri[1].x) point_swap(&tri[2], &tri[1]);\n    if(tri[1].x < tri[0].x) point_swap(&tri[1], &tri[0]);\n\n    /*Draw the triangle*/\n    lv_point_t edge1;\n    lv_coord_t dx1  = LV_MATH_ABS(tri[0].x - tri[1].x);\n    lv_coord_t sx1  = tri[0].x < tri[1].x ? 1 : -1;\n    lv_coord_t dy1  = LV_MATH_ABS(tri[0].y - tri[1].y);\n    lv_coord_t sy1  = tri[0].y < tri[1].y ? 1 : -1;\n    lv_coord_t err1 = (dx1 > dy1 ? dx1 : -dy1) / 2;\n    lv_coord_t err_tmp1;\n\n    lv_point_t edge2;\n    lv_coord_t dx2  = LV_MATH_ABS(tri[0].x - tri[2].x);\n    lv_coord_t sx2  = tri[0].x < tri[2].x ? 1 : -1;\n    lv_coord_t dy2  = LV_MATH_ABS(tri[0].y - tri[2].y);\n    lv_coord_t sy2  = tri[0].y < tri[2].y ? 1 : -1;\n    lv_coord_t err2 = (dx1 > dy2 ? dx2 : -dy2) / 2;\n    lv_coord_t err_tmp2;\n\n    lv_coord_t x1_tmp;\n    lv_coord_t x2_tmp;\n\n    edge1.x = tri[0].x;\n    edge1.y = tri[0].y;\n    edge2.x = tri[0].x;\n    edge2.y = tri[0].y;\n    lv_area_t act_area;\n    lv_area_t draw_area;\n\n    while(1) {\n        act_area.x1 = edge1.x;\n        act_area.x2 = edge2.x;\n        act_area.y1 = edge1.y;\n        act_area.y2 = edge2.y;\n\n        draw_area.x1 = LV_MATH_MIN(act_area.x1, act_area.x2);\n        draw_area.x2 = LV_MATH_MAX(act_area.x1, act_area.x2);\n        draw_area.y1 = LV_MATH_MIN(act_area.y1, act_area.y2);\n        draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2) - 1;\n\n        lv_draw_fill(&draw_area, mask, style->body.main_color, opa);\n\n        /*Calc. the next point of edge1*/\n        x1_tmp = edge1.x;\n        do {\n            if(edge1.y == tri[1].y && edge1.x == tri[1].x) {\n\n                dx1  = LV_MATH_ABS(tri[1].x - tri[2].x);\n                sx1  = tri[1].x < tri[2].x ? 1 : -1;\n                dy1  = LV_MATH_ABS(tri[1].y - tri[2].y);\n                sy1  = tri[1].y < tri[2].y ? 1 : -1;\n                err1 = (dx1 > dy1 ? dx1 : -dy1) / 2;\n            } else if(edge1.y == tri[2].y && edge1.x == tri[2].x) {\n                return;\n            }\n            err_tmp1 = err1;\n            if(err_tmp1 > -dx1) {\n                err1 -= dy1;\n                edge1.x += sx1;\n            }\n            if(err_tmp1 < dy1) {\n                err1 += dx1;\n                edge1.y += sy1;\n            }\n        } while(edge1.x == x1_tmp);\n\n        /*Calc. the next point of edge2*/\n        x2_tmp = edge2.x;\n        do {\n            if(edge2.y == tri[2].y && edge2.x == tri[2].x) {\n                return;\n            }\n\n            err_tmp2 = err2;\n            if(err_tmp2 > -dx2) {\n                err2 -= dy2;\n                edge2.x += sx2;\n            }\n            if(err_tmp2 < dy2) {\n                err2 += dx2;\n                edge2.y += sy2;\n            }\n        } while(edge2.x == x2_tmp);\n    }\n}\n\n/**\n * Swap two points\n * p1 pointer to the first point\n * p2 pointer to the second point\n */\nstatic void point_swap(lv_point_t * p1, lv_point_t * p2)\n{\n    lv_point_t tmp;\n    tmp.x = p1->x;\n    tmp.y = p1->y;\n\n    p1->x = p2->x;\n    p1->y = p2->y;\n\n    p2->x = tmp.x;\n    p2->y = tmp.y;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_draw/lv_img_cache.c",
    "content": "/**\n * @file lv_img_cache.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_draw/lv_img_cache.h\"\n#include \"libs/lvgl/lv_hal/lv_hal_tick.h\"\n#include \"libs/lvgl/lv_misc/lv_gc.h\"\n\n#if defined(LV_GC_INCLUDE)\n#include LV_GC_INCLUDE\n#endif /* LV_ENABLE_GC */\n/*********************\n *      DEFINES\n *********************/\n/*Decrement life with this value in every open*/\n#define LV_IMG_CACHE_AGING 1\n\n/*Boost life by this factor (multiply time_to_open with this value)*/\n#define LV_IMG_CACHE_LIFE_GAIN 1\n\n/*Don't let life to be greater than this limit because it would require a lot of time to\n * \"die\" from very high values */\n#define LV_IMG_CACHE_LIFE_LIMIT 1000\n\n#if LV_IMG_CACHE_DEF_SIZE < 1\n#error \"LV_IMG_CACHE_DEF_SIZE must be >= 1. See lv_conf.h\"\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic uint16_t entry_cnt;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Open an image using the image decoder interface and cache it.\n * The image will be left open meaning if the image decoder open callback allocated memory then it will remain.\n * The image is closed if a new image is opened and the new image takes its place in the cache.\n * @param src source of the image. Path to file or pointer to an `lv_img_dsc_t` variable\n * @param style style of the image\n * @return pointer to the cache entry or NULL if can open the image\n */\nlv_img_cache_entry_t * lv_img_cache_open(const void * src, const lv_style_t * style)\n{\n    if(entry_cnt == 0) {\n        LV_LOG_WARN(\"lv_img_cache_open: the cache size is 0\");\n        return NULL;\n    }\n\n    lv_img_cache_entry_t * cache = LV_GC_ROOT(_lv_img_cache_array);\n\n    /*Decrement all lifes. Make the entries older*/\n    uint16_t i;\n    for(i = 0; i < entry_cnt; i++) {\n        if(cache[i].life > INT32_MIN + LV_IMG_CACHE_AGING) {\n            cache[i].life -= LV_IMG_CACHE_AGING;\n        }\n    }\n\n    /*Is the image cached?*/\n    lv_img_cache_entry_t * cached_src = NULL;\n    for(i = 0; i < entry_cnt; i++) {\n        if(cache[i].dec_dsc.src == src) {\n            /* If opened increment its life.\n             * Image difficult to open should live longer to keep avoid frequent their recaching.\n             * Therefore increase `life` with `time_to_open`*/\n            cached_src = &cache[i];\n            cached_src->life += cached_src->dec_dsc.time_to_open * LV_IMG_CACHE_LIFE_GAIN;\n            if(cached_src->life > LV_IMG_CACHE_LIFE_LIMIT) cached_src->life = LV_IMG_CACHE_LIFE_LIMIT;\n            LV_LOG_TRACE(\"image draw: image found in the cache\");\n            break;\n        }\n    }\n\n    /*The image is not cached then cache it now*/\n    if(cached_src == NULL) {\n        /*Find an entry to reuse. Select the entry with the least life*/\n        cached_src = &cache[0];\n        for(i = 1; i < entry_cnt; i++) {\n            if(cache[i].life < cached_src->life) {\n                cached_src = &cache[i];\n            }\n        }\n\n        /*Close the decoder to reuse if it was opened (has a valid source)*/\n        if(cached_src->dec_dsc.src) {\n            lv_img_decoder_close(&cached_src->dec_dsc);\n            LV_LOG_INFO(\"image draw: cache miss, close and reuse an entry\");\n        } else {\n            LV_LOG_INFO(\"image draw: cache miss, cached to an empty entry\");\n        }\n\n        /*Open the image and measure the time to open*/\n        uint32_t t_start;\n        t_start                          = lv_tick_get();\n        cached_src->dec_dsc.time_to_open = 0;\n        lv_res_t open_res                = lv_img_decoder_open(&cached_src->dec_dsc, src, style);\n        if(open_res == LV_RES_INV) {\n            LV_LOG_WARN(\"Image draw cannot open the image resource\");\n            lv_img_decoder_close(&cached_src->dec_dsc);\n            memset(&cached_src->dec_dsc, 0, sizeof(lv_img_decoder_dsc_t));\n            memset(cached_src, 0, sizeof(lv_img_cache_entry_t));\n            cached_src->life = INT32_MIN; /*Make the empty entry very \"weak\" to force its use  */\n            return NULL;\n        }\n\n        cached_src->life = 0;\n\n        /*If `time_to_open` was not set in the open function set it here*/\n        if(cached_src->dec_dsc.time_to_open == 0) {\n            cached_src->dec_dsc.time_to_open = lv_tick_elaps(t_start);\n        }\n\n        if(cached_src->dec_dsc.time_to_open == 0) cached_src->dec_dsc.time_to_open = 1;\n    }\n\n    return cached_src;\n}\n\n/**\n * Set the number of images to be cached.\n * More cached images mean more opened image at same time which might mean more memory usage.\n * E.g. if 20 PNG or JPG images are open in the RAM they consume memory while opened in the cache.\n * @param new_entry_cnt number of image to cache\n */\nvoid lv_img_cache_set_size(uint16_t new_entry_cnt)\n{\n    if(LV_GC_ROOT(_lv_img_cache_array) != NULL) {\n        /*Clean the cache before free it*/\n        lv_img_cache_invalidate_src(NULL);\n        lv_mem_free(LV_GC_ROOT(_lv_img_cache_array));\n    }\n\n    /*Reallocate the cache*/\n    LV_GC_ROOT(_lv_img_cache_array) = lv_mem_alloc(sizeof(lv_img_cache_entry_t) * new_entry_cnt);\n    lv_mem_assert(LV_GC_ROOT(_lv_img_cache_array));\n    if(LV_GC_ROOT(_lv_img_cache_array) == NULL) {\n        entry_cnt = 0;\n        return;\n    }\n    entry_cnt = new_entry_cnt;\n\n    /*Clean the cache*/\n    uint16_t i;\n    for(i = 0; i < entry_cnt; i++) {\n        memset(&LV_GC_ROOT(_lv_img_cache_array)[i].dec_dsc, 0, sizeof(lv_img_decoder_dsc_t));\n        memset(&LV_GC_ROOT(_lv_img_cache_array)[i], 0, sizeof(lv_img_cache_entry_t));\n    }\n}\n\n/**\n * Invalidate an image source in the cache.\n * Useful if the image source is updated therefore it needs to be cached again.\n * @param src an image source path to a file or pointer to an `lv_img_dsc_t` variable.\n */\nvoid lv_img_cache_invalidate_src(const void * src)\n{\n\n    lv_img_cache_entry_t * cache = LV_GC_ROOT(_lv_img_cache_array);\n\n    uint16_t i;\n    for(i = 0; i < entry_cnt; i++) {\n        if(cache[i].dec_dsc.src == src || src == NULL) {\n            if(cache[i].dec_dsc.src != NULL) {\n                lv_img_decoder_close(&cache[i].dec_dsc);\n            }\n\n            memset(&cache[i].dec_dsc, 0, sizeof(lv_img_decoder_dsc_t));\n            memset(&cache[i], 0, sizeof(lv_img_cache_entry_t));\n        }\n    }\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_draw/lv_img_decoder.c",
    "content": "/**\n * @file lv_img_decoder.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_draw/lv_img_decoder.h\"\n#include \"libs/lvgl/lv_draw/lv_draw_img.h\"\n#include \"libs/lvgl/lv_misc/lv_ll.h\"\n#include \"libs/lvgl/lv_misc/lv_color.h\"\n#include \"libs/lvgl/lv_misc/lv_gc.h\"\n\n#if defined(LV_GC_INCLUDE)\n#include LV_GC_INCLUDE\n#endif /* LV_ENABLE_GC */\n\n/*********************\n *      DEFINES\n *********************/\n#define CF_BUILT_IN_FIRST LV_IMG_CF_TRUE_COLOR\n#define CF_BUILT_IN_LAST LV_IMG_CF_ALPHA_8BIT\n\n/**********************\n *      TYPEDEFS\n **********************/\ntypedef struct\n{\n#if LV_USE_FILESYSTEM\n    lv_fs_file_t * f;\n#endif\n    lv_color_t * palette;\n} lv_img_decoder_built_in_data_t;\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic lv_res_t lv_img_decoder_built_in_line_true_color(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,\n                                                        lv_coord_t len, uint8_t * buf);\nstatic lv_res_t lv_img_decoder_built_in_line_alpha(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,\n                                                   lv_coord_t len, uint8_t * buf);\nstatic lv_res_t lv_img_decoder_built_in_line_indexed(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,\n                                                     lv_coord_t len, uint8_t * buf);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Initialize the image decoder module\n * */\nvoid lv_img_decoder_init(void)\n{\n    lv_ll_init(&LV_GC_ROOT(_lv_img_defoder_ll), sizeof(lv_img_decoder_t));\n\n    lv_img_decoder_t * decoder;\n\n    /*Create a decoder for the built in color format*/\n    decoder = lv_img_decoder_create();\n    if(decoder == NULL) {\n        LV_LOG_WARN(\"lv_img_decoder_init: out of memory\");\n        lv_mem_assert(decoder);\n        return;\n    }\n\n    lv_img_decoder_set_info_cb(decoder, lv_img_decoder_built_in_info);\n    lv_img_decoder_set_open_cb(decoder, lv_img_decoder_built_in_open);\n    lv_img_decoder_set_read_line_cb(decoder, lv_img_decoder_built_in_read_line);\n    lv_img_decoder_set_close_cb(decoder, lv_img_decoder_built_in_close);\n}\n\n/**\n * Get information about an image.\n * Try the created image decoder one by one. Once one is able to get info that info will be used.\n * @param src the image source. E.g. file name or variable.\n * @param header the image info will be stored here\n * @return LV_RES_OK: success; LV_RES_INV: wasn't able to get info about the image\n */\nlv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header)\n{\n    header->always_zero = 0;\n\n    lv_res_t res = LV_RES_INV;\n    lv_img_decoder_t * d;\n    LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d)\n    {\n        res = LV_RES_INV;\n        if(d->info_cb) {\n            res = d->info_cb(d, src, header);\n            if(res == LV_RES_OK) break;\n        }\n    }\n\n    return res;\n}\n\n/**\n * Open an image.\n * Try the created image decoder one by one. Once one is able to open the image that decoder is save in `dsc`\n * @param dsc describe a decoding session. Simply a pointer to an `lv_img_decoder_dsc_t` variable.\n * @param src the image source. Can be\n *  1) File name: E.g. \"S:folder/img1.png\" (The drivers needs to registered via `lv_fs_add_drv()`)\n *  2) Variable: Pointer to an `lv_img_dsc_t` variable\n *  3) Symbol: E.g. `LV_SYMBOL_OK`\n * @param style the style of the image\n * @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set.\n *         LV_RES_INV: none of the registered image decoders were able to open the image.\n */\nlv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, const lv_style_t * style)\n{\n    dsc->style     = style;\n    dsc->src       = src;\n    dsc->src_type  = lv_img_src_get_type(src);\n    dsc->user_data = NULL;\n\n    lv_res_t res = LV_RES_INV;\n\n    lv_img_decoder_t * d;\n    LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d)\n    {\n        /*Info an Open callbacks are required*/\n        if(d->info_cb == NULL || d->open_cb == NULL) continue;\n\n        res = d->info_cb(d, src, &dsc->header);\n        if(res != LV_RES_OK) continue;\n\n        dsc->error_msg = NULL;\n        dsc->img_data  = NULL;\n        dsc->decoder   = d;\n\n        res = d->open_cb(d, dsc);\n\n        /*Opened successfully. It is a good decoder to for this image source*/\n        if(res == LV_RES_OK) break;\n    }\n\n    if(res == LV_RES_INV) {\n        memset(dsc, 0, sizeof(lv_img_decoder_dsc_t));\n    }\n\n    return res;\n}\n\n/**\n * Read a line from an opened image\n * @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open`\n * @param x start X coordinate (from left)\n * @param y start Y coordinate (from top)\n * @param len number of pixels to read\n * @param buf store the data here\n * @return LV_RES_OK: success; LV_RES_INV: an error occurred\n */\nlv_res_t lv_img_decoder_read_line(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf)\n{\n    lv_res_t res = LV_RES_INV;\n    if(dsc->decoder->read_line_cb) res = dsc->decoder->read_line_cb(dsc->decoder, dsc, x, y, len, buf);\n\n    return res;\n}\n\n/**\n * Close a decoding session\n * @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open`\n */\nvoid lv_img_decoder_close(lv_img_decoder_dsc_t * dsc)\n{\n    if(dsc->decoder) {\n        if(dsc->decoder->close_cb) dsc->decoder->close_cb(dsc->decoder, dsc);\n    }\n}\n\n/**\n * Create a new image decoder\n * @return pointer to the new image decoder\n */\nlv_img_decoder_t * lv_img_decoder_create(void)\n{\n    lv_img_decoder_t * decoder;\n    decoder = lv_ll_ins_head(&LV_GC_ROOT(_lv_img_defoder_ll));\n    lv_mem_assert(decoder);\n    if(decoder == NULL) return NULL;\n\n    memset(decoder, 0, sizeof(lv_img_decoder_t));\n\n    return decoder;\n}\n\n/**\n * Delete an image decoder\n * @param decoder pointer to an image decoder\n */\nvoid lv_img_decoder_delete(lv_img_decoder_t * decoder)\n{\n    lv_ll_rem(&LV_GC_ROOT(_lv_img_defoder_ll), decoder);\n    lv_mem_free(decoder);\n}\n\n/**\n * Set a callback to get information about the image\n * @param decoder pointer to an image decoder\n * @param info_cb a function to collect info about an image (fill an `lv_img_header_t` struct)\n */\nvoid lv_img_decoder_set_info_cb(lv_img_decoder_t * decoder, lv_img_decoder_info_f_t info_cb)\n{\n    decoder->info_cb = info_cb;\n}\n\n/**\n * Set a callback to open an image\n * @param decoder pointer to an image decoder\n * @param open_cb a function to open an image\n */\nvoid lv_img_decoder_set_open_cb(lv_img_decoder_t * decoder, lv_img_decoder_open_f_t open_cb)\n{\n    decoder->open_cb = open_cb;\n}\n\n/**\n * Set a callback to a decoded line of an image\n * @param decoder pointer to an image decoder\n * @param read_line_cb a function to read a line of an image\n */\nvoid lv_img_decoder_set_read_line_cb(lv_img_decoder_t * decoder, lv_img_decoder_read_line_f_t read_line_cb)\n{\n    decoder->read_line_cb = read_line_cb;\n}\n\n/**\n * Set a callback to close a decoding session. E.g. close files and free other resources.\n * @param decoder pointer to an image decoder\n * @param close_cb a function to close a decoding session\n */\nvoid lv_img_decoder_set_close_cb(lv_img_decoder_t * decoder, lv_img_decoder_close_f_t close_cb)\n{\n    decoder->close_cb = close_cb;\n}\n\n/**\n * Get info about a built-in image\n * @param decoder the decoder where this function belongs\n * @param src the image source: pointer to an `lv_img_dsc_t` variable, a file path or a symbol\n * @param header store the image data here\n * @return LV_RES_OK: the info is successfully stored in `header`; LV_RES_INV: unknown format or other error.\n */\nlv_res_t lv_img_decoder_built_in_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header)\n{\n    (void)decoder; /*Unused*/\n\n    lv_img_src_t src_type = lv_img_src_get_type(src);\n    if(src_type == LV_IMG_SRC_VARIABLE) {\n        lv_img_cf_t cf = ((lv_img_dsc_t *)src)->header.cf;\n        if(cf < CF_BUILT_IN_FIRST || cf > CF_BUILT_IN_LAST) return LV_RES_INV;\n\n        header->w  = ((lv_img_dsc_t *)src)->header.w;\n        header->h  = ((lv_img_dsc_t *)src)->header.h;\n        header->cf = ((lv_img_dsc_t *)src)->header.cf;\n    }\n#if LV_USE_FILESYSTEM\n    else if(src_type == LV_IMG_SRC_FILE) {\n        lv_fs_file_t file;\n        lv_fs_res_t res;\n        uint32_t rn;\n        res = lv_fs_open(&file, src, LV_FS_MODE_RD);\n        if(res == LV_FS_RES_OK) {\n            res = lv_fs_read(&file, header, sizeof(lv_img_header_t), &rn);\n            lv_fs_close(&file);\n        }\n\n        if(header->cf < CF_BUILT_IN_FIRST || header->cf > CF_BUILT_IN_LAST) return LV_RES_INV;\n\n    }\n#endif\n    else if(src_type == LV_IMG_SRC_SYMBOL) {\n        /*The size depend on the font but it is unknown here. It should be handled outside of the\n         * function*/\n        header->w = 1;\n        header->h = 1;\n        /* Symbols always have transparent parts. Important because of cover check in the design\n         * function. The actual value doesn't matter because lv_draw_label will draw it*/\n        header->cf = LV_IMG_CF_ALPHA_1BIT;\n    } else {\n        LV_LOG_WARN(\"Image get info found unknown src type\");\n        return LV_RES_INV;\n    }\n    return LV_RES_OK;\n}\n\n/**\n * Open a built in image\n * @param decoder the decoder where this function belongs\n * @param dsc pointer to decoder descriptor. `src`, `style` are already initialized in it.\n * @return LV_RES_OK: the info is successfully stored in `header`; LV_RES_INV: unknown format or other error.\n */\nlv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc)\n{\n    /*Open the file if it's a file*/\n    if(dsc->src_type == LV_IMG_SRC_FILE) {\n#if LV_USE_FILESYSTEM\n\n        /*Support only \"*.bin\" files*/\n        if(strcmp(lv_fs_get_ext(dsc->src), \"bin\")) return LV_RES_INV;\n\n        lv_fs_file_t f;\n        lv_fs_res_t res = lv_fs_open(&f, dsc->src, LV_FS_MODE_RD);\n        if(res != LV_FS_RES_OK) {\n            LV_LOG_WARN(\"Built-in image decoder can't open the file\");\n            return LV_RES_INV;\n        }\n\n        /*If the file was open successfully save the file descriptor*/\n        if(dsc->user_data == NULL) {\n            dsc->user_data = lv_mem_alloc(sizeof(lv_img_decoder_built_in_data_t));\n            if(dsc->user_data == NULL) {\n                LV_LOG_ERROR(\"img_decoder_built_in_open: out of memory\");\n                lv_mem_assert(dsc->user_data);\n            }\n            memset(dsc->user_data, 0, sizeof(lv_img_decoder_built_in_data_t));\n        }\n\n        lv_img_decoder_built_in_data_t * user_data = dsc->user_data;\n        user_data->f                               = lv_mem_alloc(sizeof(f));\n        if(user_data->f == NULL) {\n            LV_LOG_ERROR(\"img_decoder_built_in_open: out of memory\");\n            lv_mem_assert(user_data->f);\n        }\n\n        memcpy(user_data->f, &f, sizeof(f));\n\n#else\n        LV_LOG_WARN(\"Image built-in decoder cannot read file because LV_USE_FILESYSTEM = 0\");\n        return LV_RES_INV;\n#endif\n    }\n\n    lv_img_cf_t cf = dsc->header.cf;\n    /*Process true color formats*/\n    if(cf == LV_IMG_CF_TRUE_COLOR || cf == LV_IMG_CF_TRUE_COLOR_ALPHA || cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) {\n        if(dsc->src_type == LV_IMG_SRC_VARIABLE) {\n            /* In case of uncompressed formats the image stored in the ROM/RAM.\n             * So simply give its pointer*/\n            dsc->img_data = ((lv_img_dsc_t *)dsc->src)->data;\n            return LV_RES_OK;\n        } else {\n            /*If it's a file it need to be read line by line later*/\n            dsc->img_data = NULL;\n            return LV_RES_OK;\n        }\n    }\n    /*Process indexed images. Build a palette*/\n    else if(cf == LV_IMG_CF_INDEXED_1BIT || cf == LV_IMG_CF_INDEXED_2BIT || cf == LV_IMG_CF_INDEXED_4BIT ||\n            cf == LV_IMG_CF_INDEXED_8BIT) {\n\n#if LV_IMG_CF_INDEXED\n        uint8_t px_size       = lv_img_color_format_get_px_size(cf);\n        uint32_t palette_size = 1 << px_size;\n\n        /*Allocate the palette*/\n        if(dsc->user_data == NULL) {\n            dsc->user_data = lv_mem_alloc(sizeof(lv_img_decoder_built_in_data_t));\n            if(dsc->user_data == NULL) {\n                LV_LOG_ERROR(\"img_decoder_built_in_open: out of memory\");\n                lv_mem_assert(dsc->user_data);\n            }\n            memset(dsc->user_data, 0, sizeof(lv_img_decoder_built_in_data_t));\n        }\n\n        lv_img_decoder_built_in_data_t * user_data = dsc->user_data;\n        user_data->palette                         = lv_mem_alloc(palette_size * sizeof(lv_color_t));\n        if(user_data->palette == NULL) {\n            LV_LOG_ERROR(\"img_decoder_built_in_open: out of memory\");\n#if LV_USE_FILESYSTEM\n            lv_mem_assert(user_data->f);\n#endif\n        }\n\n        if(dsc->src_type == LV_IMG_SRC_FILE) {\n            /*Read the palette from file*/\n#if LV_USE_FILESYSTEM\n            lv_fs_seek(user_data->f, 4); /*Skip the header*/\n            lv_fs_read(user_data->f, user_data->palette, palette_size * sizeof(lv_color_t), NULL);\n#else\n            LV_LOG_WARN(\"Image built-in decoder can read the palette because LV_USE_FILESYSTEM = 0\");\n            return LV_RES_INV;\n#endif\n        } else {\n            /*The palette begins in the beginning of the image data. Just point to it.*/\n            lv_color32_t * palette_p = (lv_color32_t *)((lv_img_dsc_t *)dsc->src)->data;\n\n            uint32_t i;\n            for(i = 0; i < palette_size; i++) {\n                user_data->palette[i] = lv_color_make(palette_p[i].ch.red, palette_p[i].ch.green, palette_p[i].ch.blue);\n            }\n        }\n\n        dsc->img_data = NULL;\n        return LV_RES_OK;\n#else\n        LV_LOG_WARN(\"Indexed (palette) images are not enabled in lv_conf.h. See LV_IMG_CF_INDEXED\");\n        return LV_RES_INV;\n#endif\n    }\n    /*Alpha indexed images. */\n    else if(cf == LV_IMG_CF_ALPHA_1BIT || cf == LV_IMG_CF_ALPHA_2BIT || cf == LV_IMG_CF_ALPHA_4BIT ||\n            cf == LV_IMG_CF_ALPHA_8BIT) {\n#if LV_IMG_CF_ALPHA\n        dsc->img_data = NULL;\n        return LV_RES_OK; /*Nothing to process*/\n#else\n        LV_LOG_WARN(\"Alpha indexed images are not enabled in lv_conf.h. See LV_IMG_CF_ALPHA\");\n        return LV_RES_INV;\n#endif\n    }\n    /*Unknown format. Can't decode it.*/\n    else {\n        /*Free the potentially allocated memories*/\n        lv_img_decoder_built_in_close(decoder, dsc);\n\n        LV_LOG_WARN(\"Image decoder open: unknown color format\")\n        return LV_RES_INV;\n    }\n}\n\n/**\n * Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`.\n * Required only if the \"open\" function can't return with the whole decoded pixel array.\n * @param decoder pointer to the decoder the function associated with\n * @param dsc pointer to decoder descriptor\n * @param x start x coordinate\n * @param y start y coordinate\n * @param len number of pixels to decode\n * @param buf a buffer to store the decoded pixels\n * @return LV_RES_OK: ok; LV_RES_INV: failed\n */\nlv_res_t lv_img_decoder_built_in_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc, lv_coord_t x,\n                                                  lv_coord_t y, lv_coord_t len, uint8_t * buf)\n{\n    (void)decoder; /*Unused*/\n\n    lv_res_t res = LV_RES_INV;\n\n    if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA ||\n       dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) {\n        /* For TRUE_COLOR images read line required only for files.\n         * For variables the image data was returned in `open`*/\n        if(dsc->src_type == LV_IMG_SRC_FILE) {\n            res = lv_img_decoder_built_in_line_true_color(dsc, x, y, len, buf);\n        }\n    } else if(dsc->header.cf == LV_IMG_CF_ALPHA_1BIT || dsc->header.cf == LV_IMG_CF_ALPHA_2BIT ||\n              dsc->header.cf == LV_IMG_CF_ALPHA_4BIT || dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) {\n\n        res = lv_img_decoder_built_in_line_alpha(dsc, x, y, len, buf);\n    } else if(dsc->header.cf == LV_IMG_CF_INDEXED_1BIT || dsc->header.cf == LV_IMG_CF_INDEXED_2BIT ||\n              dsc->header.cf == LV_IMG_CF_INDEXED_4BIT || dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) {\n        res = lv_img_decoder_built_in_line_indexed(dsc, x, y, len, buf);\n    } else {\n        LV_LOG_WARN(\"Built-in image decoder read not supports the color format\");\n        return LV_RES_INV;\n    }\n\n    return res;\n}\n\n/**\n * Close the pending decoding. Free resources etc.\n * @param decoder pointer to the decoder the function associated with\n * @param dsc pointer to decoder descriptor\n */\nvoid lv_img_decoder_built_in_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc)\n{\n    (void)decoder; /*Unused*/\n\n    lv_img_decoder_built_in_data_t * user_data = dsc->user_data;\n    if(user_data) {\n#if LV_USE_FILESYSTEM\n        if(user_data->f) {\n            lv_fs_close(user_data->f);\n            lv_mem_free(user_data->f);\n        }\n#endif\n        if(user_data->palette) lv_mem_free(user_data->palette);\n\n        lv_mem_free(user_data);\n\n        dsc->user_data = NULL;\n    }\n}\n\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\nstatic lv_res_t lv_img_decoder_built_in_line_true_color(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,\n                                                        lv_coord_t len, uint8_t * buf)\n{\n#if LV_USE_FILESYSTEM\n    lv_img_decoder_built_in_data_t * user_data = dsc->user_data;\n    lv_fs_res_t res;\n    uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf);\n\n    uint32_t pos = ((y * dsc->header.w + x) * px_size) >> 3;\n    pos += 4; /*Skip the header*/\n    res = lv_fs_seek(user_data->f, pos);\n    if(res != LV_FS_RES_OK) {\n        LV_LOG_WARN(\"Built-in image decoder seek failed\");\n        return LV_RES_INV;\n    }\n    uint32_t btr = len * (px_size >> 3);\n    uint32_t br  = 0;\n    lv_fs_read(user_data->f, buf, btr, &br);\n    if(res != LV_FS_RES_OK || btr != br) {\n        LV_LOG_WARN(\"Built-in image decoder read failed\");\n        return LV_RES_INV;\n    }\n\n    return LV_RES_OK;\n#else\n    LV_LOG_WARN(\"Image built-in decoder cannot read file because LV_USE_FILESYSTEM = 0\");\n    return LV_RES_INV;\n#endif\n}\n\nstatic lv_res_t lv_img_decoder_built_in_line_alpha(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,\n                                                   lv_coord_t len, uint8_t * buf)\n{\n\n#if LV_IMG_CF_ALPHA\n    const lv_opa_t alpha1_opa_table[2]  = {0, 255};          /*Opacity mapping with bpp = 1 (Just for compatibility)*/\n    const lv_opa_t alpha2_opa_table[4]  = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/\n    const lv_opa_t alpha4_opa_table[16] = {0,  17, 34,  51,  /*Opacity mapping with bpp = 4*/\n                                           68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};\n\n    /*Simply fill the buffer with the color. Later only the alpha value will be modified.*/\n    lv_color_t bg_color = dsc->style->image.color;\n    lv_coord_t i;\n    for(i = 0; i < len; i++) {\n#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1\n        buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = bg_color.full;\n#elif LV_COLOR_DEPTH == 16\n        /*Because of Alpha byte 16 bit color can start on odd address which can cause crash*/\n        buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = bg_color.full & 0xFF;\n        buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + 1] = (bg_color.full >> 8) & 0xFF;\n#elif LV_COLOR_DEPTH == 32\n        *((uint32_t *)&buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE]) = bg_color.full;\n#else\n#error \"Invalid LV_COLOR_DEPTH. Check it in lv_conf.h\"\n#endif\n    }\n\n    const lv_opa_t * opa_table = NULL;\n    uint8_t px_size            = lv_img_color_format_get_px_size(dsc->header.cf);\n    uint16_t mask              = (1 << px_size) - 1; /*E.g. px_size = 2; mask = 0x03*/\n\n    lv_coord_t w = 0;\n    uint32_t ofs = 0;\n    int8_t pos   = 0;\n    switch(dsc->header.cf) {\n        case LV_IMG_CF_ALPHA_1BIT:\n            w = (dsc->header.w >> 3); /*E.g. w = 20 -> w = 2 + 1*/\n            if(dsc->header.w & 0x7) w++;\n            ofs += w * y + (x >> 3); /*First pixel*/\n            pos       = 7 - (x & 0x7);\n            opa_table = alpha1_opa_table;\n            break;\n        case LV_IMG_CF_ALPHA_2BIT:\n            w = (dsc->header.w >> 2); /*E.g. w = 13 -> w = 3 + 1 (bytes)*/\n            if(dsc->header.w & 0x3) w++;\n            ofs += w * y + (x >> 2); /*First pixel*/\n            pos       = 6 - ((x & 0x3) * 2);\n            opa_table = alpha2_opa_table;\n            break;\n        case LV_IMG_CF_ALPHA_4BIT:\n            w = (dsc->header.w >> 1); /*E.g. w = 13 -> w = 6 + 1 (bytes)*/\n            if(dsc->header.w & 0x1) w++;\n            ofs += w * y + (x >> 1); /*First pixel*/\n            pos       = 4 - ((x & 0x1) * 4);\n            opa_table = alpha4_opa_table;\n            break;\n        case LV_IMG_CF_ALPHA_8BIT:\n            w = dsc->header.w; /*E.g. x = 7 -> w = 7 (bytes)*/\n            ofs += w * y + x;  /*First pixel*/\n            pos = 0;\n            break;\n    }\n\n#if LV_USE_FILESYSTEM\n    lv_img_decoder_built_in_data_t * user_data = dsc->user_data;\n    uint8_t fs_buf[LV_HOR_RES_MAX];\n#endif\n\n    const uint8_t * data_tmp = NULL;\n    if(dsc->src_type == LV_IMG_SRC_VARIABLE) {\n        const lv_img_dsc_t * img_dsc = dsc->src;\n\n        data_tmp = img_dsc->data + ofs;\n    } else {\n#if LV_USE_FILESYSTEM\n        lv_fs_seek(user_data->f, ofs + 4); /*+4 to skip the header*/\n        lv_fs_read(user_data->f, fs_buf, w, NULL);\n        data_tmp = fs_buf;\n#else\n        LV_LOG_WARN(\"Image built-in alpha line reader can't read file because LV_USE_FILESYSTEM = 0\");\n        data_tmp = NULL; /*To avoid warnings*/\n        return LV_RES_INV;\n#endif\n    }\n\n    uint8_t byte_act = 0;\n    uint8_t val_act;\n    for(i = 0; i < len; i++) {\n        val_act = (data_tmp[byte_act] & (mask << pos)) >> pos;\n\n        buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + LV_IMG_PX_SIZE_ALPHA_BYTE - 1] =\n            dsc->header.cf == LV_IMG_CF_ALPHA_8BIT ? val_act : opa_table[val_act];\n\n        pos -= px_size;\n        if(pos < 0) {\n            pos = 8 - px_size;\n            data_tmp++;\n        }\n    }\n\n    return LV_RES_OK;\n\n#else\n    LV_LOG_WARN(\"Image built-in alpha line reader failed because LV_IMG_CF_ALPHA is 0 in lv_conf.h\");\n    return LV_RES_INV;\n#endif\n}\n\nstatic lv_res_t lv_img_decoder_built_in_line_indexed(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,\n                                                     lv_coord_t len, uint8_t * buf)\n{\n\n#if LV_IMG_CF_INDEXED\n    uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf);\n    uint16_t mask   = (1 << px_size) - 1; /*E.g. px_size = 2; mask = 0x03*/\n\n    lv_coord_t w = 0;\n    int8_t pos   = 0;\n    uint32_t ofs = 0;\n    switch(dsc->header.cf) {\n        case LV_IMG_CF_INDEXED_1BIT:\n            w = (dsc->header.w >> 3); /*E.g. w = 20 -> w = 2 + 1*/\n            if(dsc->header.w & 0x7) w++;\n            ofs += w * y + (x >> 3); /*First pixel*/\n            ofs += 8;                /*Skip the palette*/\n            pos = 7 - (x & 0x7);\n            break;\n        case LV_IMG_CF_INDEXED_2BIT:\n            w = (dsc->header.w >> 2); /*E.g. w = 13 -> w = 3 + 1 (bytes)*/\n            if(dsc->header.w & 0x3) w++;\n            ofs += w * y + (x >> 2); /*First pixel*/\n            ofs += 16;               /*Skip the palette*/\n            pos = 6 - ((x & 0x3) * 2);\n            break;\n        case LV_IMG_CF_INDEXED_4BIT:\n            w = (dsc->header.w >> 1); /*E.g. w = 13 -> w = 6 + 1 (bytes)*/\n            if(dsc->header.w & 0x1) w++;\n            ofs += w * y + (x >> 1); /*First pixel*/\n            ofs += 64;               /*Skip the palette*/\n            pos = 4 - ((x & 0x1) * 4);\n            break;\n        case LV_IMG_CF_INDEXED_8BIT:\n            w = dsc->header.w; /*E.g. x = 7 -> w = 7 (bytes)*/\n            ofs += w * y + x;  /*First pixel*/\n            ofs += 1024;       /*Skip the palette*/\n            pos = 0;\n            break;\n    }\n\n    lv_img_decoder_built_in_data_t * user_data = dsc->user_data;\n\n#if LV_USE_FILESYSTEM\n    uint8_t fs_buf[LV_HOR_RES_MAX];\n#endif\n    const uint8_t * data_tmp = NULL;\n    if(dsc->src_type == LV_IMG_SRC_VARIABLE) {\n        const lv_img_dsc_t * img_dsc = dsc->src;\n        data_tmp                     = img_dsc->data + ofs;\n    } else {\n#if LV_USE_FILESYSTEM\n        lv_fs_seek(user_data->f, ofs + 4); /*+4 to skip the header*/\n        lv_fs_read(user_data->f, fs_buf, w, NULL);\n        data_tmp = fs_buf;\n#else\n        LV_LOG_WARN(\"Image built-in indexed line reader can't read file because LV_USE_FILESYSTEM = 0\");\n        data_tmp = NULL; /*To avoid warnings*/\n        return LV_RES_INV;\n#endif\n    }\n\n    uint8_t byte_act = 0;\n    uint8_t val_act;\n    lv_coord_t i;\n    lv_color_t * cbuf = (lv_color_t *)buf;\n    for(i = 0; i < len; i++) {\n        val_act = (data_tmp[byte_act] & (mask << pos)) >> pos;\n        cbuf[i] = user_data->palette[val_act];\n\n        pos -= px_size;\n        if(pos < 0) {\n            pos = 8 - px_size;\n            data_tmp++;\n        }\n    }\n\n    return LV_RES_OK;\n#else\n    LV_LOG_WARN(\"Image built-in indexed line reader failed because LV_IMG_CF_INDEXED is 0 in lv_conf.h\");\n    return LV_RES_INV;\n#endif\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_font/lv_font.c",
    "content": "/**\n * @file lv_font.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n\n#include \"libs/lvgl/lv_font/lv_font.h\"\n#include \"libs/lvgl/lv_misc/lv_utils.h\"\n#include \"libs/lvgl/lv_misc/lv_log.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Return with the bitmap of a font.\n * @param font_p pointer to a font\n * @param letter an UNICODE character code\n * @return  pointer to the bitmap of the letter\n */\nconst uint8_t * lv_font_get_glyph_bitmap(const lv_font_t * font_p, uint32_t letter)\n{\n    return font_p->get_glyph_bitmap(font_p, letter);\n}\n\n/**\n * Get the descriptor of a glyph\n * @param font_p pointer to font\n * @param dsc_out store the result descriptor here\n * @param letter an UNICODE letter code\n * @return true: descriptor is successfully loaded into `dsc_out`.\n *         false: the letter was not found, no data is loaded to `dsc_out`\n */\nbool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_out, uint32_t letter, uint32_t letter_next)\n{\n    return font_p->get_glyph_dsc(font_p, dsc_out, letter, letter_next);\n}\n\n/**\n * Get the width of a glyph with kerning\n * @param font pointer to a font\n * @param letter an UNICODE letter\n * @param letter_next the next letter after `letter`. Used for kerning\n * @return the width of the glyph\n */\nuint16_t lv_font_get_glyph_width(const lv_font_t * font, uint32_t letter, uint32_t letter_next)\n{\n    lv_font_glyph_dsc_t g;\n    bool ret;\n    ret = lv_font_get_glyph_dsc(font, &g, letter, letter_next);\n    if(ret) return g.adv_w;\n    else return 0;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_font/lv_font.mk",
    "content": "CSRCS += lv_font.c\nCSRCS += lv_font_fmt_txt.c\nCSRCS += lv_font_unscii_8.c\n\nDEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_font\nVPATH += :$(LVGL_DIR)/lvgl/src/lv_font\n\nCFLAGS += \"-I$(LVGL_DIR)/lvgl/src/lv_font\"\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_font/lv_font_fmt_txt.c",
    "content": "/**\n * @file lv_font.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_font/lv_font.h\"\n#include \"libs/lvgl/lv_font/lv_font_fmt_txt.h\"\n#include \"libs/lvgl/lv_misc/lv_types.h\"\n#include \"libs/lvgl/lv_misc/lv_log.h\"\n#include \"libs/lvgl/lv_misc/lv_utils.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic uint32_t get_glyph_dsc_id(const lv_font_t * font, uint32_t letter);\nstatic int8_t get_kern_value(const lv_font_t * font, uint32_t gid_left, uint32_t gid_right);\nstatic int32_t unicode_list_compare(const void * ref, const void * element);\nstatic int32_t kern_pair_8_compare(const void * ref, const void * element);\nstatic int32_t kern_pair_16_compare(const void * ref, const void * element);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n * GLOBAL PROTOTYPES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Used as `get_glyph_bitmap` callback in LittelvGL's native font format if the font is uncompressed.\n * @param font pointer to font\n * @param unicode_letter an unicode letter which bitmap should be get\n * @return pointer to the bitmap or NULL if not found\n */\nconst uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t unicode_letter)\n{\n    lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *) font->dsc;\n    uint32_t gid = get_glyph_dsc_id(font, unicode_letter);\n    if(!gid) return false;\n\n    const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[gid];\n\n    if(gdsc) return &fdsc->glyph_bitmap[gdsc->bitmap_index];\n\n    /*If not returned earlier then the letter is not found in this font*/\n    return NULL;\n}\n\n/**\n * Used as `get_glyph_dsc` callback in LittelvGL's native font format if the font is uncompressed.\n * @param font_p pointer to font\n * @param dsc_out store the result descriptor here\n * @param letter an UNICODE letter code\n * @return true: descriptor is successfully loaded into `dsc_out`.\n *         false: the letter was not found, no data is loaded to `dsc_out`\n */\nbool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next)\n{\n    lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *) font->dsc;\n    uint32_t gid = get_glyph_dsc_id(font, unicode_letter);\n    if(!gid) return false;\n\n    int8_t kvalue = 0;\n    if(fdsc->kern_dsc) {\n        uint32_t gid_next = get_glyph_dsc_id(font, unicode_letter_next);\n        if(gid_next) {\n            kvalue = get_kern_value(font, gid, gid_next);\n        }\n    }\n\n    /*Put together a glyph dsc*/\n    const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[gid];\n\n    uint32_t adv_w = gdsc->adv_w + ((int32_t)((int32_t)kvalue * fdsc->kern_scale) >> 4);\n    adv_w  = (adv_w + (1 << 3)) >> 4;\n\n    dsc_out->adv_w = adv_w;\n    dsc_out->box_h = gdsc->box_h;\n    dsc_out->box_w = gdsc->box_w;\n    dsc_out->ofs_x = gdsc->ofs_x;\n    dsc_out->ofs_y = gdsc->ofs_y;\n    dsc_out->bpp   = fdsc->bpp;\n\n    return true;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\nstatic uint32_t get_glyph_dsc_id(const lv_font_t * font, uint32_t letter)\n{\n    if(letter == '\\0') return 0;\n\n    lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *) font->dsc;\n\n    /*Check the cache first*/\n    if(letter == fdsc->last_letter) return fdsc->last_glyph_id;\n\n    uint16_t i;\n    for(i = 0; i < fdsc->cmap_num; i++) {\n\n        /*Relative code point*/\n        uint32_t rcp = letter - fdsc->cmaps[i].range_start;\n        if(rcp > fdsc->cmaps[i].range_length) continue;\n        uint32_t glyph_id = 0;\n        if(fdsc->cmaps[i].type == LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY) {\n            glyph_id = fdsc->cmaps[i].glyph_id_start + rcp;\n        }\n        else if(fdsc->cmaps[i].type == LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL) {\n            const uint8_t * gid_ofs_8 = fdsc->cmaps[i].glyph_id_ofs_list;\n            glyph_id = fdsc->cmaps[i].glyph_id_start + gid_ofs_8[rcp];\n        }\n        else if(fdsc->cmaps[i].type == LV_FONT_FMT_TXT_CMAP_SPARSE_TINY) {\n            uint8_t * p = lv_utils_bsearch(&rcp, fdsc->cmaps[i].unicode_list, fdsc->cmaps[i].list_length, sizeof(fdsc->cmaps[i].unicode_list[0]), unicode_list_compare);\n\n            if(p) {\n                uint32_t ofs = (lv_uintptr_t)p - (lv_uintptr_t) fdsc->cmaps[i].unicode_list;\n                ofs = ofs >> 1;     /*The list stores `uint16_t` so the get the index divide by 2*/\n                glyph_id = fdsc->cmaps[i].glyph_id_start + ofs;\n            }\n        }\n        else if(fdsc->cmaps[i].type == LV_FONT_FMT_TXT_CMAP_SPARSE_FULL) {\n            uint8_t * p = lv_utils_bsearch(&rcp, fdsc->cmaps[i].unicode_list, fdsc->cmaps[i].list_length, sizeof(fdsc->cmaps[i].unicode_list[0]), unicode_list_compare);\n\n            if(p) {\n                uint32_t ofs = (lv_uintptr_t)p - (lv_uintptr_t) fdsc->cmaps[i].unicode_list;\n                ofs = ofs >> 1;     /*The list stores `uint16_t` so the get the index divide by 2*/\n                const uint8_t * gid_ofs_16 = fdsc->cmaps[i].glyph_id_ofs_list;\n                glyph_id = fdsc->cmaps[i].glyph_id_start + gid_ofs_16[ofs];\n            }\n        }\n\n        /*Update the cache*/\n        fdsc->last_letter = letter;\n        fdsc->last_glyph_id = glyph_id;\n        return glyph_id;\n    }\n\n    fdsc->last_letter = letter;\n    fdsc->last_glyph_id = 0;\n    return 0;\n\n}\n\nstatic int8_t get_kern_value(const lv_font_t * font, uint32_t gid_left, uint32_t gid_right)\n{\n    lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *) font->dsc;\n\n    int8_t value = 0;\n\n    if(fdsc->kern_classes == 0) {\n        /*Kern pairs*/\n        const lv_font_fmt_txt_kern_pair_t * kdsc = fdsc->kern_dsc;\n        if(kdsc->glyph_ids_size == 0) {\n            /* Use binary search to find the kern value.\n             * The pairs are ordered left_id first, then right_id secondly. */\n            const uint8_t * g_ids = kdsc->glyph_ids;\n            uint16_t g_id_both = (gid_right << 8) + gid_left; /*Create one number from the ids*/\n            uint8_t * kid_p = lv_utils_bsearch(&g_id_both, g_ids, kdsc->pair_cnt, 2, kern_pair_8_compare);\n\n            /*If the `g_id_both` were found get its index from the pointer*/\n            if(kid_p) {\n                uint32_t ofs = (lv_uintptr_t)kid_p - (lv_uintptr_t)g_ids;\n                ofs = ofs >> 1;     /*ofs is for pair, divide by 2 to refer as a single value*/\n                value = kdsc->values[ofs];\n            }\n        } else if(kdsc->glyph_ids_size == 1) {\n            /* Use binary search to find the kern value.\n             * The pairs are ordered left_id first, then right_id secondly. */\n            const uint16_t * g_ids = kdsc->glyph_ids;\n            uint32_t g_id_both = (uint32_t)((uint32_t)gid_right << 8) + gid_left; /*Create one number from the ids*/\n            uint8_t * kid_p = lv_utils_bsearch(&g_id_both, g_ids, kdsc->pair_cnt, 4, kern_pair_16_compare);\n\n            /*If the `g_id_both` were found get its index from the pointer*/\n            if(kid_p) {\n                uint32_t ofs = (lv_uintptr_t)kid_p - (lv_uintptr_t)g_ids;\n                ofs = ofs >> 4;     /*ofs is 4 byte pairs, divide by 4 to refer as a single value*/\n                value = kdsc->values[ofs];\n            }\n\n        } else {\n            /*Invalid value*/\n        }\n    } else {\n        /*Kern classes*/\n        const lv_font_fmt_txt_kern_classes_t * kdsc = fdsc->kern_dsc;\n        uint8_t left_class = kdsc->left_class_mapping[gid_left];\n        uint8_t right_class = kdsc->left_class_mapping[gid_right];\n\n        /* If class = 0, kerning not exist for that glyph\n         * else got the value form `class_pair_values` 2D array*/\n        if(left_class > 0 && right_class > 0) {\n            value = kdsc->class_pair_values[(left_class-1)* kdsc->right_class_cnt + (right_class-1)];\n        }\n\n    }\n    return value;\n}\n\nstatic int32_t kern_pair_8_compare(const void * ref, const void * element)\n{\n    const uint8_t * ref8_p = ref;\n    const uint8_t * element8_p = element;\n\n    /*If the MSB is different it will matter. If not return the diff. of the LSB*/\n    if(ref8_p[0] != element8_p[0]) return (int32_t)ref8_p[0] - element8_p[0];\n    else return (int32_t) ref8_p[1] - element8_p[1];\n\n}\n\nstatic int32_t kern_pair_16_compare(const void * ref, const void * element)\n{\n    const uint16_t * ref16_p = ref;\n    const uint16_t * element16_p = element;\n\n    /*If the MSB is different it will matter. If not return the diff. of the LSB*/\n    if(ref16_p[0] != element16_p[0]) return (int32_t)ref16_p[0] - element16_p[0];\n    else return (int32_t) ref16_p[1] - element16_p[1];\n}\n\n/** Code Comparator.\n *\n *  Compares the value of both input arguments.\n *\n *  @param[in]  pRef        Pointer to the reference.\n *  @param[in]  pElement    Pointer to the element to compare.\n *\n *  @return Result of comparison.\n *  @retval < 0   Reference is greater than element.\n *  @retval = 0   Reference is equal to element.\n *  @retval > 0   Reference is less than element.\n *\n */\nstatic int32_t unicode_list_compare(const void * ref, const void * element)\n{\n    return (*(uint16_t *)ref) - (*(uint16_t *)element);\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_font/lv_font_ma_110.c",
    "content": "#include \"libs/lvgl/lvgl.h\"\n#include \"core/argon-resources.h\"\n\n/*******************************************************************************\n * Size: 110 px\n * Bpp: 4\n * Opts: \n ******************************************************************************/\n\n#ifndef LV_FONT_MA_110\n#define LV_FONT_MA_110 1\n#endif\n\n#if LV_FONT_MA_110\n\n/*-----------------\n *    BITMAPS\n *----------------*/\n\n/*Store the image of the glyphs*/\n\n\n/*---------------------\n *  GLYPH DESCRIPTION\n *--------------------*/\nstatic const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {\n    {.bitmap_index = 0, .adv_w = 0, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,\n    {.bitmap_index = 0, .adv_w = 452, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 0, .adv_w = 444, .box_h = 78, .box_w = 10, .ofs_x = 9, .ofs_y = -1},\n    {.bitmap_index = 390, .adv_w = 628, .box_h = 29, .box_w = 23, .ofs_x = 8, .ofs_y = 48},\n    {.bitmap_index = 724, .adv_w = 1214, .box_h = 77, .box_w = 70, .ofs_x = 3, .ofs_y = 0},\n    {.bitmap_index = 3419, .adv_w = 1072, .box_h = 105, .box_w = 57, .ofs_x = 5, .ofs_y = -14},\n    {.bitmap_index = 6412, .adv_w = 1438, .box_h = 79, .box_w = 80, .ofs_x = 5, .ofs_y = -1},\n    {.bitmap_index = 9572, .adv_w = 1153, .box_h = 79, .box_w = 66, .ofs_x = 5, .ofs_y = -1},\n    {.bitmap_index = 12179, .adv_w = 341, .box_h = 29, .box_w = 6, .ofs_x = 8, .ofs_y = 48},\n    {.bitmap_index = 12266, .adv_w = 565, .box_h = 104, .box_w = 18, .ofs_x = 12, .ofs_y = -22},\n    {.bitmap_index = 13202, .adv_w = 567, .box_h = 104, .box_w = 19, .ofs_x = 5, .ofs_y = -22},\n    {.bitmap_index = 14190, .adv_w = 660, .box_h = 40, .box_w = 37, .ofs_x = 2, .ofs_y = 42},\n    {.bitmap_index = 14930, .adv_w = 1001, .box_h = 47, .box_w = 48, .ofs_x = 7, .ofs_y = 15},\n    {.bitmap_index = 16058, .adv_w = 352, .box_h = 25, .box_w = 10, .ofs_x = 6, .ofs_y = -16},\n    {.bitmap_index = 16183, .adv_w = 671, .box_h = 5, .box_w = 30, .ofs_x = 6, .ofs_y = 27},\n    {.bitmap_index = 16258, .adv_w = 352, .box_h = 10, .box_w = 10, .ofs_x = 6, .ofs_y = -1},\n    {.bitmap_index = 16308, .adv_w = 563, .box_h = 104, .box_w = 42, .ofs_x = -3, .ofs_y = -11},\n    {.bitmap_index = 18492, .adv_w = 1158, .box_h = 79, .box_w = 61, .ofs_x = 6, .ofs_y = -1},\n    {.bitmap_index = 20902, .adv_w = 621, .box_h = 77, .box_w = 26, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 21903, .adv_w = 991, .box_h = 78, .box_w = 56, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 24087, .adv_w = 982, .box_h = 78, .box_w = 55, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 26232, .adv_w = 1151, .box_h = 77, .box_w = 67, .ofs_x = 4, .ofs_y = 0},\n    {.bitmap_index = 28812, .adv_w = 982, .box_h = 78, .box_w = 54, .ofs_x = 3, .ofs_y = -1},\n    {.bitmap_index = 30918, .adv_w = 1060, .box_h = 79, .box_w = 57, .ofs_x = 6, .ofs_y = -1},\n    {.bitmap_index = 33170, .adv_w = 1023, .box_h = 77, .box_w = 56, .ofs_x = 3, .ofs_y = 0},\n    {.bitmap_index = 35326, .adv_w = 1112, .box_h = 79, .box_w = 59, .ofs_x = 5, .ofs_y = -1},\n    {.bitmap_index = 37657, .adv_w = 1060, .box_h = 79, .box_w = 58, .ofs_x = 3, .ofs_y = -1},\n    {.bitmap_index = 39948, .adv_w = 352, .box_h = 59, .box_w = 10, .ofs_x = 6, .ofs_y = -1},\n    {.bitmap_index = 40243, .adv_w = 352, .box_h = 74, .box_w = 10, .ofs_x = 6, .ofs_y = -16},\n    {.bitmap_index = 40613, .adv_w = 1001, .box_h = 45, .box_w = 47, .ofs_x = 8, .ofs_y = 16},\n    {.bitmap_index = 41671, .adv_w = 1001, .box_h = 31, .box_w = 47, .ofs_x = 8, .ofs_y = 23},\n    {.bitmap_index = 42400, .adv_w = 1001, .box_h = 43, .box_w = 47, .ofs_x = 8, .ofs_y = 17},\n    {.bitmap_index = 43411, .adv_w = 989, .box_h = 79, .box_w = 52, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 45465, .adv_w = 1818, .box_h = 100, .box_w = 102, .ofs_x = 6, .ofs_y = -22},\n    {.bitmap_index = 50565, .adv_w = 1412, .box_h = 78, .box_w = 64, .ofs_x = 12, .ofs_y = 0},\n    {.bitmap_index = 53061, .adv_w = 1324, .box_h = 77, .box_w = 64, .ofs_x = 13, .ofs_y = 0},\n    {.bitmap_index = 55525, .adv_w = 1260, .box_h = 79, .box_w = 68, .ofs_x = 6, .ofs_y = -1},\n    {.bitmap_index = 58211, .adv_w = 1454, .box_h = 77, .box_w = 72, .ofs_x = 13, .ofs_y = 0},\n    {.bitmap_index = 60983, .adv_w = 1102, .box_h = 79, .box_w = 61, .ofs_x = 6, .ofs_y = -1},\n    {.bitmap_index = 63393, .adv_w = 1054, .box_h = 78, .box_w = 52, .ofs_x = 12, .ofs_y = 0},\n    {.bitmap_index = 65421, .adv_w = 1360, .box_h = 79, .box_w = 68, .ofs_x = 6, .ofs_y = -1},\n    {.bitmap_index = 68107, .adv_w = 1433, .box_h = 77, .box_w = 64, .ofs_x = 13, .ofs_y = 0},\n    {.bitmap_index = 70571, .adv_w = 766, .box_h = 77, .box_w = 39, .ofs_x = 4, .ofs_y = 0},\n    {.bitmap_index = 72073, .adv_w = 862, .box_h = 89, .box_w = 42, .ofs_x = 0, .ofs_y = -12},\n    {.bitmap_index = 73942, .adv_w = 1237, .box_h = 77, .box_w = 64, .ofs_x = 13, .ofs_y = 0},\n    {.bitmap_index = 76406, .adv_w = 1030, .box_h = 77, .box_w = 51, .ofs_x = 13, .ofs_y = 0},\n    {.bitmap_index = 78370, .adv_w = 2156, .box_h = 78, .box_w = 109, .ofs_x = 13, .ofs_y = 0},\n    {.bitmap_index = 82621, .adv_w = 1406, .box_h = 78, .box_w = 63, .ofs_x = 13, .ofs_y = 0},\n    {.bitmap_index = 85078, .adv_w = 1475, .box_h = 79, .box_w = 80, .ofs_x = 6, .ofs_y = -1},\n    {.bitmap_index = 88238, .adv_w = 1258, .box_h = 77, .box_w = 60, .ofs_x = 13, .ofs_y = 0},\n    {.bitmap_index = 90548, .adv_w = 1475, .box_h = 93, .box_w = 81, .ofs_x = 6, .ofs_y = -15},\n    {.bitmap_index = 94315, .adv_w = 1267, .box_h = 77, .box_w = 61, .ofs_x = 13, .ofs_y = 0},\n    {.bitmap_index = 96664, .adv_w = 1072, .box_h = 79, .box_w = 57, .ofs_x = 5, .ofs_y = -1},\n    {.bitmap_index = 98916, .adv_w = 1000, .box_h = 78, .box_w = 63, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 101373, .adv_w = 1399, .box_h = 78, .box_w = 62, .ofs_x = 12, .ofs_y = -1},\n    {.bitmap_index = 103791, .adv_w = 1209, .box_h = 77, .box_w = 75, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 106679, .adv_w = 2116, .box_h = 78, .box_w = 108, .ofs_x = 12, .ofs_y = -1},\n    {.bitmap_index = 110891, .adv_w = 1130, .box_h = 77, .box_w = 67, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 113471, .adv_w = 1387, .box_h = 89, .box_w = 62, .ofs_x = 12, .ofs_y = -12},\n    {.bitmap_index = 116230, .adv_w = 1155, .box_h = 77, .box_w = 63, .ofs_x = 5, .ofs_y = 0},\n    {.bitmap_index = 118656, .adv_w = 539, .box_h = 104, .box_w = 19, .ofs_x = 13, .ofs_y = -22},\n    {.bitmap_index = 119644, .adv_w = 563, .box_h = 104, .box_w = 42, .ofs_x = -4, .ofs_y = -11},\n    {.bitmap_index = 121828, .adv_w = 539, .box_h = 104, .box_w = 19, .ofs_x = 2, .ofs_y = -22},\n    {.bitmap_index = 122816, .adv_w = 1003, .box_h = 47, .box_w = 43, .ofs_x = 10, .ofs_y = 15},\n    {.bitmap_index = 123827, .adv_w = 880, .box_h = 4, .box_w = 55, .ofs_x = 0, .ofs_y = -4},\n    {.bitmap_index = 123937, .adv_w = 1056, .box_h = 14, .box_w = 24, .ofs_x = 16, .ofs_y = 66},\n    {.bitmap_index = 124105, .adv_w = 1188, .box_h = 59, .box_w = 58, .ofs_x = 5, .ofs_y = -1},\n    {.bitmap_index = 125816, .adv_w = 1188, .box_h = 83, .box_w = 58, .ofs_x = 11, .ofs_y = -1},\n    {.bitmap_index = 128223, .adv_w = 977, .box_h = 59, .box_w = 52, .ofs_x = 5, .ofs_y = -1},\n    {.bitmap_index = 129757, .adv_w = 1188, .box_h = 83, .box_w = 58, .ofs_x = 5, .ofs_y = -1},\n    {.bitmap_index = 132164, .adv_w = 1051, .box_h = 59, .box_w = 56, .ofs_x = 5, .ofs_y = -1},\n    {.bitmap_index = 133816, .adv_w = 558, .box_h = 82, .box_w = 28, .ofs_x = 11, .ofs_y = 0},\n    {.bitmap_index = 134964, .adv_w = 1200, .box_h = 80, .box_w = 59, .ofs_x = 5, .ofs_y = -22},\n    {.bitmap_index = 137324, .adv_w = 1184, .box_h = 82, .box_w = 53, .ofs_x = 11, .ofs_y = 0},\n    {.bitmap_index = 139497, .adv_w = 459, .box_h = 81, .box_w = 9, .ofs_x = 10, .ofs_y = 0},\n    {.bitmap_index = 139862, .adv_w = 468, .box_h = 103, .box_w = 30, .ofs_x = -10, .ofs_y = -22},\n    {.bitmap_index = 141407, .adv_w = 1035, .box_h = 82, .box_w = 53, .ofs_x = 11, .ofs_y = 0},\n    {.bitmap_index = 143580, .adv_w = 524, .box_h = 83, .box_w = 23, .ofs_x = 11, .ofs_y = -1},\n    {.bitmap_index = 144535, .adv_w = 1873, .box_h = 58, .box_w = 95, .ofs_x = 11, .ofs_y = 0},\n    {.bitmap_index = 147290, .adv_w = 1184, .box_h = 58, .box_w = 52, .ofs_x = 11, .ofs_y = 0},\n    {.bitmap_index = 148798, .adv_w = 1091, .box_h = 59, .box_w = 58, .ofs_x = 5, .ofs_y = -1},\n    {.bitmap_index = 150509, .adv_w = 1188, .box_h = 80, .box_w = 58, .ofs_x = 11, .ofs_y = -22},\n    {.bitmap_index = 152829, .adv_w = 1188, .box_h = 80, .box_w = 58, .ofs_x = 5, .ofs_y = -22},\n    {.bitmap_index = 155149, .adv_w = 693, .box_h = 58, .box_w = 28, .ofs_x = 11, .ofs_y = 0},\n    {.bitmap_index = 155961, .adv_w = 841, .box_h = 59, .box_w = 46, .ofs_x = 3, .ofs_y = -1},\n    {.bitmap_index = 157318, .adv_w = 672, .box_h = 71, .box_w = 28, .ofs_x = 11, .ofs_y = -1},\n    {.bitmap_index = 158312, .adv_w = 1177, .box_h = 59, .box_w = 51, .ofs_x = 11, .ofs_y = -1},\n    {.bitmap_index = 159817, .adv_w = 929, .box_h = 58, .box_w = 58, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 161499, .adv_w = 1795, .box_h = 59, .box_w = 91, .ofs_x = 11, .ofs_y = -1},\n    {.bitmap_index = 164184, .adv_w = 913, .box_h = 58, .box_w = 53, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 165721, .adv_w = 1177, .box_h = 80, .box_w = 51, .ofs_x = 11, .ofs_y = -22},\n    {.bitmap_index = 167761, .adv_w = 903, .box_h = 58, .box_w = 46, .ofs_x = 5, .ofs_y = 0},\n    {.bitmap_index = 169095, .adv_w = 563, .box_h = 104, .box_w = 27, .ofs_x = 6, .ofs_y = -22},\n    {.bitmap_index = 170499, .adv_w = 512, .box_h = 104, .box_w = 6, .ofs_x = 13, .ofs_y = -22},\n    {.bitmap_index = 170811, .adv_w = 563, .box_h = 104, .box_w = 27, .ofs_x = 2, .ofs_y = -22},\n    {.bitmap_index = 172215, .adv_w = 1001, .box_h = 17, .box_w = 49, .ofs_x = 7, .ofs_y = 30},\n    {.bitmap_index = 172632, .adv_w = 1760, .box_h = 111, .box_w = 110, .ofs_x = 0, .ofs_y = -14},\n    {.bitmap_index = 178737, .adv_w = 1760, .box_h = 111, .box_w = 110, .ofs_x = 0, .ofs_y = -14}\n};\n\n/*---------------------\n *  CHARACTER MAPPING\n *--------------------*/\n\n\n\n/*Collect the unicode lists and glyph_id offsets*/\nstatic const uint16_t unicode_list_1[] = {\n    0x0, 0x61e\n};\n\n/*Collect the unicode lists and glyph_id offsets*/\nstatic const lv_font_fmt_txt_cmap_t cmaps[] =\n{\n    {\n        .range_start = 32, .range_length = 95, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY,\n        .glyph_id_start = 1, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0\n    },\n    {\n        .range_start = 61749, .range_length = 1567, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY,\n        .glyph_id_start = 96, .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 2\n    }\n};\n\n/*-----------------\n *    KERNING\n *----------------*/\n\n\n\n\n/*Collect the kern class' data in one place*/\nstatic const lv_font_fmt_txt_kern_classes_t kern_classes =\n{\n    .class_pair_values   = (const uint8_t*)(ARGON_RES_ADDR + MONTSERRAT_ALT_110_KERN_CLASS_VALUE),\n    .left_class_mapping  = (const uint8_t*)(ARGON_RES_ADDR + MONTSERRAT_ALT_110_KERN_LEFT_MAP),\n    .right_class_mapping = (const uint8_t*)(ARGON_RES_ADDR + MONTSERRAT_ALT_110_KERN_RIGHT_MAP),\n    .left_class_cnt      = 61,\n    .right_class_cnt     = 48,\n};\n\n/*--------------------\n *  ALL CUSTOM DATA\n *--------------------*/\n\n/*Store all the custom data of the font*/\nstatic lv_font_fmt_txt_dsc_t font_dsc = {\n    .glyph_bitmap = (const uint8_t*)(ARGON_RES_ADDR + MONTSERRAT_ALT_110_GLYPH_BMP),\n    .glyph_dsc = glyph_dsc,\n    .cmaps = cmaps,\n    .cmap_num = 2,\n    .bpp = 4,\n\n    .kern_scale = 33,\n    .kern_dsc = &kern_classes,\n    .kern_classes = 1\n};\n\n\n/*-----------------\n *  PUBLIC FONT\n *----------------*/\n\n/*Initialize a public general font descriptor*/\nlv_font_t lv_font_montserrat_alternate_110 = {\n    .dsc = &font_dsc,          /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */\n    .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt,    /*Function pointer to get glyph's bitmap*/\n    .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt,    /*Function pointer to get glyph's data*/\n    .line_height = 119,          /*The maximum line height required by the font*/\n    .base_line = 22,             /*Baseline measured from the bottom of the line*/\n};\n\n#endif /*#if MONTSERRAT_ALTERNATE_110*/\n\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_font/lv_font_ma_20.c",
    "content": "#include \"libs/lvgl/lvgl.h\"\n#include \"core/argon-resources.h\"\n\n\n#ifndef LV_FONT_MA_20\n#define LV_FONT_MA_20 1\n#endif\n\n#if LV_FONT_MA_20\n\n/*-----------------\n *    BITMAPS\n *----------------*/\nstatic const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {\n    {.bitmap_index = 0, .adv_w = 0, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,\n    {.bitmap_index = 0, .adv_w = 88, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 0, .adv_w = 94, .box_h = 16, .box_w = 4, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 32, .adv_w = 120, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = 9},\n    {.bitmap_index = 45, .adv_w = 235, .box_h = 15, .box_w = 13, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 143, .adv_w = 198, .box_h = 18, .box_w = 12, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 251, .adv_w = 252, .box_h = 16, .box_w = 14, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 363, .adv_w = 222, .box_h = 16, .box_w = 13, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 467, .adv_w = 74, .box_h = 5, .box_w = 3, .ofs_x = 1, .ofs_y = 9},\n    {.bitmap_index = 475, .adv_w = 106, .box_h = 19, .box_w = 5, .ofs_x = 1, .ofs_y = -3},\n    {.bitmap_index = 523, .adv_w = 106, .box_h = 19, .box_w = 6, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 580, .adv_w = 138, .box_h = 7, .box_w = 7, .ofs_x = 1, .ofs_y = 7},\n    {.bitmap_index = 605, .adv_w = 182, .box_h = 10, .box_w = 10, .ofs_x = 1, .ofs_y = 3},\n    {.bitmap_index = 655, .adv_w = 90, .box_h = 5, .box_w = 4, .ofs_x = 1, .ofs_y = -2},\n    {.bitmap_index = 665, .adv_w = 152, .box_h = 3, .box_w = 8, .ofs_x = 1, .ofs_y = 4},\n    {.bitmap_index = 677, .adv_w = 90, .box_h = 4, .box_w = 4, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 685, .adv_w = 188, .box_h = 20, .box_w = 12, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 805, .adv_w = 220, .box_h = 14, .box_w = 12, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 889, .adv_w = 122, .box_h = 12, .box_w = 6, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 925, .adv_w = 188, .box_h = 13, .box_w = 10, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 990, .adv_w = 185, .box_h = 15, .box_w = 11, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 1073, .adv_w = 183, .box_h = 14, .box_w = 11, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 1150, .adv_w = 185, .box_h = 15, .box_w = 10, .ofs_x = 1, .ofs_y = -3},\n    {.bitmap_index = 1225, .adv_w = 198, .box_h = 16, .box_w = 11, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 1313, .adv_w = 181, .box_h = 14, .box_w = 10, .ofs_x = 1, .ofs_y = -2},\n    {.bitmap_index = 1383, .adv_w = 204, .box_h = 16, .box_w = 11, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 1471, .adv_w = 198, .box_h = 16, .box_w = 11, .ofs_x = 1, .ofs_y = -3},\n    {.bitmap_index = 1559, .adv_w = 94, .box_h = 9, .box_w = 4, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 1577, .adv_w = 95, .box_h = 10, .box_w = 4, .ofs_x = 1, .ofs_y = -2},\n    {.bitmap_index = 1597, .adv_w = 189, .box_h = 12, .box_w = 10, .ofs_x = 1, .ofs_y = 2},\n    {.bitmap_index = 1657, .adv_w = 200, .box_h = 6, .box_w = 11, .ofs_x = 1, .ofs_y = 5},\n    {.bitmap_index = 1690, .adv_w = 189, .box_h = 12, .box_w = 10, .ofs_x = 1, .ofs_y = 2},\n    {.bitmap_index = 1750, .adv_w = 163, .box_h = 15, .box_w = 9, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1818, .adv_w = 289, .box_h = 17, .box_w = 17, .ofs_x = 1, .ofs_y = -3},\n    {.bitmap_index = 1963, .adv_w = 245, .box_h = 15, .box_w = 13, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 2061, .adv_w = 226, .box_h = 14, .box_w = 11, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 2138, .adv_w = 236, .box_h = 16, .box_w = 13, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 2242, .adv_w = 250, .box_h = 14, .box_w = 13, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 2333, .adv_w = 186, .box_h = 16, .box_w = 10, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 2413, .adv_w = 186, .box_h = 15, .box_w = 11, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 2496, .adv_w = 244, .box_h = 16, .box_w = 13, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 2600, .adv_w = 249, .box_h = 14, .box_w = 12, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 2684, .adv_w = 155, .box_h = 15, .box_w = 8, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 2744, .adv_w = 182, .box_h = 17, .box_w = 10, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 2829, .adv_w = 225, .box_h = 14, .box_w = 12, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 2913, .adv_w = 181, .box_h = 14, .box_w = 10, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 2983, .adv_w = 345, .box_h = 15, .box_w = 18, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 3118, .adv_w = 249, .box_h = 15, .box_w = 12, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 3208, .adv_w = 269, .box_h = 16, .box_w = 15, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 3328, .adv_w = 219, .box_h = 14, .box_w = 11, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 3405, .adv_w = 269, .box_h = 18, .box_w = 15, .ofs_x = 1, .ofs_y = -3},\n    {.bitmap_index = 3540, .adv_w = 233, .box_h = 14, .box_w = 12, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 3624, .adv_w = 202, .box_h = 16, .box_w = 12, .ofs_x = 0, .ofs_y = -1},\n    {.bitmap_index = 3720, .adv_w = 216, .box_h = 15, .box_w = 13, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 3818, .adv_w = 249, .box_h = 15, .box_w = 13, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 3916, .adv_w = 224, .box_h = 14, .box_w = 14, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 4014, .adv_w = 335, .box_h = 15, .box_w = 19, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 4157, .adv_w = 217, .box_h = 14, .box_w = 13, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 4248, .adv_w = 232, .box_h = 17, .box_w = 12, .ofs_x = 1, .ofs_y = -3},\n    {.bitmap_index = 4350, .adv_w = 216, .box_h = 14, .box_w = 12, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 4434, .adv_w = 114, .box_h = 19, .box_w = 6, .ofs_x = 1, .ofs_y = -3},\n    {.bitmap_index = 4491, .adv_w = 167, .box_h = 16, .box_w = 10, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 4571, .adv_w = 114, .box_h = 19, .box_w = 6, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 4628, .adv_w = 126, .box_h = 4, .box_w = 8, .ofs_x = 0, .ofs_y = 14},\n    {.bitmap_index = 4644, .adv_w = 231, .box_h = 2, .box_w = 12, .ofs_x = 1, .ofs_y = -3},\n    {.bitmap_index = 4656, .adv_w = 267, .box_h = 3, .box_w = 5, .ofs_x = 6, .ofs_y = 12},\n    {.bitmap_index = 4664, .adv_w = 215, .box_h = 12, .box_w = 11, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 4730, .adv_w = 215, .box_h = 16, .box_w = 12, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 4826, .adv_w = 184, .box_h = 12, .box_w = 10, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 4886, .adv_w = 215, .box_h = 16, .box_w = 11, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 4974, .adv_w = 196, .box_h = 12, .box_w = 11, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 5040, .adv_w = 118, .box_h = 15, .box_w = 8, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 5100, .adv_w = 209, .box_h = 16, .box_w = 11, .ofs_x = 1, .ofs_y = -5},\n    {.bitmap_index = 5188, .adv_w = 207, .box_h = 15, .box_w = 11, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 5271, .adv_w = 88, .box_h = 16, .box_w = 4, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 5303, .adv_w = 88, .box_h = 21, .box_w = 7, .ofs_x = -3, .ofs_y = -5},\n    {.bitmap_index = 5377, .adv_w = 186, .box_h = 15, .box_w = 11, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 5460, .adv_w = 110, .box_h = 15, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 5505, .adv_w = 324, .box_h = 11, .box_w = 18, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 5604, .adv_w = 207, .box_h = 11, .box_w = 11, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 5665, .adv_w = 209, .box_h = 12, .box_w = 11, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 5731, .adv_w = 215, .box_h = 15, .box_w = 12, .ofs_x = 1, .ofs_y = -4},\n    {.bitmap_index = 5821, .adv_w = 215, .box_h = 15, .box_w = 11, .ofs_x = 1, .ofs_y = -4},\n    {.bitmap_index = 5904, .adv_w = 127, .box_h = 11, .box_w = 7, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 5943, .adv_w = 162, .box_h = 12, .box_w = 10, .ofs_x = 0, .ofs_y = -1},\n    {.bitmap_index = 6003, .adv_w = 124, .box_h = 15, .box_w = 7, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 6056, .adv_w = 207, .box_h = 12, .box_w = 11, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 6122, .adv_w = 183, .box_h = 11, .box_w = 12, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 6188, .adv_w = 292, .box_h = 11, .box_w = 18, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 6287, .adv_w = 179, .box_h = 11, .box_w = 11, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 6348, .adv_w = 206, .box_h = 16, .box_w = 11, .ofs_x = 1, .ofs_y = -5},\n    {.bitmap_index = 6436, .adv_w = 173, .box_h = 11, .box_w = 9, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 6486, .adv_w = 108, .box_h = 19, .box_w = 6, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 6543, .adv_w = 82, .box_h = 20, .box_w = 3, .ofs_x = 1, .ofs_y = -4},\n    {.bitmap_index = 6573, .adv_w = 108, .box_h = 19, .box_w = 5, .ofs_x = 1, .ofs_y = -3},\n    {.bitmap_index = 6621, .adv_w = 184, .box_h = 5, .box_w = 10, .ofs_x = 1, .ofs_y = 5},\n    {.bitmap_index = 6646, .adv_w = 274, .box_h = 19, .box_w = 18, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 6817, .adv_w = 343, .box_h = 19, .box_w = 22, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 7026, .adv_w = 320, .box_h = 16, .box_w = 20, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 7186, .adv_w = 320, .box_h = 14, .box_w = 18, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 7312, .adv_w = 251, .box_h = 14, .box_w = 14, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 7410, .adv_w = 274, .box_h = 20, .box_w = 18, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 7590, .adv_w = 274, .box_h = 18, .box_w = 18, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 7752, .adv_w = 251, .box_h = 18, .box_w = 16, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 7896, .adv_w = 297, .box_h = 15, .box_w = 19, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 8039, .adv_w = 297, .box_h = 18, .box_w = 19, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 8210, .adv_w = 274, .box_h = 15, .box_w = 18, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 8345, .adv_w = 274, .box_h = 18, .box_w = 18, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 8507, .adv_w = 137, .box_h = 14, .box_w = 9, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 8570, .adv_w = 206, .box_h = 14, .box_w = 13, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 8661, .adv_w = 297, .box_h = 16, .box_w = 19, .ofs_x = 0, .ofs_y = -1},\n    {.bitmap_index = 8813, .adv_w = 343, .box_h = 18, .box_w = 22, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 9011, .adv_w = 274, .box_h = 18, .box_w = 17, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 9164, .adv_w = 183, .box_h = 18, .box_w = 12, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 9272, .adv_w = 251, .box_h = 18, .box_w = 16, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 9416, .adv_w = 274, .box_h = 18, .box_w = 18, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 9578, .adv_w = 274, .box_h = 18, .box_w = 18, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 9740, .adv_w = 183, .box_h = 18, .box_w = 12, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 9848, .adv_w = 275, .box_h = 15, .box_w = 18, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 9983, .adv_w = 229, .box_h = 18, .box_w = 13, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 10100, .adv_w = 229, .box_h = 19, .box_w = 12, .ofs_x = 1, .ofs_y = -2},\n    {.bitmap_index = 10214, .adv_w = 251, .box_h = 16, .box_w = 16, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 10342, .adv_w = 251, .box_h = 5, .box_w = 16, .ofs_x = 0, .ofs_y = 5},\n    {.bitmap_index = 10382, .adv_w = 320, .box_h = 19, .box_w = 20, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 10572, .adv_w = 320, .box_h = 18, .box_w = 20, .ofs_x = 0, .ofs_y = -1},\n    {.bitmap_index = 10752, .adv_w = 320, .box_h = 12, .box_w = 18, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 10860, .adv_w = 320, .box_h = 13, .box_w = 18, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 10977, .adv_w = 343, .box_h = 13, .box_w = 22, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 11120, .adv_w = 297, .box_h = 16, .box_w = 19, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 11272, .adv_w = 297, .box_h = 19, .box_w = 19, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 11453, .adv_w = 251, .box_h = 16, .box_w = 16, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 11581, .adv_w = 320, .box_h = 17, .box_w = 20, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 11751, .adv_w = 320, .box_h = 21, .box_w = 20, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 11961, .adv_w = 274, .box_h = 18, .box_w = 18, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 12123, .adv_w = 160, .box_h = 19, .box_w = 10, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 12218, .adv_w = 320, .box_h = 20, .box_w = 20, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 12418, .adv_w = 343, .box_h = 13, .box_w = 22, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 12561, .adv_w = 251, .box_h = 17, .box_w = 16, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 12697, .adv_w = 274, .box_h = 21, .box_w = 18, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 12886, .adv_w = 366, .box_h = 16, .box_w = 23, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 13070, .adv_w = 411, .box_h = 15, .box_w = 26, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 13265, .adv_w = 411, .box_h = 15, .box_w = 26, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 13460, .adv_w = 411, .box_h = 15, .box_w = 26, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 13655, .adv_w = 411, .box_h = 15, .box_w = 26, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 13850, .adv_w = 411, .box_h = 15, .box_w = 26, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 14045, .adv_w = 274, .box_h = 21, .box_w = 15, .ofs_x = 1, .ofs_y = -3}\n};\n\n/*---------------------\n *  CHARACTER MAPPING\n *--------------------*/\n\nstatic const uint16_t unicode_list_1[] = {\n    0x0, 0x7, 0xa, 0xb, 0xc, 0x10, 0x12, 0x13,\n    0x14, 0x18, 0x1b, 0x20, 0x25, 0x26, 0x27, 0x3d,\n    0x3f, 0x47, 0x4a, 0x4b, 0x4c, 0x50, 0x51, 0x52,\n    0x53, 0x66, 0x67, 0x70, 0x73, 0x76, 0x77, 0x78,\n    0x7a, 0x92, 0x94, 0xc3, 0xc4, 0xc6, 0xe6, 0xf2,\n    0x11b, 0x123, 0x15a, 0x1ea, 0x23f, 0x240, 0x241, 0x242,\n    0x243, 0x292\n};\n\n/*Collect the unicode lists and glyph_id offsets*/\nstatic const lv_font_fmt_txt_cmap_t cmaps[] =\n{\n    {\n        .range_start = 32, .range_length = 95, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY,\n        .glyph_id_start = 1, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0\n    },\n    {\n        .range_start = 61441, .range_length = 659, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY,\n        .glyph_id_start = 96, .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 50\n    }\n};\n\n\nstatic const lv_font_fmt_txt_kern_pair_t kern_pairs =\n{\n    .glyph_ids = (const uint8_t *)(ARGON_RES_ADDR + MONTSERRAT_ALT_20_KERN_PAIR_GLYPH),\n    .values = (const int8_t *)(ARGON_RES_ADDR + MONTSERRAT_ALT_20_KERN_PAIR_VALUE),\n    .pair_cnt = 210,\n    .glyph_ids_size = 0\n};\n\n/*--------------------\n *  ALL CUSTOM DATA\n *--------------------*/\n\n/*Store all the custom data of the font*/\nstatic lv_font_fmt_txt_dsc_t font_dsc = {\n    .glyph_bitmap = (const uint8_t *)(ARGON_RES_ADDR + MONTSERRAT_ALT_20_GLYPH_BMP),\n    .glyph_dsc = glyph_dsc,\n    .cmaps = cmaps,\n    .cmap_num = 2,\n    .bpp = 4,\n\n    .kern_scale = 16,\n    .kern_dsc = &kern_pairs,\n    .kern_classes = 0\n};\n\n\n/*-----------------\n *  PUBLIC FONT\n *----------------*/\n\n/*Initialize a public general font descriptor*/\nlv_font_t lv_font_montserrat_alternate_20 = {\n    .dsc = &font_dsc,          /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */\n    .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt,    /*Function pointer to get glyph's bitmap*/\n    .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt,    /*Function pointer to get glyph's data*/\n    .line_height = 23,          /*The maximum line height required by the font*/\n    .base_line = 5,             /*Baseline measured from the bottom of the line*/\n};\n\n#endif"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_font/lv_font_ma_30.c",
    "content": "#include \"libs/lvgl/lvgl.h\"\n#include \"core/argon-resources.h\"\n\n\n#ifndef LV_FONT_MA_30\n#define LV_FONT_MA_30 1\n#endif\n\n#if LV_FONT_MA_30\n\n/*-----------------\n *    BITMAPS\n *----------------*/\nstatic const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {\n    {.bitmap_index = 0, .adv_w = 0, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,\n    {.bitmap_index = 0, .adv_w = 132, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 0, .adv_w = 142, .box_h = 23, .box_w = 5, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 58, .adv_w = 180, .box_h = 8, .box_w = 7, .ofs_x = 2, .ofs_y = 13},\n    {.bitmap_index = 86, .adv_w = 353, .box_h = 22, .box_w = 20, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 306, .adv_w = 297, .box_h = 26, .box_w = 17, .ofs_x = 1, .ofs_y = -3},\n    {.bitmap_index = 527, .adv_w = 377, .box_h = 23, .box_w = 22, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 780, .adv_w = 333, .box_h = 23, .box_w = 19, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 999, .adv_w = 111, .box_h = 8, .box_w = 3, .ofs_x = 2, .ofs_y = 13},\n    {.bitmap_index = 1011, .adv_w = 159, .box_h = 27, .box_w = 8, .ofs_x = 1, .ofs_y = -4},\n    {.bitmap_index = 1119, .adv_w = 159, .box_h = 27, .box_w = 8, .ofs_x = 1, .ofs_y = -4},\n    {.bitmap_index = 1227, .adv_w = 207, .box_h = 10, .box_w = 10, .ofs_x = 1, .ofs_y = 11},\n    {.bitmap_index = 1277, .adv_w = 273, .box_h = 15, .box_w = 15, .ofs_x = 1, .ofs_y = 4},\n    {.bitmap_index = 1390, .adv_w = 135, .box_h = 9, .box_w = 5, .ofs_x = 2, .ofs_y = -4},\n    {.bitmap_index = 1413, .adv_w = 228, .box_h = 4, .box_w = 11, .ofs_x = 2, .ofs_y = 7},\n    {.bitmap_index = 1435, .adv_w = 134, .box_h = 6, .box_w = 5, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 1450, .adv_w = 282, .box_h = 29, .box_w = 17, .ofs_x = 0, .ofs_y = -4},\n    {.bitmap_index = 1697, .adv_w = 330, .box_h = 20, .box_w = 18, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 1877, .adv_w = 183, .box_h = 18, .box_w = 9, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1958, .adv_w = 283, .box_h = 19, .box_w = 15, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 2101, .adv_w = 277, .box_h = 22, .box_w = 15, .ofs_x = 1, .ofs_y = -4},\n    {.bitmap_index = 2266, .adv_w = 275, .box_h = 21, .box_w = 15, .ofs_x = 1, .ofs_y = -3},\n    {.bitmap_index = 2424, .adv_w = 278, .box_h = 22, .box_w = 15, .ofs_x = 1, .ofs_y = -4},\n    {.bitmap_index = 2589, .adv_w = 298, .box_h = 23, .box_w = 16, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 2773, .adv_w = 272, .box_h = 21, .box_w = 16, .ofs_x = 1, .ofs_y = -3},\n    {.bitmap_index = 2941, .adv_w = 305, .box_h = 23, .box_w = 17, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 3137, .adv_w = 297, .box_h = 23, .box_w = 16, .ofs_x = 1, .ofs_y = -4},\n    {.bitmap_index = 3321, .adv_w = 141, .box_h = 13, .box_w = 5, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 3354, .adv_w = 142, .box_h = 16, .box_w = 5, .ofs_x = 2, .ofs_y = -4},\n    {.bitmap_index = 3394, .adv_w = 284, .box_h = 18, .box_w = 15, .ofs_x = 1, .ofs_y = 3},\n    {.bitmap_index = 3529, .adv_w = 300, .box_h = 9, .box_w = 16, .ofs_x = 1, .ofs_y = 7},\n    {.bitmap_index = 3601, .adv_w = 284, .box_h = 18, .box_w = 15, .ofs_x = 2, .ofs_y = 3},\n    {.bitmap_index = 3736, .adv_w = 244, .box_h = 23, .box_w = 13, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 3886, .adv_w = 434, .box_h = 25, .box_w = 25, .ofs_x = 1, .ofs_y = -4},\n    {.bitmap_index = 4199, .adv_w = 368, .box_h = 22, .box_w = 19, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 4408, .adv_w = 339, .box_h = 21, .box_w = 17, .ofs_x = 3, .ofs_y = 0},\n    {.bitmap_index = 4587, .adv_w = 353, .box_h = 23, .box_w = 20, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 4817, .adv_w = 375, .box_h = 21, .box_w = 19, .ofs_x = 3, .ofs_y = 0},\n    {.bitmap_index = 5017, .adv_w = 279, .box_h = 23, .box_w = 16, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 5201, .adv_w = 279, .box_h = 22, .box_w = 15, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 5366, .adv_w = 366, .box_h = 23, .box_w = 20, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 5596, .adv_w = 373, .box_h = 21, .box_w = 18, .ofs_x = 3, .ofs_y = 0},\n    {.bitmap_index = 5785, .adv_w = 232, .box_h = 22, .box_w = 12, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 5917, .adv_w = 273, .box_h = 25, .box_w = 15, .ofs_x = 0, .ofs_y = -4},\n    {.bitmap_index = 6105, .adv_w = 338, .box_h = 21, .box_w = 18, .ofs_x = 3, .ofs_y = 0},\n    {.bitmap_index = 6294, .adv_w = 272, .box_h = 21, .box_w = 15, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 6452, .adv_w = 517, .box_h = 22, .box_w = 27, .ofs_x = 3, .ofs_y = 0},\n    {.bitmap_index = 6749, .adv_w = 373, .box_h = 22, .box_w = 18, .ofs_x = 3, .ofs_y = 0},\n    {.bitmap_index = 6947, .adv_w = 403, .box_h = 23, .box_w = 23, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 7212, .adv_w = 328, .box_h = 21, .box_w = 17, .ofs_x = 3, .ofs_y = 0},\n    {.bitmap_index = 7391, .adv_w = 403, .box_h = 26, .box_w = 23, .ofs_x = 1, .ofs_y = -4},\n    {.bitmap_index = 7690, .adv_w = 349, .box_h = 21, .box_w = 18, .ofs_x = 3, .ofs_y = 0},\n    {.bitmap_index = 7879, .adv_w = 302, .box_h = 23, .box_w = 17, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 8075, .adv_w = 324, .box_h = 22, .box_w = 20, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 8295, .adv_w = 373, .box_h = 22, .box_w = 19, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 8504, .adv_w = 336, .box_h = 21, .box_w = 21, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 8725, .adv_w = 503, .box_h = 22, .box_w = 27, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 9022, .adv_w = 325, .box_h = 21, .box_w = 20, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 9232, .adv_w = 348, .box_h = 25, .box_w = 17, .ofs_x = 2, .ofs_y = -4},\n    {.bitmap_index = 9445, .adv_w = 324, .box_h = 21, .box_w = 18, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 9634, .adv_w = 170, .box_h = 28, .box_w = 8, .ofs_x = 2, .ofs_y = -5},\n    {.bitmap_index = 9746, .adv_w = 251, .box_h = 23, .box_w = 15, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 9919, .adv_w = 170, .box_h = 28, .box_w = 8, .ofs_x = 1, .ofs_y = -5},\n    {.bitmap_index = 10031, .adv_w = 189, .box_h = 5, .box_w = 11, .ofs_x = 0, .ofs_y = 22},\n    {.bitmap_index = 10059, .adv_w = 347, .box_h = 3, .box_w = 18, .ofs_x = 2, .ofs_y = -5},\n    {.bitmap_index = 10086, .adv_w = 400, .box_h = 5, .box_w = 7, .ofs_x = 9, .ofs_y = 18},\n    {.bitmap_index = 10104, .adv_w = 323, .box_h = 18, .box_w = 17, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 10257, .adv_w = 323, .box_h = 24, .box_w = 17, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 10461, .adv_w = 276, .box_h = 18, .box_w = 15, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 10596, .adv_w = 323, .box_h = 24, .box_w = 17, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 10800, .adv_w = 294, .box_h = 18, .box_w = 17, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 10953, .adv_w = 178, .box_h = 22, .box_w = 11, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 11074, .adv_w = 314, .box_h = 24, .box_w = 17, .ofs_x = 1, .ofs_y = -7},\n    {.bitmap_index = 11278, .adv_w = 310, .box_h = 23, .box_w = 16, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 11462, .adv_w = 132, .box_h = 23, .box_w = 5, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 11520, .adv_w = 132, .box_h = 30, .box_w = 11, .ofs_x = -4, .ofs_y = -7},\n    {.bitmap_index = 11685, .adv_w = 279, .box_h = 23, .box_w = 15, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 11858, .adv_w = 165, .box_h = 22, .box_w = 9, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 11957, .adv_w = 487, .box_h = 17, .box_w = 27, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 12187, .adv_w = 310, .box_h = 17, .box_w = 16, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 12323, .adv_w = 313, .box_h = 18, .box_w = 18, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 12485, .adv_w = 323, .box_h = 23, .box_w = 17, .ofs_x = 2, .ofs_y = -6},\n    {.bitmap_index = 12681, .adv_w = 323, .box_h = 23, .box_w = 17, .ofs_x = 1, .ofs_y = -6},\n    {.bitmap_index = 12877, .adv_w = 191, .box_h = 17, .box_w = 9, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 12954, .adv_w = 243, .box_h = 18, .box_w = 13, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 13071, .adv_w = 186, .box_h = 22, .box_w = 10, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 13181, .adv_w = 310, .box_h = 17, .box_w = 15, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 13309, .adv_w = 275, .box_h = 16, .box_w = 17, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 13445, .adv_w = 438, .box_h = 16, .box_w = 27, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 13661, .adv_w = 268, .box_h = 16, .box_w = 16, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 13789, .adv_w = 310, .box_h = 23, .box_w = 16, .ofs_x = 1, .ofs_y = -7},\n    {.bitmap_index = 13973, .adv_w = 259, .box_h = 16, .box_w = 14, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 14085, .adv_w = 161, .box_h = 28, .box_w = 8, .ofs_x = 1, .ofs_y = -5},\n    {.bitmap_index = 14197, .adv_w = 123, .box_h = 29, .box_w = 4, .ofs_x = 2, .ofs_y = -5},\n    {.bitmap_index = 14255, .adv_w = 161, .box_h = 28, .box_w = 8, .ofs_x = 1, .ofs_y = -5},\n    {.bitmap_index = 14367, .adv_w = 276, .box_h = 7, .box_w = 15, .ofs_x = 1, .ofs_y = 8},\n    {.bitmap_index = 14420, .adv_w = 411, .box_h = 29, .box_w = 26, .ofs_x = 0, .ofs_y = -5},\n    {.bitmap_index = 14797, .adv_w = 514, .box_h = 29, .box_w = 33, .ofs_x = 0, .ofs_y = -5},\n    {.bitmap_index = 15276, .adv_w = 480, .box_h = 24, .box_w = 30, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 15636, .adv_w = 480, .box_h = 20, .box_w = 26, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 15896, .adv_w = 377, .box_h = 21, .box_w = 21, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 16117, .adv_w = 411, .box_h = 29, .box_w = 26, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 16494, .adv_w = 411, .box_h = 27, .box_w = 26, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 16845, .adv_w = 377, .box_h = 27, .box_w = 24, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 17169, .adv_w = 446, .box_h = 22, .box_w = 28, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 17477, .adv_w = 446, .box_h = 26, .box_w = 28, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 17841, .adv_w = 411, .box_h = 22, .box_w = 26, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 18127, .adv_w = 411, .box_h = 27, .box_w = 26, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 18478, .adv_w = 206, .box_h = 21, .box_w = 13, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 18615, .adv_w = 309, .box_h = 21, .box_w = 20, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 18825, .adv_w = 446, .box_h = 25, .box_w = 28, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 19175, .adv_w = 514, .box_h = 27, .box_w = 33, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 19621, .adv_w = 411, .box_h = 27, .box_w = 26, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 19972, .adv_w = 274, .box_h = 27, .box_w = 18, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 20215, .adv_w = 377, .box_h = 27, .box_w = 24, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 20539, .adv_w = 411, .box_h = 27, .box_w = 26, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 20890, .adv_w = 411, .box_h = 27, .box_w = 26, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 21241, .adv_w = 274, .box_h = 27, .box_w = 18, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 21484, .adv_w = 412, .box_h = 22, .box_w = 26, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 21770, .adv_w = 343, .box_h = 28, .box_w = 18, .ofs_x = 2, .ofs_y = -2},\n    {.bitmap_index = 22022, .adv_w = 343, .box_h = 28, .box_w = 18, .ofs_x = 1, .ofs_y = -2},\n    {.bitmap_index = 22274, .adv_w = 377, .box_h = 24, .box_w = 24, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 22562, .adv_w = 377, .box_h = 7, .box_w = 24, .ofs_x = 0, .ofs_y = 8},\n    {.bitmap_index = 22646, .adv_w = 480, .box_h = 29, .box_w = 30, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 23081, .adv_w = 480, .box_h = 28, .box_w = 30, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 23501, .adv_w = 480, .box_h = 18, .box_w = 28, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 23753, .adv_w = 480, .box_h = 18, .box_w = 28, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 24005, .adv_w = 514, .box_h = 20, .box_w = 32, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 24325, .adv_w = 446, .box_h = 24, .box_w = 28, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 24661, .adv_w = 446, .box_h = 28, .box_w = 28, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 25053, .adv_w = 377, .box_h = 24, .box_w = 24, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 25341, .adv_w = 480, .box_h = 25, .box_w = 30, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 25716, .adv_w = 480, .box_h = 31, .box_w = 30, .ofs_x = 0, .ofs_y = -5},\n    {.bitmap_index = 26181, .adv_w = 411, .box_h = 27, .box_w = 26, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 26532, .adv_w = 240, .box_h = 29, .box_w = 15, .ofs_x = 0, .ofs_y = -5},\n    {.bitmap_index = 26750, .adv_w = 480, .box_h = 31, .box_w = 28, .ofs_x = 1, .ofs_y = -5},\n    {.bitmap_index = 27184, .adv_w = 514, .box_h = 20, .box_w = 33, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 27514, .adv_w = 377, .box_h = 24, .box_w = 24, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 27802, .adv_w = 411, .box_h = 31, .box_w = 26, .ofs_x = 0, .ofs_y = -5},\n    {.bitmap_index = 28205, .adv_w = 549, .box_h = 24, .box_w = 34, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 28613, .adv_w = 617, .box_h = 22, .box_w = 39, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 29042, .adv_w = 617, .box_h = 22, .box_w = 39, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 29471, .adv_w = 617, .box_h = 22, .box_w = 39, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 29900, .adv_w = 617, .box_h = 22, .box_w = 39, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 30329, .adv_w = 617, .box_h = 22, .box_w = 39, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 30758, .adv_w = 411, .box_h = 31, .box_w = 23, .ofs_x = 1, .ofs_y = -5}\n};\n\n/*---------------------\n *  CHARACTER MAPPING\n *--------------------*/\n\nstatic const uint16_t unicode_list_1[] = {\n    0x0, 0x7, 0xa, 0xb, 0xc, 0x10, 0x12, 0x13,\n    0x14, 0x18, 0x1b, 0x20, 0x25, 0x26, 0x27, 0x3d,\n    0x3f, 0x47, 0x4a, 0x4b, 0x4c, 0x50, 0x51, 0x52,\n    0x53, 0x66, 0x67, 0x70, 0x73, 0x76, 0x77, 0x78,\n    0x7a, 0x92, 0x94, 0xc3, 0xc4, 0xc6, 0xe6, 0xf2,\n    0x11b, 0x123, 0x15a, 0x1ea, 0x23f, 0x240, 0x241, 0x242,\n    0x243, 0x292\n};\n\nstatic const lv_font_fmt_txt_cmap_t cmaps[] =\n{\n    {\n        .range_start = 32, .range_length = 95, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY,\n        .glyph_id_start = 1, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0\n    },\n    {\n        .range_start = 61441, .range_length = 659, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY,\n        .glyph_id_start = 96, .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 50\n    }\n};\n\n/*Collect the kern pair's data in one place*/\nstatic const lv_font_fmt_txt_kern_pair_t kern_pairs =\n{\n    .glyph_ids = (const uint8_t *)(ARGON_RES_ADDR + MONTSERRAT_ALT_30_KERN_PAIR_GLYPH),\n    .values = (const int8_t *)(ARGON_RES_ADDR + MONTSERRAT_ALT_30_KERN_PAIR_VALUE),\n    .pair_cnt = 210,\n    .glyph_ids_size = 0\n};\n\n/*--------------------\n *  ALL CUSTOM DATA\n *--------------------*/\n\n/*Store all the custom data of the font*/\nstatic lv_font_fmt_txt_dsc_t font_dsc = {\n    .glyph_bitmap = (const uint8_t *)(ARGON_RES_ADDR + MONTSERRAT_ALT_30_GLYPH_BMP),\n    .glyph_dsc = glyph_dsc,\n    .cmaps = cmaps,\n    .cmap_num = 2,\n    .bpp = 4,\n\n    .kern_scale = 18,\n    .kern_dsc = &kern_pairs,\n    .kern_classes = 0\n};\n\n\n/*-----------------\n *  PUBLIC FONT\n *----------------*/\n\n/*Initialize a public general font descriptor*/\nlv_font_t lv_font_montserrat_alternate_30 = {\n    .dsc = &font_dsc,          /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */\n    .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt,    /*Function pointer to get glyph's bitmap*/\n    .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt,    /*Function pointer to get glyph's data*/\n    .line_height = 34,          /*The maximum line height required by the font*/\n    .base_line = 7,             /*Baseline measured from the bottom of the line*/\n};\n\n#endif"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_font/lv_font_ma_80.c",
    "content": "#include \"libs/lvgl/lvgl.h\"\n#include \"core/argon-resources.h\"\n\n\n#ifndef LV_FONT_MA_80\n#define LV_FONT_MA_80 1\n#endif\n\n#if LV_FONT_MA_80\n\n/*-----------------\n *    BITMAPS\n *----------------*/\nstatic const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {\n    {.bitmap_index = 0, .adv_w = 0, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,\n    {.bitmap_index = 0, .adv_w = 351, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 0, .adv_w = 378, .box_h = 59, .box_w = 12, .ofs_x = 6, .ofs_y = -1},\n    {.bitmap_index = 354, .adv_w = 479, .box_h = 20, .box_w = 18, .ofs_x = 6, .ofs_y = 36},\n    {.bitmap_index = 534, .adv_w = 941, .box_h = 58, .box_w = 53, .ofs_x = 3, .ofs_y = 0},\n    {.bitmap_index = 2071, .adv_w = 792, .box_h = 67, .box_w = 43, .ofs_x = 3, .ofs_y = -6},\n    {.bitmap_index = 3512, .adv_w = 1006, .box_h = 59, .box_w = 57, .ofs_x = 3, .ofs_y = -1},\n    {.bitmap_index = 5194, .adv_w = 888, .box_h = 60, .box_w = 50, .ofs_x = 4, .ofs_y = -2},\n    {.bitmap_index = 6694, .adv_w = 297, .box_h = 20, .box_w = 7, .ofs_x = 6, .ofs_y = 36},\n    {.bitmap_index = 6764, .adv_w = 425, .box_h = 72, .box_w = 20, .ofs_x = 4, .ofs_y = -11},\n    {.bitmap_index = 7484, .adv_w = 425, .box_h = 72, .box_w = 21, .ofs_x = 2, .ofs_y = -11},\n    {.bitmap_index = 8240, .adv_w = 553, .box_h = 26, .box_w = 26, .ofs_x = 4, .ofs_y = 30},\n    {.bitmap_index = 8578, .adv_w = 727, .box_h = 38, .box_w = 39, .ofs_x = 3, .ofs_y = 12},\n    {.bitmap_index = 9319, .adv_w = 360, .box_h = 21, .box_w = 13, .ofs_x = 5, .ofs_y = -9},\n    {.bitmap_index = 9456, .adv_w = 609, .box_h = 10, .box_w = 28, .ofs_x = 5, .ofs_y = 19},\n    {.bitmap_index = 9596, .adv_w = 358, .box_h = 13, .box_w = 13, .ofs_x = 5, .ofs_y = -1},\n    {.bitmap_index = 9681, .adv_w = 751, .box_h = 75, .box_w = 43, .ofs_x = 2, .ofs_y = -10},\n    {.bitmap_index = 11294, .adv_w = 881, .box_h = 51, .box_w = 47, .ofs_x = 4, .ofs_y = -1},\n    {.bitmap_index = 12493, .adv_w = 488, .box_h = 48, .box_w = 21, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 12997, .adv_w = 754, .box_h = 50, .box_w = 39, .ofs_x = 4, .ofs_y = 0},\n    {.bitmap_index = 13972, .adv_w = 740, .box_h = 57, .box_w = 39, .ofs_x = 3, .ofs_y = -9},\n    {.bitmap_index = 15084, .adv_w = 732, .box_h = 56, .box_w = 41, .ofs_x = 2, .ofs_y = -8},\n    {.bitmap_index = 16232, .adv_w = 741, .box_h = 57, .box_w = 39, .ofs_x = 4, .ofs_y = -9},\n    {.bitmap_index = 17344, .adv_w = 794, .box_h = 58, .box_w = 42, .ofs_x = 4, .ofs_y = -1},\n    {.bitmap_index = 18562, .adv_w = 724, .box_h = 56, .box_w = 40, .ofs_x = 3, .ofs_y = -8},\n    {.bitmap_index = 19682, .adv_w = 814, .box_h = 58, .box_w = 43, .ofs_x = 4, .ofs_y = -1},\n    {.bitmap_index = 20929, .adv_w = 792, .box_h = 58, .box_w = 41, .ofs_x = 4, .ofs_y = -9},\n    {.bitmap_index = 22118, .adv_w = 375, .box_h = 32, .box_w = 13, .ofs_x = 5, .ofs_y = -1},\n    {.bitmap_index = 22326, .adv_w = 379, .box_h = 40, .box_w = 13, .ofs_x = 5, .ofs_y = -9},\n    {.bitmap_index = 22586, .adv_w = 758, .box_h = 46, .box_w = 39, .ofs_x = 3, .ofs_y = 9},\n    {.bitmap_index = 23483, .adv_w = 799, .box_h = 24, .box_w = 42, .ofs_x = 4, .ofs_y = 19},\n    {.bitmap_index = 23987, .adv_w = 758, .box_h = 46, .box_w = 38, .ofs_x = 6, .ofs_y = 9},\n    {.bitmap_index = 24861, .adv_w = 650, .box_h = 58, .box_w = 34, .ofs_x = 3, .ofs_y = -1},\n    {.bitmap_index = 25847, .adv_w = 1157, .box_h = 64, .box_w = 65, .ofs_x = 4, .ofs_y = -10},\n    {.bitmap_index = 27927, .adv_w = 982, .box_h = 58, .box_w = 48, .ofs_x = 7, .ofs_y = 0},\n    {.bitmap_index = 29319, .adv_w = 904, .box_h = 56, .box_w = 46, .ofs_x = 7, .ofs_y = 0},\n    {.bitmap_index = 30607, .adv_w = 942, .box_h = 59, .box_w = 52, .ofs_x = 4, .ofs_y = -1},\n    {.bitmap_index = 32141, .adv_w = 1001, .box_h = 56, .box_w = 52, .ofs_x = 7, .ofs_y = 0},\n    {.bitmap_index = 33597, .adv_w = 744, .box_h = 59, .box_w = 40, .ofs_x = 4, .ofs_y = -1},\n    {.bitmap_index = 34777, .adv_w = 745, .box_h = 58, .box_w = 38, .ofs_x = 7, .ofs_y = 0},\n    {.bitmap_index = 35879, .adv_w = 975, .box_h = 59, .box_w = 52, .ofs_x = 4, .ofs_y = -1},\n    {.bitmap_index = 37413, .adv_w = 995, .box_h = 56, .box_w = 48, .ofs_x = 7, .ofs_y = 0},\n    {.bitmap_index = 38757, .adv_w = 620, .box_h = 57, .box_w = 31, .ofs_x = 4, .ofs_y = -1},\n    {.bitmap_index = 39641, .adv_w = 728, .box_h = 66, .box_w = 37, .ofs_x = 1, .ofs_y = -10},\n    {.bitmap_index = 40862, .adv_w = 901, .box_h = 56, .box_w = 48, .ofs_x = 7, .ofs_y = 0},\n    {.bitmap_index = 42206, .adv_w = 724, .box_h = 56, .box_w = 36, .ofs_x = 7, .ofs_y = 0},\n    {.bitmap_index = 43214, .adv_w = 1379, .box_h = 58, .box_w = 72, .ofs_x = 7, .ofs_y = 0},\n    {.bitmap_index = 45302, .adv_w = 996, .box_h = 58, .box_w = 49, .ofs_x = 7, .ofs_y = 0},\n    {.bitmap_index = 46723, .adv_w = 1075, .box_h = 59, .box_w = 59, .ofs_x = 4, .ofs_y = -1},\n    {.bitmap_index = 48464, .adv_w = 876, .box_h = 56, .box_w = 45, .ofs_x = 7, .ofs_y = 0},\n    {.bitmap_index = 49724, .adv_w = 1075, .box_h = 68, .box_w = 59, .ofs_x = 4, .ofs_y = -10},\n    {.bitmap_index = 51730, .adv_w = 932, .box_h = 56, .box_w = 48, .ofs_x = 7, .ofs_y = 0},\n    {.bitmap_index = 53074, .adv_w = 806, .box_h = 59, .box_w = 44, .ofs_x = 3, .ofs_y = -1},\n    {.bitmap_index = 54372, .adv_w = 865, .box_h = 58, .box_w = 52, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 55880, .adv_w = 995, .box_h = 57, .box_w = 48, .ofs_x = 7, .ofs_y = -1},\n    {.bitmap_index = 57248, .adv_w = 896, .box_h = 56, .box_w = 56, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 58816, .adv_w = 1340, .box_h = 57, .box_w = 70, .ofs_x = 7, .ofs_y = -1},\n    {.bitmap_index = 60811, .adv_w = 867, .box_h = 56, .box_w = 52, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 62267, .adv_w = 927, .box_h = 66, .box_w = 46, .ofs_x = 5, .ofs_y = -10},\n    {.bitmap_index = 63785, .adv_w = 864, .box_h = 56, .box_w = 47, .ofs_x = 3, .ofs_y = 0},\n    {.bitmap_index = 65101, .adv_w = 454, .box_h = 73, .box_w = 19, .ofs_x = 7, .ofs_y = -12},\n    {.bitmap_index = 65795, .adv_w = 668, .box_h = 61, .box_w = 38, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 66954, .adv_w = 454, .box_h = 73, .box_w = 19, .ofs_x = 3, .ofs_y = -12},\n    {.bitmap_index = 67648, .adv_w = 504, .box_h = 13, .box_w = 29, .ofs_x = 1, .ofs_y = 59},\n    {.bitmap_index = 67837, .adv_w = 924, .box_h = 5, .box_w = 47, .ofs_x = 5, .ofs_y = -11},\n    {.bitmap_index = 67955, .adv_w = 1066, .box_h = 12, .box_w = 19, .ofs_x = 25, .ofs_y = 48},\n    {.bitmap_index = 68069, .adv_w = 860, .box_h = 45, .box_w = 45, .ofs_x = 3, .ofs_y = -1},\n    {.bitmap_index = 69082, .adv_w = 860, .box_h = 61, .box_w = 44, .ofs_x = 6, .ofs_y = -1},\n    {.bitmap_index = 70424, .adv_w = 737, .box_h = 45, .box_w = 41, .ofs_x = 3, .ofs_y = -1},\n    {.bitmap_index = 71347, .adv_w = 860, .box_h = 61, .box_w = 45, .ofs_x = 3, .ofs_y = -1},\n    {.bitmap_index = 72720, .adv_w = 783, .box_h = 45, .box_w = 44, .ofs_x = 3, .ofs_y = -1},\n    {.bitmap_index = 73710, .adv_w = 474, .box_h = 58, .box_w = 28, .ofs_x = 6, .ofs_y = 0},\n    {.bitmap_index = 74522, .adv_w = 837, .box_h = 61, .box_w = 43, .ofs_x = 3, .ofs_y = -17},\n    {.bitmap_index = 75834, .adv_w = 827, .box_h = 60, .box_w = 40, .ofs_x = 6, .ofs_y = 0},\n    {.bitmap_index = 77034, .adv_w = 351, .box_h = 61, .box_w = 12, .ofs_x = 5, .ofs_y = 0},\n    {.bitmap_index = 77400, .adv_w = 351, .box_h = 78, .box_w = 26, .ofs_x = -9, .ofs_y = -17},\n    {.bitmap_index = 78414, .adv_w = 744, .box_h = 60, .box_w = 40, .ofs_x = 6, .ofs_y = 0},\n    {.bitmap_index = 79614, .adv_w = 440, .box_h = 57, .box_w = 22, .ofs_x = 6, .ofs_y = -1},\n    {.bitmap_index = 80241, .adv_w = 1298, .box_h = 44, .box_w = 70, .ofs_x = 6, .ofs_y = 0},\n    {.bitmap_index = 81781, .adv_w = 827, .box_h = 44, .box_w = 40, .ofs_x = 6, .ofs_y = 0},\n    {.bitmap_index = 82661, .adv_w = 835, .box_h = 45, .box_w = 46, .ofs_x = 3, .ofs_y = -1},\n    {.bitmap_index = 83696, .adv_w = 860, .box_h = 60, .box_w = 44, .ofs_x = 6, .ofs_y = -16},\n    {.bitmap_index = 85016, .adv_w = 860, .box_h = 60, .box_w = 45, .ofs_x = 3, .ofs_y = -16},\n    {.bitmap_index = 86366, .adv_w = 508, .box_h = 44, .box_w = 24, .ofs_x = 6, .ofs_y = 0},\n    {.bitmap_index = 86894, .adv_w = 648, .box_h = 45, .box_w = 35, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 87682, .adv_w = 495, .box_h = 57, .box_w = 25, .ofs_x = 6, .ofs_y = -1},\n    {.bitmap_index = 88395, .adv_w = 827, .box_h = 44, .box_w = 40, .ofs_x = 6, .ofs_y = -1},\n    {.bitmap_index = 89275, .adv_w = 732, .box_h = 43, .box_w = 45, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 90243, .adv_w = 1167, .box_h = 43, .box_w = 71, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 91770, .adv_w = 714, .box_h = 43, .box_w = 42, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 92673, .adv_w = 826, .box_h = 60, .box_w = 41, .ofs_x = 4, .ofs_y = -17},\n    {.bitmap_index = 93903, .adv_w = 691, .box_h = 43, .box_w = 37, .ofs_x = 3, .ofs_y = 0},\n    {.bitmap_index = 94699, .adv_w = 430, .box_h = 73, .box_w = 20, .ofs_x = 3, .ofs_y = -12},\n    {.bitmap_index = 95429, .adv_w = 329, .box_h = 76, .box_w = 8, .ofs_x = 6, .ofs_y = -13},\n    {.bitmap_index = 95733, .adv_w = 430, .box_h = 73, .box_w = 20, .ofs_x = 4, .ofs_y = -12},\n    {.bitmap_index = 96463, .adv_w = 737, .box_h = 17, .box_w = 40, .ofs_x = 3, .ofs_y = 22},\n    {.bitmap_index = 96803, .adv_w = 1097, .box_h = 75, .box_w = 69, .ofs_x = 0, .ofs_y = -12},\n    {.bitmap_index = 99391, .adv_w = 1371, .box_h = 75, .box_w = 86, .ofs_x = 0, .ofs_y = -12},\n    {.bitmap_index = 102616, .adv_w = 1280, .box_h = 63, .box_w = 80, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 105136, .adv_w = 1280, .box_h = 54, .box_w = 70, .ofs_x = 5, .ofs_y = 0},\n    {.bitmap_index = 107026, .adv_w = 1006, .box_h = 54, .box_w = 54, .ofs_x = 4, .ofs_y = -1},\n    {.bitmap_index = 108484, .adv_w = 1097, .box_h = 75, .box_w = 69, .ofs_x = 0, .ofs_y = -6},\n    {.bitmap_index = 111072, .adv_w = 1097, .box_h = 69, .box_w = 69, .ofs_x = 0, .ofs_y = -6},\n    {.bitmap_index = 113453, .adv_w = 1006, .box_h = 69, .box_w = 63, .ofs_x = 0, .ofs_y = -6},\n    {.bitmap_index = 115627, .adv_w = 1189, .box_h = 58, .box_w = 72, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 117715, .adv_w = 1189, .box_h = 69, .box_w = 75, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 120303, .adv_w = 1097, .box_h = 58, .box_w = 69, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 122304, .adv_w = 1097, .box_h = 69, .box_w = 69, .ofs_x = 0, .ofs_y = -6},\n    {.bitmap_index = 124685, .adv_w = 549, .box_h = 55, .box_w = 35, .ofs_x = 0, .ofs_y = 1},\n    {.bitmap_index = 125648, .adv_w = 823, .box_h = 55, .box_w = 52, .ofs_x = 0, .ofs_y = 1},\n    {.bitmap_index = 127078, .adv_w = 1189, .box_h = 65, .box_w = 75, .ofs_x = 0, .ofs_y = -4},\n    {.bitmap_index = 129516, .adv_w = 1371, .box_h = 69, .box_w = 86, .ofs_x = 0, .ofs_y = -6},\n    {.bitmap_index = 132483, .adv_w = 1097, .box_h = 68, .box_w = 68, .ofs_x = 0, .ofs_y = -6},\n    {.bitmap_index = 134795, .adv_w = 731, .box_h = 69, .box_w = 46, .ofs_x = 0, .ofs_y = -6},\n    {.bitmap_index = 136382, .adv_w = 1006, .box_h = 70, .box_w = 63, .ofs_x = 0, .ofs_y = -6},\n    {.bitmap_index = 138587, .adv_w = 1097, .box_h = 69, .box_w = 69, .ofs_x = 0, .ofs_y = -6},\n    {.bitmap_index = 140968, .adv_w = 1097, .box_h = 69, .box_w = 69, .ofs_x = 0, .ofs_y = -6},\n    {.bitmap_index = 143349, .adv_w = 731, .box_h = 69, .box_w = 46, .ofs_x = 0, .ofs_y = -6},\n    {.bitmap_index = 144936, .adv_w = 1099, .box_h = 58, .box_w = 69, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 146937, .adv_w = 914, .box_h = 73, .box_w = 48, .ofs_x = 6, .ofs_y = -5},\n    {.bitmap_index = 148689, .adv_w = 914, .box_h = 73, .box_w = 47, .ofs_x = 4, .ofs_y = -5},\n    {.bitmap_index = 150405, .adv_w = 1006, .box_h = 63, .box_w = 63, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 152390, .adv_w = 1006, .box_h = 18, .box_w = 63, .ofs_x = 0, .ofs_y = 22},\n    {.bitmap_index = 152957, .adv_w = 1280, .box_h = 75, .box_w = 80, .ofs_x = 0, .ofs_y = -6},\n    {.bitmap_index = 155957, .adv_w = 1280, .box_h = 72, .box_w = 80, .ofs_x = 0, .ofs_y = -5},\n    {.bitmap_index = 158837, .adv_w = 1280, .box_h = 47, .box_w = 72, .ofs_x = 4, .ofs_y = 1},\n    {.bitmap_index = 160529, .adv_w = 1280, .box_h = 47, .box_w = 72, .ofs_x = 4, .ofs_y = -2},\n    {.bitmap_index = 162221, .adv_w = 1371, .box_h = 52, .box_w = 86, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 164457, .adv_w = 1189, .box_h = 63, .box_w = 75, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 166820, .adv_w = 1189, .box_h = 72, .box_w = 75, .ofs_x = 0, .ofs_y = -6},\n    {.bitmap_index = 169520, .adv_w = 1006, .box_h = 63, .box_w = 63, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 171505, .adv_w = 1280, .box_h = 64, .box_w = 80, .ofs_x = 0, .ofs_y = -6},\n    {.bitmap_index = 174065, .adv_w = 1280, .box_h = 81, .box_w = 80, .ofs_x = 0, .ofs_y = -12},\n    {.bitmap_index = 177305, .adv_w = 1097, .box_h = 69, .box_w = 69, .ofs_x = 0, .ofs_y = -6},\n    {.bitmap_index = 179686, .adv_w = 640, .box_h = 75, .box_w = 40, .ofs_x = 0, .ofs_y = -12},\n    {.bitmap_index = 181186, .adv_w = 1280, .box_h = 81, .box_w = 74, .ofs_x = 3, .ofs_y = -12},\n    {.bitmap_index = 184183, .adv_w = 1371, .box_h = 52, .box_w = 86, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 186419, .adv_w = 1006, .box_h = 64, .box_w = 63, .ofs_x = 0, .ofs_y = -6},\n    {.bitmap_index = 188435, .adv_w = 1097, .box_h = 81, .box_w = 69, .ofs_x = 0, .ofs_y = -12},\n    {.bitmap_index = 191230, .adv_w = 1463, .box_h = 63, .box_w = 88, .ofs_x = 2, .ofs_y = 0},\n    {.bitmap_index = 194002, .adv_w = 1646, .box_h = 58, .box_w = 103, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 196989, .adv_w = 1646, .box_h = 58, .box_w = 103, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 199976, .adv_w = 1646, .box_h = 58, .box_w = 103, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 202963, .adv_w = 1646, .box_h = 58, .box_w = 103, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 205950, .adv_w = 1646, .box_h = 58, .box_w = 103, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 208937, .adv_w = 1097, .box_h = 81, .box_w = 60, .ofs_x = 4, .ofs_y = -12}\n};\n\n/*---------------------\n *  CHARACTER MAPPING\n *--------------------*/\n\nstatic const uint16_t unicode_list_1[] = {\n    0x0, 0x7, 0xa, 0xb, 0xc, 0x10, 0x12, 0x13,\n    0x14, 0x18, 0x1b, 0x20, 0x25, 0x26, 0x27, 0x3d,\n    0x3f, 0x47, 0x4a, 0x4b, 0x4c, 0x50, 0x51, 0x52,\n    0x53, 0x66, 0x67, 0x70, 0x73, 0x76, 0x77, 0x78,\n    0x7a, 0x92, 0x94, 0xc3, 0xc4, 0xc6, 0xe6, 0xf2,\n    0x11b, 0x123, 0x15a, 0x1ea, 0x23f, 0x240, 0x241, 0x242,\n    0x243, 0x292\n};\n\n/*Collect the unicode lists and glyph_id offsets*/\nstatic const lv_font_fmt_txt_cmap_t cmaps[] =\n{\n    {\n        .range_start = 32, .range_length = 95, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY,\n        .glyph_id_start = 1, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0\n    },\n    {\n        .range_start = 61441, .range_length = 659, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY,\n        .glyph_id_start = 96, .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 50\n    }\n};\n\n/*Collect the kern pair's data in one place*/\nstatic const lv_font_fmt_txt_kern_pair_t kern_pairs =\n{\n    .glyph_ids = (const uint8_t *)(ARGON_RES_ADDR + MONTSERRAT_ALT_80_KERN_PAIR_GLYPH),\n    .values = (const int8_t *)(ARGON_RES_ADDR + MONTSERRAT_ALT_80_KERN_PAIR_VALUE),\n    .pair_cnt = 210,\n    .glyph_ids_size = 0\n};\n\n/*--------------------\n *  ALL CUSTOM DATA\n *--------------------*/\n\n/*Store all the custom data of the font*/\nstatic lv_font_fmt_txt_dsc_t font_dsc = {\n    .glyph_bitmap = (const uint8_t *)(ARGON_RES_ADDR + MONTSERRAT_ALT_80_GLYPH_BMP),\n    .glyph_dsc = glyph_dsc,\n    .cmaps = cmaps,\n    .cmap_num = 2,\n    .bpp = 4,\n\n    .kern_scale = 48,\n    .kern_dsc = &kern_pairs,\n    .kern_classes = 0\n};\n\n\n/*-----------------\n *  PUBLIC FONT\n *----------------*/\n\n/*Initialize a public general font descriptor*/\nlv_font_t lv_font_montserrat_alternate_80 = {\n    .dsc = &font_dsc,          /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */\n    .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt,    /*Function pointer to get glyph's bitmap*/\n    .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt,    /*Function pointer to get glyph's data*/\n    .line_height = 89,          /*The maximum line height required by the font*/\n    .base_line = 17,             /*Baseline measured from the bottom of the line*/\n};\n\n#endif /*#if MONTSERRAT_ALTERNATE_80*/\n\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_font/lv_font_montserrat_12.c",
    "content": "#include \"libs/lvgl/lvgl.h\"\n#include \"core/argon-resources.h\"\n\n/*******************************************************************************\n * Size: 22 px\n * Bpp: 4\n * Opts:\n ******************************************************************************/\n\n#ifndef LV_FONT_MONTSERRAT_12\n#define LV_FONT_MONTSERRAT_12 1\n#endif\n\n#if LV_FONT_MONTSERRAT_12\n\n/*-----------------\n *    BITMAPS\n *----------------*/\nstatic const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {\n    {.bitmap_index = 0, .adv_w = 0, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,\n    {.bitmap_index = 0, .adv_w = 53, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 0, .adv_w = 57, .box_h = 9, .box_w = 2, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 9, .adv_w = 72, .box_h = 4, .box_w = 3, .ofs_x = 1, .ofs_y = 5},\n    {.bitmap_index = 15, .adv_w = 141, .box_h = 9, .box_w = 9, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 56, .adv_w = 119, .box_h = 10, .box_w = 7, .ofs_x = 0, .ofs_y = -1},\n    {.bitmap_index = 91, .adv_w = 151, .box_h = 9, .box_w = 9, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 132, .adv_w = 133, .box_h = 10, .box_w = 8, .ofs_x = 0, .ofs_y = -1},\n    {.bitmap_index = 172, .adv_w = 45, .box_h = 4, .box_w = 2, .ofs_x = 0, .ofs_y = 5},\n    {.bitmap_index = 176, .adv_w = 64, .box_h = 11, .box_w = 4, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 198, .adv_w = 64, .box_h = 11, .box_w = 4, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 220, .adv_w = 83, .box_h = 5, .box_w = 5, .ofs_x = 0, .ofs_y = 4},\n    {.bitmap_index = 233, .adv_w = 109, .box_h = 7, .box_w = 7, .ofs_x = 0, .ofs_y = 1},\n    {.bitmap_index = 258, .adv_w = 54, .box_h = 4, .box_w = 3, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 264, .adv_w = 91, .box_h = 3, .box_w = 5, .ofs_x = 0, .ofs_y = 2},\n    {.bitmap_index = 272, .adv_w = 54, .box_h = 2, .box_w = 3, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 275, .adv_w = 113, .box_h = 12, .box_w = 7, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 317, .adv_w = 132, .box_h = 9, .box_w = 8, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 353, .adv_w = 73, .box_h = 9, .box_w = 4, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 371, .adv_w = 113, .box_h = 9, .box_w = 7, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 403, .adv_w = 111, .box_h = 9, .box_w = 7, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 435, .adv_w = 110, .box_h = 9, .box_w = 7, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 467, .adv_w = 111, .box_h = 9, .box_w = 7, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 499, .adv_w = 119, .box_h = 9, .box_w = 7, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 531, .adv_w = 109, .box_h = 9, .box_w = 7, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 563, .adv_w = 122, .box_h = 9, .box_w = 7, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 595, .adv_w = 119, .box_h = 9, .box_w = 7, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 627, .adv_w = 56, .box_h = 5, .box_w = 3, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 635, .adv_w = 57, .box_h = 7, .box_w = 2, .ofs_x = 1, .ofs_y = -2},\n    {.bitmap_index = 642, .adv_w = 114, .box_h = 7, .box_w = 7, .ofs_x = 0, .ofs_y = 1},\n    {.bitmap_index = 667, .adv_w = 120, .box_h = 4, .box_w = 7, .ofs_x = 0, .ofs_y = 3},\n    {.bitmap_index = 681, .adv_w = 114, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = 1},\n    {.bitmap_index = 702, .adv_w = 98, .box_h = 9, .box_w = 6, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 729, .adv_w = 174, .box_h = 10, .box_w = 11, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 784, .adv_w = 142, .box_h = 9, .box_w = 9, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 825, .adv_w = 136, .box_h = 9, .box_w = 7, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 857, .adv_w = 141, .box_h = 9, .box_w = 9, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 898, .adv_w = 150, .box_h = 9, .box_w = 8, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 934, .adv_w = 126, .box_h = 9, .box_w = 7, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 966, .adv_w = 116, .box_h = 9, .box_w = 6, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 993, .adv_w = 145, .box_h = 9, .box_w = 9, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1034, .adv_w = 149, .box_h = 9, .box_w = 8, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 1070, .adv_w = 60, .box_h = 9, .box_w = 2, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 1079, .adv_w = 106, .box_h = 9, .box_w = 6, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1106, .adv_w = 135, .box_h = 9, .box_w = 8, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 1142, .adv_w = 109, .box_h = 9, .box_w = 6, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 1169, .adv_w = 189, .box_h = 9, .box_w = 10, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 1214, .adv_w = 161, .box_h = 9, .box_w = 8, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 1250, .adv_w = 161, .box_h = 9, .box_w = 10, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1295, .adv_w = 131, .box_h = 9, .box_w = 7, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 1327, .adv_w = 161, .box_h = 11, .box_w = 10, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 1382, .adv_w = 140, .box_h = 9, .box_w = 8, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 1418, .adv_w = 121, .box_h = 9, .box_w = 7, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1450, .adv_w = 116, .box_h = 9, .box_w = 7, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1482, .adv_w = 147, .box_h = 9, .box_w = 8, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 1518, .adv_w = 134, .box_h = 9, .box_w = 9, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1559, .adv_w = 201, .box_h = 9, .box_w = 13, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1618, .adv_w = 129, .box_h = 9, .box_w = 8, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1654, .adv_w = 120, .box_h = 9, .box_w = 8, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1690, .adv_w = 130, .box_h = 9, .box_w = 8, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1726, .adv_w = 68, .box_h = 11, .box_w = 3, .ofs_x = 1, .ofs_y = -2},\n    {.bitmap_index = 1743, .adv_w = 100, .box_h = 9, .box_w = 6, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1770, .adv_w = 68, .box_h = 11, .box_w = 4, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 1792, .adv_w = 76, .box_h = 2, .box_w = 5, .ofs_x = 0, .ofs_y = 9},\n    {.bitmap_index = 1797, .adv_w = 139, .box_h = 1, .box_w = 8, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 1801, .adv_w = 160, .box_h = 2, .box_w = 4, .ofs_x = 3, .ofs_y = 7},\n    {.bitmap_index = 1805, .adv_w = 113, .box_h = 7, .box_w = 7, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1830, .adv_w = 129, .box_h = 9, .box_w = 7, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 1862, .adv_w = 111, .box_h = 7, .box_w = 7, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1887, .adv_w = 129, .box_h = 9, .box_w = 7, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1919, .adv_w = 119, .box_h = 7, .box_w = 7, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1944, .adv_w = 74, .box_h = 9, .box_w = 5, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 1967, .adv_w = 126, .box_h = 10, .box_w = 7, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 2002, .adv_w = 124, .box_h = 9, .box_w = 6, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 2029, .adv_w = 53, .box_h = 9, .box_w = 3, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 2043, .adv_w = 53, .box_h = 12, .box_w = 5, .ofs_x = -2, .ofs_y = -3},\n    {.bitmap_index = 2073, .adv_w = 112, .box_h = 9, .box_w = 6, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 2100, .adv_w = 53, .box_h = 9, .box_w = 2, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 2109, .adv_w = 195, .box_h = 7, .box_w = 11, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 2148, .adv_w = 124, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 2169, .adv_w = 125, .box_h = 7, .box_w = 8, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 2197, .adv_w = 129, .box_h = 10, .box_w = 7, .ofs_x = 1, .ofs_y = -3},\n    {.bitmap_index = 2232, .adv_w = 129, .box_h = 10, .box_w = 7, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 2267, .adv_w = 76, .box_h = 7, .box_w = 4, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 2281, .adv_w = 97, .box_h = 7, .box_w = 6, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 2302, .adv_w = 80, .box_h = 9, .box_w = 5, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 2325, .adv_w = 124, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 2346, .adv_w = 110, .box_h = 7, .box_w = 7, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 2371, .adv_w = 175, .box_h = 7, .box_w = 11, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 2410, .adv_w = 107, .box_h = 7, .box_w = 7, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 2435, .adv_w = 110, .box_h = 10, .box_w = 7, .ofs_x = 0, .ofs_y = -3},\n    {.bitmap_index = 2470, .adv_w = 104, .box_h = 7, .box_w = 6, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 2491, .adv_w = 65, .box_h = 11, .box_w = 4, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 2513, .adv_w = 49, .box_h = 12, .box_w = 2, .ofs_x = 1, .ofs_y = -2},\n    {.bitmap_index = 2525, .adv_w = 65, .box_h = 11, .box_w = 4, .ofs_x = 0, .ofs_y = -2},\n    {.bitmap_index = 2547, .adv_w = 108, .box_h = 3, .box_w = 7, .ofs_x = 0, .ofs_y = 3}\n};\n\n/*Collect the unicode lists and glyph_id offsets*/\nstatic const lv_font_fmt_txt_cmap_t cmaps[] =\n{\n    {\n        .range_start = 32, \n        .range_length = 95, \n        .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY,\n        .glyph_id_start = 1, \n        .unicode_list = NULL, \n        .glyph_id_ofs_list = NULL, \n        .list_length = 0\n    }\n};\n\n/*-----------------\n *    KERNING\n *----------------*/\n\nstatic const lv_font_fmt_txt_kern_pair_t kern_pairs =\n{\n    .glyph_ids = (const uint8_t *)(ARGON_RES_ADDR + MONTSERRAT_12_KERN_PAIR_GLYPH),\n    .values = (const int8_t *)(ARGON_RES_ADDR + MONTSERRAT_12_KERN_PAIR_VALUE),\n    .pair_cnt = 764,\n    .glyph_ids_size = 0\n};\n\n/*--------------------\n *  ALL CUSTOM DATA\n *--------------------*/\n\n/*Store all the custom data of the font*/\nstatic lv_font_fmt_txt_dsc_t font_dsc = {\n    .glyph_bitmap = (const uint8_t *)(ARGON_RES_ADDR + MONTSERRAT_12_GLYPH_BMP),\n    .glyph_dsc = glyph_dsc,\n    .cmaps = cmaps,\n    .cmap_num = 1,\n    .bpp = 4,\n\n    .kern_scale = 16,\n    .kern_dsc = &kern_pairs,\n    .kern_classes = 0\n};\n\n\n/*-----------------\n *  PUBLIC FONT\n *----------------*/\n\n/*Initialize a public general font descriptor*/\nlv_font_t lv_font_montserrat_12 = {\n    .dsc = &font_dsc,          /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */\n    .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt,    /*Function pointer to get glyph's bitmap*/\n    .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt,    /*Function pointer to get glyph's data*/\n    .line_height = 14,          /*The maximum line height required by the font*/\n    .base_line = 3,             /*Baseline measured from the bottom of the line*/\n};\n\n\n#endif /*#if LV_FONT_MONTSERRAT_12*/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_font/lv_font_unscii_8.c",
    "content": "#include \"libs/lvgl/lvgl.h\"\n\n/*******************************************************************************\n * Size: 8 px\n * Bpp: 1\n * Opts: \n ******************************************************************************/\n\n#ifndef LV_FONT_UNSCII_8\n#define LV_FONT_UNSCII_8 1\n#endif\n\n#if LV_FONT_UNSCII_8\n\n/*-----------------\n *    BITMAPS\n *----------------*/\n\n/*Store the image of the glyphs*/\nstatic LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = {\n    /* U+20 \" \" */\n\n    /* U+21 \"!\" */\n    0xf2,\n\n    /* U+22 \"\\\"\" */\n    0x99, 0x90,\n\n    /* U+23 \"#\" */\n    0x49, 0x2f, 0xd2, 0xfd, 0x24, 0x80,\n\n    /* U+24 \"$\" */\n    0x23, 0xe8, 0xe2, 0xf8, 0x80,\n\n    /* U+25 \"%\" */\n    0xc7, 0x21, 0x8, 0x4e, 0x30,\n\n    /* U+26 \"&\" */\n    0x62, 0x49, 0x18, 0x96, 0x27, 0x40,\n\n    /* U+27 \"'\" */\n    0x2a, 0x0,\n\n    /* U+28 \"(\" */\n    0x2a, 0x48, 0x88,\n\n    /* U+29 \")\" */\n    0x88, 0x92, 0xa0,\n\n    /* U+2A \"*\" */\n    0x25, 0x5c, 0x47, 0x54, 0x80,\n\n    /* U+2B \"+\" */\n    0x21, 0x3e, 0x42, 0x0,\n\n    /* U+2C \",\" */\n    0x58,\n\n    /* U+2D \"-\" */\n    0xf8,\n\n    /* U+2E \".\" */\n    0x80,\n\n    /* U+2F \"/\" */\n    0x2, 0x8, 0x20, 0x82, 0x8, 0x20, 0x0,\n\n    /* U+30 \"0\" */\n    0x74, 0x67, 0x5c, 0xc5, 0xc0,\n\n    /* U+31 \"1\" */\n    0x23, 0x28, 0x42, 0x13, 0xe0,\n\n    /* U+32 \"2\" */\n    0x74, 0x42, 0x26, 0x43, 0xe0,\n\n    /* U+33 \"3\" */\n    0x74, 0x42, 0x60, 0xc5, 0xc0,\n\n    /* U+34 \"4\" */\n    0x11, 0x95, 0x2f, 0x88, 0x40,\n\n    /* U+35 \"5\" */\n    0xfc, 0x3c, 0x10, 0xc5, 0xc0,\n\n    /* U+36 \"6\" */\n    0x3a, 0x21, 0xe8, 0xc5, 0xc0,\n\n    /* U+37 \"7\" */\n    0xf8, 0x44, 0x44, 0x21, 0x0,\n\n    /* U+38 \"8\" */\n    0x74, 0x62, 0xe8, 0xc5, 0xc0,\n\n    /* U+39 \"9\" */\n    0x74, 0x62, 0xf0, 0x8b, 0x80,\n\n    /* U+3A \":\" */\n    0x90,\n\n    /* U+3B \";\" */\n    0x41, 0x60,\n\n    /* U+3C \"<\" */\n    0x12, 0x48, 0x42, 0x10,\n\n    /* U+3D \"=\" */\n    0xf8, 0x3e,\n\n    /* U+3E \">\" */\n    0x84, 0x21, 0x24, 0x80,\n\n    /* U+3F \"?\" */\n    0x7a, 0x10, 0x84, 0x10, 0x1, 0x0,\n\n    /* U+40 \"@\" */\n    0x7a, 0x19, 0x6b, 0x9a, 0x7, 0x80,\n\n    /* U+41 \"A\" */\n    0x31, 0x28, 0x7f, 0x86, 0x18, 0x40,\n\n    /* U+42 \"B\" */\n    0xfa, 0x18, 0x7e, 0x86, 0x1f, 0x80,\n\n    /* U+43 \"C\" */\n    0x7a, 0x18, 0x20, 0x82, 0x17, 0x80,\n\n    /* U+44 \"D\" */\n    0xf2, 0x28, 0x61, 0x86, 0x2f, 0x0,\n\n    /* U+45 \"E\" */\n    0xfe, 0x8, 0x3c, 0x82, 0xf, 0xc0,\n\n    /* U+46 \"F\" */\n    0xfe, 0x8, 0x3c, 0x82, 0x8, 0x0,\n\n    /* U+47 \"G\" */\n    0x7a, 0x18, 0x27, 0x86, 0x17, 0x80,\n\n    /* U+48 \"H\" */\n    0x86, 0x18, 0x7f, 0x86, 0x18, 0x40,\n\n    /* U+49 \"I\" */\n    0xe9, 0x24, 0xb8,\n\n    /* U+4A \"J\" */\n    0x8, 0x42, 0x10, 0xc5, 0xc0,\n\n    /* U+4B \"K\" */\n    0x86, 0x29, 0x38, 0x92, 0x28, 0x40,\n\n    /* U+4C \"L\" */\n    0x82, 0x8, 0x20, 0x82, 0xf, 0xc0,\n\n    /* U+4D \"M\" */\n    0x87, 0x3b, 0x61, 0x86, 0x18, 0x40,\n\n    /* U+4E \"N\" */\n    0x87, 0x1a, 0x65, 0x8e, 0x18, 0x40,\n\n    /* U+4F \"O\" */\n    0x7a, 0x18, 0x61, 0x86, 0x17, 0x80,\n\n    /* U+50 \"P\" */\n    0xfa, 0x18, 0x7e, 0x82, 0x8, 0x0,\n\n    /* U+51 \"Q\" */\n    0x7a, 0x18, 0x61, 0x96, 0x27, 0x40,\n\n    /* U+52 \"R\" */\n    0xfa, 0x18, 0x7e, 0x92, 0x28, 0x40,\n\n    /* U+53 \"S\" */\n    0x7a, 0x18, 0x1e, 0x6, 0x17, 0x80,\n\n    /* U+54 \"T\" */\n    0xf9, 0x8, 0x42, 0x10, 0x80,\n\n    /* U+55 \"U\" */\n    0x86, 0x18, 0x61, 0x86, 0x17, 0x80,\n\n    /* U+56 \"V\" */\n    0x86, 0x18, 0x61, 0x85, 0x23, 0x0,\n\n    /* U+57 \"W\" */\n    0x86, 0x18, 0x61, 0xb7, 0x38, 0x40,\n\n    /* U+58 \"X\" */\n    0x86, 0x14, 0x8c, 0x4a, 0x18, 0x40,\n\n    /* U+59 \"Y\" */\n    0x8c, 0x62, 0xe2, 0x10, 0x80,\n\n    /* U+5A \"Z\" */\n    0xf8, 0x44, 0x44, 0x43, 0xe0,\n\n    /* U+5B \"[\" */\n    0xf2, 0x49, 0x38,\n\n    /* U+5C \"\\\\\" */\n    0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,\n\n    /* U+5D \"]\" */\n    0xe4, 0x92, 0x78,\n\n    /* U+5E \"^\" */\n    0x22, 0xa2,\n\n    /* U+5F \"_\" */\n    0xf8,\n\n    /* U+60 \"`\" */\n    0x88, 0x80,\n\n    /* U+61 \"a\" */\n    0x70, 0x5f, 0x17, 0x80,\n\n    /* U+62 \"b\" */\n    0x84, 0x3d, 0x18, 0xc7, 0xc0,\n\n    /* U+63 \"c\" */\n    0x74, 0x61, 0x17, 0x0,\n\n    /* U+64 \"d\" */\n    0x8, 0x5f, 0x18, 0xc5, 0xe0,\n\n    /* U+65 \"e\" */\n    0x74, 0x7f, 0x7, 0x0,\n\n    /* U+66 \"f\" */\n    0x18, 0x92, 0x3e, 0x20, 0x82, 0x0,\n\n    /* U+67 \"g\" */\n    0x7c, 0x62, 0xf0, 0xb8,\n\n    /* U+68 \"h\" */\n    0x84, 0x3d, 0x18, 0xc6, 0x20,\n\n    /* U+69 \"i\" */\n    0x43, 0x24, 0xb8,\n\n    /* U+6A \"j\" */\n    0x10, 0x31, 0x11, 0x96,\n\n    /* U+6B \"k\" */\n    0x84, 0x23, 0x2e, 0x4a, 0x20,\n\n    /* U+6C \"l\" */\n    0xc9, 0x24, 0xb8,\n\n    /* U+6D \"m\" */\n    0xd5, 0x6b, 0x5a, 0x80,\n\n    /* U+6E \"n\" */\n    0xf4, 0x63, 0x18, 0x80,\n\n    /* U+6F \"o\" */\n    0x74, 0x63, 0x17, 0x0,\n\n    /* U+70 \"p\" */\n    0xf4, 0x63, 0xe8, 0x40,\n\n    /* U+71 \"q\" */\n    0x7c, 0x62, 0xf0, 0x84,\n\n    /* U+72 \"r\" */\n    0xbe, 0x21, 0x8, 0x0,\n\n    /* U+73 \"s\" */\n    0x7c, 0x1c, 0x1f, 0x0,\n\n    /* U+74 \"t\" */\n    0x42, 0x3c, 0x84, 0x24, 0xc0,\n\n    /* U+75 \"u\" */\n    0x8c, 0x63, 0x17, 0x0,\n\n    /* U+76 \"v\" */\n    0x8c, 0x62, 0xa2, 0x0,\n\n    /* U+77 \"w\" */\n    0x8d, 0x6b, 0x55, 0x0,\n\n    /* U+78 \"x\" */\n    0x8a, 0x88, 0xa8, 0x80,\n\n    /* U+79 \"y\" */\n    0x8c, 0x62, 0xf0, 0xb8,\n\n    /* U+7A \"z\" */\n    0xf8, 0x88, 0x8f, 0x80,\n\n    /* U+7B \"{\" */\n    0x34, 0x48, 0x44, 0x30,\n\n    /* U+7C \"|\" */\n    0xff,\n\n    /* U+7D \"}\" */\n    0xc2, 0x21, 0x22, 0xc0,\n\n    /* U+7E \"~\" */\n    0x45, 0x44,\n\n    /* U+7F \"\" */\n    0xc1, 0x42, 0xbd, 0x2c, 0x40, 0x81, 0x0\n};\n\n\n/*---------------------\n *  GLYPH DESCRIPTION\n *--------------------*/\n\nstatic  lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {\n    {.bitmap_index = 0, .adv_w = 0, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,\n    {.bitmap_index = 0, .adv_w = 128, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0},\n    {.bitmap_index = 0, .adv_w = 128, .box_h = 7, .box_w = 1, .ofs_x = 3, .ofs_y = -1},\n    {.bitmap_index = 1, .adv_w = 128, .box_h = 3, .box_w = 4, .ofs_x = 2, .ofs_y = 3},\n    {.bitmap_index = 3, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 9, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 14, .adv_w = 128, .box_h = 6, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 19, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 25, .adv_w = 128, .box_h = 3, .box_w = 3, .ofs_x = 2, .ofs_y = 3},\n    {.bitmap_index = 27, .adv_w = 128, .box_h = 7, .box_w = 3, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 30, .adv_w = 128, .box_h = 7, .box_w = 3, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 33, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 38, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = 0},\n    {.bitmap_index = 42, .adv_w = 128, .box_h = 3, .box_w = 2, .ofs_x = 3, .ofs_y = -2},\n    {.bitmap_index = 43, .adv_w = 128, .box_h = 1, .box_w = 5, .ofs_x = 1, .ofs_y = 1},\n    {.bitmap_index = 44, .adv_w = 128, .box_h = 1, .box_w = 1, .ofs_x = 3, .ofs_y = -1},\n    {.bitmap_index = 45, .adv_w = 128, .box_h = 7, .box_w = 7, .ofs_x = 0, .ofs_y = -1},\n    {.bitmap_index = 52, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 57, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 62, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 67, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 72, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 77, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 82, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 87, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 92, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 97, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 102, .adv_w = 128, .box_h = 4, .box_w = 1, .ofs_x = 3, .ofs_y = 0},\n    {.bitmap_index = 103, .adv_w = 128, .box_h = 6, .box_w = 2, .ofs_x = 2, .ofs_y = -2},\n    {.bitmap_index = 105, .adv_w = 128, .box_h = 7, .box_w = 4, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 109, .adv_w = 128, .box_h = 3, .box_w = 5, .ofs_x = 1, .ofs_y = 1},\n    {.bitmap_index = 111, .adv_w = 128, .box_h = 7, .box_w = 4, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 115, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 121, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 127, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 133, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 139, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 145, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 151, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 157, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 163, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 169, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 175, .adv_w = 128, .box_h = 7, .box_w = 3, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 178, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 183, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 189, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 195, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 201, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 207, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 213, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 219, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 225, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 231, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 237, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 242, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 248, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 254, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 260, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 266, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 271, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 276, .adv_w = 128, .box_h = 7, .box_w = 3, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 279, .adv_w = 128, .box_h = 7, .box_w = 7, .ofs_x = 0, .ofs_y = -1},\n    {.bitmap_index = 286, .adv_w = 128, .box_h = 7, .box_w = 3, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 289, .adv_w = 128, .box_h = 3, .box_w = 5, .ofs_x = 1, .ofs_y = 3},\n    {.bitmap_index = 291, .adv_w = 128, .box_h = 1, .box_w = 5, .ofs_x = 1, .ofs_y = -2},\n    {.bitmap_index = 292, .adv_w = 128, .box_h = 3, .box_w = 3, .ofs_x = 2, .ofs_y = 3},\n    {.bitmap_index = 294, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 298, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 303, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 307, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 312, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 316, .adv_w = 128, .box_h = 7, .box_w = 6, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 322, .adv_w = 128, .box_h = 6, .box_w = 5, .ofs_x = 1, .ofs_y = -2},\n    {.bitmap_index = 326, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 331, .adv_w = 128, .box_h = 7, .box_w = 3, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 334, .adv_w = 128, .box_h = 8, .box_w = 4, .ofs_x = 2, .ofs_y = -2},\n    {.bitmap_index = 338, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 343, .adv_w = 128, .box_h = 7, .box_w = 3, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 346, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 350, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 354, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 358, .adv_w = 128, .box_h = 6, .box_w = 5, .ofs_x = 1, .ofs_y = -2},\n    {.bitmap_index = 362, .adv_w = 128, .box_h = 6, .box_w = 5, .ofs_x = 1, .ofs_y = -2},\n    {.bitmap_index = 366, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 370, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 374, .adv_w = 128, .box_h = 7, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 379, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 383, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 387, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 391, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 395, .adv_w = 128, .box_h = 6, .box_w = 5, .ofs_x = 1, .ofs_y = -2},\n    {.bitmap_index = 399, .adv_w = 128, .box_h = 5, .box_w = 5, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 403, .adv_w = 128, .box_h = 7, .box_w = 4, .ofs_x = 1, .ofs_y = -1},\n    {.bitmap_index = 407, .adv_w = 128, .box_h = 8, .box_w = 1, .ofs_x = 3, .ofs_y = -2},\n    {.bitmap_index = 408, .adv_w = 128, .box_h = 7, .box_w = 4, .ofs_x = 2, .ofs_y = -1},\n    {.bitmap_index = 412, .adv_w = 128, .box_h = 3, .box_w = 5, .ofs_x = 1, .ofs_y = 3},\n    {.bitmap_index = 414, .adv_w = 128, .box_h = 7, .box_w = 7, .ofs_x = 0, .ofs_y = -1}\n};\n\n/*---------------------\n *  CHARACTER MAPPING\n *--------------------*/\n\n\n\n/*Collect the unicode lists and glyph_id offsets*/\nstatic const lv_font_fmt_txt_cmap_t cmaps[] =\n{\n    {\n        .range_start = 32, .range_length = 96, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY,\n        .glyph_id_start = 1, .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0\n    }\n};\n\n\n\n/*--------------------\n *  ALL CUSTOM DATA\n *--------------------*/\n\n/*Store all the custom data of the font*/\nstatic lv_font_fmt_txt_dsc_t font_dsc = {\n    .glyph_bitmap = gylph_bitmap,\n    .glyph_dsc = glyph_dsc,\n    .cmaps = cmaps,\n    .cmap_num = 1,\n    .bpp = 1,\n\n    .kern_scale = 0,\n    .kern_dsc = NULL,\n    .kern_classes = 0,\n};\n\n\n/*-----------------\n *  PUBLIC FONT\n *----------------*/\n\n/*Initialize a public general font descriptor*/\nlv_font_t lv_font_unscii_8 = {\n    .dsc = &font_dsc,          /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */\n    .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt,    /*Function pointer to get glyph's bitmap*/\n    .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt,    /*Function pointer to get glyph's data*/\n    .line_height = 8,          /*The maximum line height required by the font*/\n    .base_line = 2,             /*Baseline measured from the bottom of the line*/\n};\n\n#endif /*#if LV_FONT_UNSCII_8*/\n\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_hal/lv_hal.mk",
    "content": "CSRCS += lv_hal_disp.c\nCSRCS += lv_hal_indev.c\nCSRCS += lv_hal_tick.c\n\nDEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_hal\nVPATH += :$(LVGL_DIR)/lvgl/src/lv_hal\n\nCFLAGS += \"-I$(LVGL_DIR)/lvgl/src/lv_hal\"\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_hal/lv_hal_disp.c",
    "content": "\n/**\n * @file hal_disp.c\n *\n * @description HAL layer for display driver\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include <stdint.h>\n#include <stddef.h>\n#include \"libs/lvgl/lv_hal/lv_hal.h\"\n#include \"libs/lvgl/lv_misc/lv_mem.h\"\n#include \"libs/lvgl/lv_core/lv_obj.h\"\n#include \"libs/lvgl/lv_core/lv_refr.h\"\n#include \"libs/lvgl/lv_misc/lv_gc.h\"\n\n#if defined(LV_GC_INCLUDE)\n#include LV_GC_INCLUDE\n#endif /* LV_ENABLE_GC */\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_disp_t * disp_def;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Initialize a display driver with default values.\n * It is used to surly have known values in the fields ant not memory junk.\n * After it you can set the fields.\n * @param driver pointer to driver variable to initialize\n */\nvoid lv_disp_drv_init(lv_disp_drv_t * driver)\n{\n    memset(driver, 0, sizeof(lv_disp_drv_t));\n\n    driver->flush_cb         = NULL;\n    driver->hor_res          = LV_HOR_RES_MAX;\n    driver->ver_res          = LV_VER_RES_MAX;\n    driver->buffer           = NULL;\n    driver->rotated          = 0;\n    driver->color_chroma_key = LV_COLOR_TRANSP;\n\n#if LV_ANTIALIAS\n    driver->antialiasing = true;\n#endif\n\n#if LV_COLOR_SCREEN_TRANSP\n    driver->screen_transp = 1;\n#endif\n\n#if LV_USE_GPU\n    driver->gpu_blend_cb = NULL;\n    driver->gpu_fill_cb  = NULL;\n#endif\n\n#if LV_USE_USER_DATA\n    driver->user_data = NULL;\n#endif\n\n    driver->set_px_cb = NULL;\n}\n\n/**\n * Initialize a display buffer\n * @param disp_buf pointer `lv_disp_buf_t` variable to initialize\n * @param buf1 A buffer to be used by LittlevGL to draw the image.\n *             Always has to specified and can't be NULL.\n *             Can be an array allocated by the user. E.g. `static lv_color_t disp_buf1[1024 * 10]`\n *             Or a memory address e.g. in external SRAM\n * @param buf2 Optionally specify a second buffer to make image rendering and image flushing\n *             (sending to the display) parallel.\n *             In the `disp_drv->flush` you should use DMA or similar hardware to send\n *             the image to the display in the background.\n *             It lets LittlevGL to render next frame into the other buffer while previous is being\n * sent. Set to `NULL` if unused.\n * @param size_in_px_cnt size of the `buf1` and `buf2` in pixel count.\n */\nvoid lv_disp_buf_init(lv_disp_buf_t * disp_buf, void * buf1, void * buf2, uint32_t size_in_px_cnt)\n{\n    memset(disp_buf, 0, sizeof(lv_disp_buf_t));\n\n    disp_buf->buf1    = buf1;\n    disp_buf->buf2    = buf2;\n    disp_buf->buf_act = disp_buf->buf1;\n    disp_buf->size    = size_in_px_cnt;\n}\n\n/**\n * Register an initialized display driver.\n * Automatically set the first display as active.\n * @param driver pointer to an initialized 'lv_disp_drv_t' variable (can be local variable)\n * @return pointer to the new display or NULL on error\n */\nlv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)\n{\n    lv_disp_t * disp = lv_ll_ins_head(&LV_GC_ROOT(_lv_disp_ll));\n    if(!disp) {\n        lv_mem_assert(disp);\n        return NULL;\n    }\n\n    memcpy(&disp->driver, driver, sizeof(lv_disp_drv_t));\n    memset(&disp->inv_area_joined, 0, sizeof(disp->inv_area_joined));\n    memset(&disp->inv_areas, 0, sizeof(disp->inv_areas));\n    lv_ll_init(&disp->scr_ll, sizeof(lv_obj_t));\n\n    if(disp_def == NULL) disp_def = disp;\n\n    lv_disp_t * disp_def_tmp = disp_def;\n    disp_def                 = disp; /*Temporarily change the default screen to create the default screens on the\n                                        new display*/\n\n    disp->inv_p = 0;\n\n    disp->act_scr   = lv_obj_create(NULL, NULL); /*Create a default screen on the display*/\n    disp->top_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/\n    disp->sys_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/\n    lv_obj_set_style(disp->top_layer, &lv_style_transp);\n    lv_obj_set_style(disp->sys_layer, &lv_style_transp);\n\n    lv_obj_invalidate(disp->act_scr);\n\n    disp_def = disp_def_tmp; /*Revert the default display*/\n\n    /*Create a refresh task*/\n    disp->refr_task = lv_task_create(lv_disp_refr_task, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, disp);\n    lv_mem_assert(disp->refr_task);\n    if(disp->refr_task == NULL) return NULL;\n\n    lv_task_ready(disp->refr_task); /*Be sure the screen will be refreshed immediately on start up*/\n\n    return disp;\n}\n\n/**\n * Update the driver in run time.\n * @param disp pointer to a display. (return value of `lv_disp_drv_register`)\n * @param new_drv pointer to the new driver\n */\nvoid lv_disp_drv_update(lv_disp_t * disp, lv_disp_drv_t * new_drv)\n{\n    memcpy(&disp->driver, new_drv, sizeof(lv_disp_drv_t));\n\n    lv_obj_t * scr;\n    LV_LL_READ(disp->scr_ll, scr)\n    {\n        lv_obj_set_size(scr, lv_disp_get_hor_res(disp), lv_disp_get_ver_res(disp));\n    }\n}\n\n/**\n * Remove a display\n * @param disp pointer to display\n */\nvoid lv_disp_remove(lv_disp_t * disp)\n{\n    bool was_default = false;\n    if(disp == lv_disp_get_default()) was_default = true;\n\n    /*Detach the input devices */\n    lv_indev_t * indev;\n    indev = lv_indev_get_next(NULL);\n    while(indev) {\n        if(indev->driver.disp == disp) {\n            indev->driver.disp = NULL;\n        }\n        indev = lv_indev_get_next(indev);\n    }\n\n    lv_ll_rem(&LV_GC_ROOT(_lv_disp_ll), disp);\n    lv_mem_free(disp);\n\n    if(was_default) lv_disp_set_default(lv_ll_get_head(&LV_GC_ROOT(_lv_disp_ll)));\n}\n\n/**\n * Set a default screen. The new screens will be created on it by default.\n * @param disp pointer to a display\n */\nvoid lv_disp_set_default(lv_disp_t * disp)\n{\n    disp_def = disp;\n}\n\n/**\n * Get the default display\n * @return pointer to the default display\n */\nlv_disp_t * lv_disp_get_default(void)\n{\n    return disp_def;\n}\n\n/**\n * Get the horizontal resolution of a display\n * @param disp pointer to a display (NULL to use the default display)\n * @return the horizontal resolution of the display\n */\nlv_coord_t lv_disp_get_hor_res(lv_disp_t * disp)\n{\n    if(disp == NULL) disp = lv_disp_get_default();\n\n    if(disp == NULL)\n        return LV_HOR_RES_MAX;\n    else\n        return disp->driver.rotated == 0 ? disp->driver.hor_res : disp->driver.ver_res;\n}\n\n/**\n * Get the vertical resolution of a display\n * @param disp pointer to a display (NULL to use the default display)\n * @return the vertical resolution of the display\n */\nlv_coord_t lv_disp_get_ver_res(lv_disp_t * disp)\n{\n    if(disp == NULL) disp = lv_disp_get_default();\n\n    if(disp == NULL)\n        return LV_VER_RES_MAX;\n    else\n        return disp->driver.rotated == 0 ? disp->driver.ver_res : disp->driver.hor_res;\n}\n\n/**\n * Get if anti-aliasing is enabled for a display or not\n * @param disp pointer to a display (NULL to use the default display)\n * @return true: anti-aliasing is enabled; false: disabled\n */\nbool lv_disp_get_antialiasing(lv_disp_t * disp)\n{\n#if LV_ANTIALIAS == 0\n    return false;\n#else\n    if(disp == NULL) disp = lv_disp_get_default();\n    if(disp == NULL) return false;\n\n    return disp->driver.antialiasing ? true : false;\n#endif\n}\n\n/**\n * Call in the display driver's `flush_cb` function when the flushing is finished\n * @param disp_drv pointer to display driver in `flush_cb` where this function is called\n */\nLV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_drv_t * disp_drv)\n{\n    disp_drv->buffer->flushing = 0;\n\n    /*If the screen is transparent initialize it when the flushing is ready*/\n#if LV_COLOR_SCREEN_TRANSP\n    if(disp_drv->screen_transp) {\n        memset(disp_drv->buffer->buf_act, 0x00, disp_drv->buffer->size * sizeof(lv_color32_t));\n    }\n#endif\n}\n\n/**\n * Get the next display.\n * @param disp pointer to the current display. NULL to initialize.\n * @return the next display or NULL if no more. Give the first display when the parameter is NULL\n */\nlv_disp_t * lv_disp_get_next(lv_disp_t * disp)\n{\n    if(disp == NULL)\n        return lv_ll_get_head(&LV_GC_ROOT(_lv_disp_ll));\n    else\n        return lv_ll_get_next(&LV_GC_ROOT(_lv_disp_ll), disp);\n}\n\n/**\n * Get the internal buffer of a display\n * @param disp pointer to a display\n * @return pointer to the internal buffers\n */\nlv_disp_buf_t * lv_disp_get_buf(lv_disp_t * disp)\n{\n    return disp->driver.buffer;\n}\n\n/**\n * Get the number of areas in the buffer\n * @return number of invalid areas\n */\nuint16_t lv_disp_get_inv_buf_size(lv_disp_t * disp)\n{\n    return disp->inv_p;\n}\n\n/**\n * Pop (delete) the last 'num' invalidated areas from the buffer\n * @param num number of areas to delete\n */\nvoid lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num)\n{\n\n    if(disp->inv_p < num)\n        disp->inv_p = 0;\n    else\n        disp->inv_p -= num;\n}\n\n/**\n * Check the driver configuration if it's double buffered (both `buf1` and `buf2` are set)\n * @param disp pointer to to display to check\n * @return true: double buffered; false: not double buffered\n */\nbool lv_disp_is_double_buf(lv_disp_t * disp)\n{\n    if(disp->driver.buffer->buf1 && disp->driver.buffer->buf2)\n        return true;\n    else\n        return false;\n}\n\n/**\n * Check the driver configuration if it's TRUE double buffered (both `buf1` and `buf2` are set and\n * `size` is screen sized)\n * @param disp pointer to to display to check\n * @return true: double buffered; false: not double buffered\n */\nbool lv_disp_is_true_double_buf(lv_disp_t * disp)\n{\n    uint32_t scr_size = disp->driver.hor_res * disp->driver.ver_res;\n\n    if(lv_disp_is_double_buf(disp) && disp->driver.buffer->size == scr_size) {\n        return true;\n    } else {\n        return false;\n    }\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_hal/lv_hal_indev.c",
    "content": "/**\n * @file hal_indev.c\n *\n * @description Input device HAL interface\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_hal/lv_hal_indev.h\"\n#include \"libs/lvgl/lv_core/lv_indev.h\"\n#include \"libs/lvgl/lv_misc/lv_mem.h\"\n#include \"libs/lvgl/lv_misc/lv_gc.h\"\n#include \"libs/lvgl/lv_hal/lv_hal_disp.h\"\n\n#if defined(LV_GC_INCLUDE)\n#include LV_GC_INCLUDE\n#endif /* LV_ENABLE_GC */\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Initialize an input device driver with default values.\n * It is used to surly have known values in the fields ant not memory junk.\n * After it you can set the fields.\n * @param driver pointer to driver variable to initialize\n */\nvoid lv_indev_drv_init(lv_indev_drv_t * driver)\n{\n    memset(driver, 0, sizeof(lv_indev_drv_t));\n\n    driver->type                = LV_INDEV_TYPE_NONE;\n    driver->drag_limit          = LV_INDEV_DEF_DRAG_LIMIT;\n    driver->drag_throw          = LV_INDEV_DEF_DRAG_THROW;\n    driver->long_press_time     = LV_INDEV_DEF_LONG_PRESS_TIME;\n    driver->long_press_rep_time = LV_INDEV_DEF_LONG_PRESS_REP_TIME;\n}\n\n/**\n * Register an initialized input device driver.\n * @param driver pointer to an initialized 'lv_indev_drv_t' variable (can be local variable)\n * @return pointer to the new input device or NULL on error\n */\nlv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver)\n{\n\n    if(driver->disp == NULL) driver->disp = lv_disp_get_default();\n\n    if(driver->disp == NULL) {\n        LV_LOG_WARN(\"lv_indev_drv_register: no display registered hence can't attache the indev to \"\n                    \"a display\");\n        return NULL;\n    }\n\n    lv_indev_t * indev = lv_ll_ins_head(&LV_GC_ROOT(_lv_indev_ll));\n    if(!indev) {\n        lv_mem_assert(indev);\n        return NULL;\n    }\n\n    memset(indev, 0, sizeof(lv_indev_t));\n    memcpy(&indev->driver, driver, sizeof(lv_indev_drv_t));\n\n    indev->proc.reset_query = 1;\n    indev->cursor           = NULL;\n    indev->group            = NULL;\n    indev->btn_points       = NULL;\n\n    indev->driver.read_task = lv_task_create(lv_indev_read_task, LV_INDEV_DEF_READ_PERIOD, LV_TASK_PRIO_MID, indev);\n\n    return indev;\n}\n\n/**\n * Update the driver in run time.\n * @param indev pointer to a input device. (return value of `lv_indev_drv_register`)\n * @param new_drv pointer to the new driver\n */\nvoid lv_indev_drv_update(lv_indev_t * indev, lv_indev_drv_t * new_drv)\n{\n    memcpy(&indev->driver, new_drv, sizeof(lv_indev_drv_t));\n}\n\n/**\n * Get the next input device.\n * @param indev pointer to the current input device. NULL to initialize.\n * @return the next input devise or NULL if no more. Give the first input device when the parameter\n * is NULL\n */\nlv_indev_t * lv_indev_get_next(lv_indev_t * indev)\n{\n    if(indev == NULL)\n        return lv_ll_get_head(&LV_GC_ROOT(_lv_indev_ll));\n    else\n        return lv_ll_get_next(&LV_GC_ROOT(_lv_indev_ll), indev);\n}\n\n/**\n * Read data from an input device.\n * @param indev pointer to an input device\n * @param data input device will write its data here\n * @return false: no more data; true: there more data to read (buffered)\n */\nbool lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data)\n{\n    bool cont = false;\n\n    memset(data, 0, sizeof(lv_indev_data_t));\n\n    /* For touchpad sometimes users don't the last pressed coordinate on release.\n     * So be sure a coordinates are initialized to the last point */\n    if(indev->driver.type == LV_INDEV_TYPE_POINTER) {\n        data->point.x = indev->proc.types.pointer.act_point.x;\n        data->point.y = indev->proc.types.pointer.act_point.y;\n    }\n    /*Similarly set at least the last key in case of the  the user doesn't set it  on release*/\n    else if(indev->driver.type == LV_INDEV_TYPE_KEYPAD) {\n        data->key = indev->proc.types.keypad.last_key;\n    }\n\n    if(indev->driver.read_cb) {\n        LV_LOG_TRACE(\"idnev read started\");\n        cont = indev->driver.read_cb(&indev->driver, data);\n        LV_LOG_TRACE(\"idnev read finished\");\n    } else {\n        LV_LOG_WARN(\"indev function registered\");\n    }\n\n    return cont;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_hal/lv_hal_tick.c",
    "content": "/**\n * @file systick.c\n * Provide access to the system tick with 1 millisecond resolution\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"lv_conf.h\"\n#else\n#include \"libs/lvgl/lv_conf.h\"\n#endif\n\n#include \"libs/lvgl/lv_hal/lv_hal_tick.h\"\n#include <stddef.h>\n\n#if LV_TICK_CUSTOM == 1\n#include LV_TICK_CUSTOM_INCLUDE\n#endif\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic uint32_t sys_time = 0;\nstatic volatile uint8_t tick_irq_flag;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * You have to call this function periodically\n * @param tick_period the call period of this function in milliseconds\n */\nLV_ATTRIBUTE_TICK_INC void lv_tick_inc(uint32_t tick_period)\n{\n    tick_irq_flag = 0;\n    sys_time += tick_period;\n}\n\n/**\n * Get the elapsed milliseconds since start up\n * @return the elapsed milliseconds\n */\nuint32_t lv_tick_get(void)\n{\n#if LV_TICK_CUSTOM == 0\n    uint32_t result;\n    do {\n        tick_irq_flag = 1;\n        result        = sys_time;\n    } while(!tick_irq_flag); /*'lv_tick_inc()' clears this flag which can be in an interrupt.\n                                Continue until make a non interrupted cycle */\n\n    return result;\n#else\n    return LV_TICK_CUSTOM_SYS_TIME_EXPR;\n#endif\n}\n\n/**\n * Get the elapsed milliseconds since a previous time stamp\n * @param prev_tick a previous time stamp (return value of systick_get() )\n * @return the elapsed milliseconds since 'prev_tick'\n */\nuint32_t lv_tick_elaps(uint32_t prev_tick)\n{\n    uint32_t act_time = lv_tick_get();\n\n    /*If there is no overflow in sys_time simple subtract*/\n    if(act_time >= prev_tick) {\n        prev_tick = act_time - prev_tick;\n    } else {\n        prev_tick = UINT32_MAX - prev_tick + 1;\n        prev_tick += act_time;\n    }\n\n    return prev_tick;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_misc/lv_anim.c",
    "content": "/**\n * @file anim.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_misc/lv_anim.h\"\n\n#if LV_USE_ANIMATION\n#include <stddef.h>\n#include <string.h>\n#include \"libs/lvgl/lv_hal/lv_hal_tick.h\"\n#include \"libs/lvgl/lv_misc/lv_task.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n#include \"libs/lvgl/lv_misc/lv_gc.h\"\n\n#if defined(LV_GC_INCLUDE)\n#include LV_GC_INCLUDE\n#endif /* LV_ENABLE_GC */\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_ANIM_RESOLUTION 1024\n#define LV_ANIM_RES_SHIFT 10\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic void anim_task(lv_task_t * param);\nstatic bool anim_ready_handler(lv_anim_t * a);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic uint32_t last_task_run;\nstatic bool anim_list_changed;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Init. the animation module\n */\nvoid lv_anim_core_init(void)\n{\n    lv_ll_init(&LV_GC_ROOT(_lv_anim_ll), sizeof(lv_anim_t));\n    last_task_run = lv_tick_get();\n    lv_task_create(anim_task, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, NULL);\n}\n\n/**\n * Initialize an animation variable.\n * E.g.:\n * lv_anim_t a;\n * lv_anim_init(&a);\n * lv_anim_set_...(&a);\n * lv_anim_craete(&a);\n * @param a pointer to an `lv_anim_t` variable to initialize\n */\nvoid lv_anim_init(lv_anim_t * a)\n{\n    memset(a, 0, sizeof(lv_anim_t));\n    a->time    = 500;\n    a->start   = 0;\n    a->end     = 100;\n    a->path_cb = lv_anim_path_linear;\n}\n/**\n * Create an animation\n * @param a an initialized 'anim_t' variable. Not required after call.\n */\nvoid lv_anim_create(lv_anim_t * a)\n{\n    LV_LOG_TRACE(\"animation create started\")\n    /* Do not let two animations for the  same 'var' with the same 'fp'*/\n    if(a->exec_cb != NULL) lv_anim_del(a->var, a->exec_cb); /*fp == NULL would delete all animations of var*/\n\n    /*Add the new animation to the animation linked list*/\n    lv_anim_t * new_anim = lv_ll_ins_head(&LV_GC_ROOT(_lv_anim_ll));\n    lv_mem_assert(new_anim);\n    if(new_anim == NULL) return;\n\n    /*Initialize the animation descriptor*/\n    a->playback_now = 0;\n    memcpy(new_anim, a, sizeof(lv_anim_t));\n\n    /*Set the start value*/\n    if(new_anim->exec_cb) new_anim->exec_cb(new_anim->var, new_anim->start);\n\n    /* Creating an animation changed the linked list.\n     * It's important if it happens in a ready callback. (see `anim_task`)*/\n    anim_list_changed = true;\n\n    LV_LOG_TRACE(\"animation created\")\n}\n\n/**\n * Delete an animation of a variable with a given animator function\n * @param var pointer to variable\n * @param exec_cb a function pointer which is animating 'var',\n *           or NULL to delete all the animations of 'var'\n * @return true: at least 1 animation is deleted, false: no animation is deleted\n */\nbool lv_anim_del(void * var, lv_anim_exec_xcb_t exec_cb)\n{\n    lv_anim_t * a;\n    lv_anim_t * a_next;\n    bool del = false;\n    a        = lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));\n    while(a != NULL) {\n        /*'a' might be deleted, so get the next object while 'a' is valid*/\n        a_next = lv_ll_get_next(&LV_GC_ROOT(_lv_anim_ll), a);\n\n        if(a->var == var && (a->exec_cb == exec_cb || exec_cb == NULL)) {\n            lv_ll_rem(&LV_GC_ROOT(_lv_anim_ll), a);\n            lv_mem_free(a);\n            anim_list_changed = true; /*Read by `anim_task`. It need to know if a delete occurred in\n                                         the linked list*/\n            del = true;\n        }\n\n        a = a_next;\n    }\n\n    return del;\n}\n\n/**\n * Get the number of currently running animations\n * @return the number of running animations\n */\nuint16_t lv_anim_count_running(void)\n{\n    uint16_t cnt = 0;\n    lv_anim_t * a;\n    LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a) cnt++;\n\n    return cnt++;\n}\n\n/**\n * Calculate the time of an animation with a given speed and the start and end values\n * @param speed speed of animation in unit/sec\n * @param start start value of the animation\n * @param end end value of the animation\n * @return the required time [ms] for the animation with the given parameters\n */\nuint16_t lv_anim_speed_to_time(uint16_t speed, lv_anim_value_t start, lv_anim_value_t end)\n{\n    int32_t d     = LV_MATH_ABS((int32_t)start - end);\n    uint32_t time = (int32_t)((int32_t)(d * 1000) / speed);\n\n    if(time > UINT16_MAX) time = UINT16_MAX;\n\n    if(time == 0) {\n        time++;\n    }\n\n    return time;\n}\n\n/**\n * Calculate the current value of an animation applying linear characteristic\n * @param a pointer to an animation\n * @return the current value to set\n */\nlv_anim_value_t lv_anim_path_linear(const lv_anim_t * a)\n{\n    /*Calculate the current step*/\n    uint32_t step;\n    if(a->time == a->act_time) {\n        step = LV_ANIM_RESOLUTION; /*Use the last value if the time fully elapsed*/\n    } else {\n        step = ((int32_t)a->act_time * LV_ANIM_RESOLUTION) / a->time;\n    }\n\n    /* Get the new value which will be proportional to `step`\n     * and the `start` and `end` values*/\n    int32_t new_value;\n    new_value = (int32_t)step * (a->end - a->start);\n    new_value = new_value >> LV_ANIM_RES_SHIFT;\n    new_value += a->start;\n\n    return (lv_anim_value_t)new_value;\n}\n\n/**\n * Calculate the current value of an animation slowing down the start phase\n * @param a pointer to an animation\n * @return the current value to set\n */\nlv_anim_value_t lv_anim_path_ease_in(const lv_anim_t * a)\n{\n    /*Calculate the current step*/\n    uint32_t t;\n    if(a->time == a->act_time)\n        t = 1024;\n    else\n        t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;\n\n    int32_t step = lv_bezier3(t, 0, 1, 1, 1024);\n\n    int32_t new_value;\n    new_value = (int32_t)step * (a->end - a->start);\n    new_value = new_value >> 10;\n    new_value += a->start;\n\n    return (lv_anim_value_t)new_value;\n}\n\n/**\n * Calculate the current value of an animation slowing down the end phase\n * @param a pointer to an animation\n * @return the current value to set\n */\nlv_anim_value_t lv_anim_path_ease_out(const lv_anim_t * a)\n{\n    /*Calculate the current step*/\n\n    uint32_t t;\n    if(a->time == a->act_time)\n        t = 1024;\n    else\n        t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;\n\n    int32_t step = lv_bezier3(t, 0, 1023, 1023, 1024);\n\n    int32_t new_value;\n    new_value = (int32_t)step * (a->end - a->start);\n    new_value = new_value >> 10;\n    new_value += a->start;\n\n    return (lv_anim_value_t)new_value;\n}\n\n/**\n * Calculate the current value of an animation applying an \"S\" characteristic (cosine)\n * @param a pointer to an animation\n * @return the current value to set\n */\nlv_anim_value_t lv_anim_path_ease_in_out(const lv_anim_t * a)\n{\n    /*Calculate the current step*/\n\n    uint32_t t;\n    if(a->time == a->act_time)\n        t = 1024;\n    else\n        t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;\n\n    int32_t step = lv_bezier3(t, 0, 100, 924, 1024);\n\n    int32_t new_value;\n    new_value = (int32_t)step * (a->end - a->start);\n    new_value = new_value >> 10;\n    new_value += a->start;\n\n    return (lv_anim_value_t)new_value;\n}\n\n/**\n * Calculate the current value of an animation with overshoot at the end\n * @param a pointer to an animation\n * @return the current value to set\n */\nlv_anim_value_t lv_anim_path_overshoot(const lv_anim_t * a)\n{\n    /*Calculate the current step*/\n\n    uint32_t t;\n    if(a->time == a->act_time)\n        t = 1024;\n    else\n        t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;\n\n    int32_t step = lv_bezier3(t, 0, 600, 1300, 1024);\n\n    int32_t new_value;\n    new_value = (int32_t)step * (a->end - a->start);\n    new_value = new_value >> 10;\n    new_value += a->start;\n\n    return (lv_anim_value_t)new_value;\n}\n\n/**\n * Calculate the current value of an animation with 3 bounces\n * @param a pointer to an animation\n * @return the current value to set\n */\nlv_anim_value_t lv_anim_path_bounce(const lv_anim_t * a)\n{\n    /*Calculate the current step*/\n    uint32_t t;\n    if(a->time == a->act_time)\n        t = 1024;\n    else\n        t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time;\n\n    int32_t diff = (a->end - a->start);\n\n    /*3 bounces has 5 parts: 3 down and 2 up. One part is t / 5 long*/\n\n    if(t < 408) {\n        /*Go down*/\n        t = (t * 2500) >> 10; /*[0..1024] range*/\n    } else if(t >= 408 && t < 614) {\n        /*First bounce back*/\n        t -= 408;\n        t    = t * 5; /*to [0..1024] range*/\n        t    = 1024 - t;\n        diff = diff / 6;\n    } else if(t >= 614 && t < 819) {\n        /*Fall back*/\n        t -= 614;\n        t    = t * 5; /*to [0..1024] range*/\n        diff = diff / 6;\n    } else if(t >= 819 && t < 921) {\n        /*Second bounce back*/\n        t -= 819;\n        t    = t * 10; /*to [0..1024] range*/\n        t    = 1024 - t;\n        diff = diff / 16;\n    } else if(t >= 921 && t <= 1024) {\n        /*Fall back*/\n        t -= 921;\n        t    = t * 10; /*to [0..1024] range*/\n        diff = diff / 16;\n    }\n\n    if(t > 1024) t = 1024;\n\n    int32_t step = lv_bezier3(t, 1024, 1024, 800, 0);\n\n    int32_t new_value;\n    new_value = (int32_t)step * diff;\n    new_value = new_value >> 10;\n    new_value = a->end - new_value;\n\n    return (lv_anim_value_t)new_value;\n}\n\n/**\n * Calculate the current value of an animation applying step characteristic.\n * (Set end value on the end of the animation)\n * @param a pointer to an animation\n * @return the current value to set\n */\nlv_anim_value_t lv_anim_path_step(const lv_anim_t * a)\n{\n    if(a->act_time >= a->time)\n        return a->end;\n    else\n        return a->start;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Periodically handle the animations.\n * @param param unused\n */\nstatic void anim_task(lv_task_t * param)\n{\n    (void)param;\n\n    lv_anim_t * a;\n    LV_LL_READ(LV_GC_ROOT(_lv_anim_ll), a)\n    {\n        a->has_run = 0;\n    }\n\n    uint32_t elaps = lv_tick_elaps(last_task_run);\n\n    a = lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));\n\n    while(a != NULL) {\n        /*It can be set by `lv_anim_del()` typically in `end_cb`. If set then an animation delete\n         * happened in `anim_ready_handler` which could make this linked list reading corrupt\n         * because the list is changed meanwhile\n         */\n        anim_list_changed = false;\n\n        if(!a->has_run) {\n            a->has_run = 1; /*The list readying might be reseted so need to know which anim has run already*/\n            a->act_time += elaps;\n            if(a->act_time >= 0) {\n                if(a->act_time > a->time) a->act_time = a->time;\n\n                int32_t new_value;\n                new_value = a->path_cb(a);\n\n                /*Apply the calculated value*/\n                if(a->exec_cb) a->exec_cb(a->var, new_value);\n\n                /*If the time is elapsed the animation is ready*/\n                if(a->act_time >= a->time) {\n                    anim_ready_handler(a);\n                }\n            }\n        }\n\n        /* If the linked list changed due to anim. delete then it's not safe to continue\n         * the reading of the list from here -> start from the head*/\n        if(anim_list_changed)\n            a = lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll));\n        else\n            a = lv_ll_get_next(&LV_GC_ROOT(_lv_anim_ll), a);\n    }\n\n    last_task_run = lv_tick_get();\n}\n\n/**\n * Called when an animation is ready to do the necessary thinks\n * e.g. repeat, play back, delete etc.\n * @param a pointer to an animation descriptor\n * @return true: animation delete occurred nnd the `LV_GC_ROOT(_lv_anim_ll)` has changed\n * */\nstatic bool anim_ready_handler(lv_anim_t * a)\n{\n\n    /*Delete the animation if\n     * - no repeat and no play back (simple one shot animation)\n     * - no repeat, play back is enabled and play back is ready */\n    if((a->repeat == 0 && a->playback == 0) || (a->repeat == 0 && a->playback == 1 && a->playback_now == 1)) {\n\n        /*Create copy from the animation and delete the animation from the list.\n         * This way the `ready_cb` will see the animations like it's animation is ready deleted*/\n        lv_anim_t a_tmp;\n        memcpy(&a_tmp, a, sizeof(lv_anim_t));\n        lv_ll_rem(&LV_GC_ROOT(_lv_anim_ll), a);\n        lv_mem_free(a);\n        anim_list_changed = true;\n\n        /* Call the callback function at the end*/\n        if(a_tmp.ready_cb != NULL) a_tmp.ready_cb(&a_tmp);\n    }\n    /*If the animation is not deleted then restart it*/\n    else {\n        a->act_time = -a->repeat_pause; /*Restart the animation*/\n        /*Swap the start and end values in play back mode*/\n        if(a->playback != 0) {\n            /*If now turning back use the 'playback_pause*/\n            if(a->playback_now == 0) a->act_time = -a->playback_pause;\n\n            /*Toggle the play back state*/\n            a->playback_now = a->playback_now == 0 ? 1 : 0;\n            /*Swap the start and end values*/\n            int32_t tmp;\n            tmp      = a->start;\n            a->start = a->end;\n            a->end   = tmp;\n        }\n    }\n\n    return anim_list_changed;\n}\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_misc/lv_area.c",
    "content": "/**\n * @file lv_area.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#ifdef LV_CONF_INCLUDE_SIMPLE\n#include \"libs/lvgl/lv_conf.h\"\n#else\n#include \"libs/lvgl/lv_conf.h\"\n#endif\n\n#include \"libs/lvgl/lv_misc/lv_area.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Initialize an area\n * @param area_p pointer to an area\n * @param x1 left coordinate of the area\n * @param y1 top coordinate of the area\n * @param x2 right coordinate of the area\n * @param y2 bottom coordinate of the area\n */\nvoid lv_area_set(lv_area_t * area_p, lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2)\n{\n    area_p->x1 = x1;\n    area_p->y1 = y1;\n    area_p->x2 = x2;\n    area_p->y2 = y2;\n}\n\n/**\n * Set the width of an area\n * @param area_p pointer to an area\n * @param w the new width of the area (w == 1 makes x1 == x2)\n */\nvoid lv_area_set_width(lv_area_t * area_p, lv_coord_t w)\n{\n    area_p->x2 = area_p->x1 + w - 1;\n}\n\n/**\n * Set the height of an area\n * @param area_p pointer to an area\n * @param h the new height of the area (h == 1 makes y1 == y2)\n */\nvoid lv_area_set_height(lv_area_t * area_p, lv_coord_t h)\n{\n    area_p->y2 = area_p->y1 + h - 1;\n}\n\n/**\n * Set the position of an area (width and height will be kept)\n * @param area_p pointer to an area\n * @param x the new x coordinate of the area\n * @param y the new y coordinate of the area\n */\nvoid lv_area_set_pos(lv_area_t * area_p, lv_coord_t x, lv_coord_t y)\n{\n    lv_coord_t w = lv_area_get_width(area_p);\n    lv_coord_t h = lv_area_get_height(area_p);\n    area_p->x1   = x;\n    area_p->y1   = y;\n    lv_area_set_width(area_p, w);\n    lv_area_set_height(area_p, h);\n}\n\n/**\n * Return with area of an area (x * y)\n * @param area_p pointer to an area\n * @return size of area\n */\nuint32_t lv_area_get_size(const lv_area_t * area_p)\n{\n    uint32_t size;\n\n    size = (uint32_t)(area_p->x2 - area_p->x1 + 1) * (area_p->y2 - area_p->y1 + 1);\n\n    return size;\n}\n\n/**\n * Get the common parts of two areas\n * @param res_p pointer to an area, the result will be stored here\n * @param a1_p pointer to the first area\n * @param a2_p pointer to the second area\n * @return false: the two area has NO common parts, res_p is invalid\n */\nbool lv_area_intersect(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t * a2_p)\n{\n    /* Get the smaller area from 'a1_p' and 'a2_p' */\n    res_p->x1 = LV_MATH_MAX(a1_p->x1, a2_p->x1);\n    res_p->y1 = LV_MATH_MAX(a1_p->y1, a2_p->y1);\n    res_p->x2 = LV_MATH_MIN(a1_p->x2, a2_p->x2);\n    res_p->y2 = LV_MATH_MIN(a1_p->y2, a2_p->y2);\n\n    /*If x1 or y1 greater then x2 or y2 then the areas union is empty*/\n    bool union_ok = true;\n    if((res_p->x1 > res_p->x2) || (res_p->y1 > res_p->y2)) {\n        union_ok = false;\n    }\n\n    return union_ok;\n}\n/**\n * Join two areas into a third which involves the other two\n * @param res_p pointer to an area, the result will be stored here\n * @param a1_p pointer to the first area\n * @param a2_p pointer to the second area\n */\nvoid lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t * a2_p)\n{\n    a_res_p->x1 = LV_MATH_MIN(a1_p->x1, a2_p->x1);\n    a_res_p->y1 = LV_MATH_MIN(a1_p->y1, a2_p->y1);\n    a_res_p->x2 = LV_MATH_MAX(a1_p->x2, a2_p->x2);\n    a_res_p->y2 = LV_MATH_MAX(a1_p->y2, a2_p->y2);\n}\n\n/**\n * Check if a point is on an area\n * @param a_p pointer to an area\n * @param p_p pointer to a point\n * @return false:the point is out of the area\n */\nbool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p)\n{\n    bool is_on = false;\n\n    if((p_p->x >= a_p->x1 && p_p->x <= a_p->x2) && ((p_p->y >= a_p->y1 && p_p->y <= a_p->y2))) {\n        is_on = true;\n    }\n\n    return is_on;\n}\n\n/**\n * Check if two area has common parts\n * @param a1_p pointer to an area.\n * @param a2_p pointer to an other area\n * @return false: a1_p and a2_p has no common parts\n */\nbool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p)\n{\n    if((a1_p->x1 <= a2_p->x2) && (a1_p->x2 >= a2_p->x1) && (a1_p->y1 <= a2_p->y2) && (a1_p->y2 >= a2_p->y1)) {\n        return true;\n    } else {\n        return false;\n    }\n}\n\n/**\n * Check if an area is fully on an other\n * @param ain_p pointer to an area which could be in 'aholder_p'\n * @param aholder pointer to an area which could involve 'ain_p'\n * @return\n */\nbool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p)\n{\n    bool is_in = false;\n\n    if(ain_p->x1 >= aholder_p->x1 && ain_p->y1 >= aholder_p->y1 && ain_p->x2 <= aholder_p->x2 &&\n       ain_p->y2 <= aholder_p->y2) {\n        is_in = true;\n    }\n\n    return is_in;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_misc/lv_async.c",
    "content": "/**\n * @file lv_async.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n\n#include \"libs/lvgl/lv_misc/lv_async.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\nstatic void lv_async_task_cb(lv_task_t *task);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\nlv_res_t lv_async_call(lv_async_cb_t async_xcb, void * user_data)\n{\n    /*Allocate an info structure */\n    lv_async_info_t *info = lv_mem_alloc(sizeof(lv_async_info_t));\n    \n    if(info == NULL)\n        return LV_RES_INV;\n    \n    /* Create a new task */\n    /* Use highest priority so that it will run before a refresh */\n    lv_task_t *task = lv_task_create(lv_async_task_cb, 0, LV_TASK_PRIO_HIGHEST, info);\n    \n    if(task == NULL) {\n        lv_mem_free(info);\n        return LV_RES_INV;\n    }\n    \n    info->cb = async_xcb;\n    info->user_data = user_data;\n\n    /* Set the task's user data */\n    task->user_data = info;\n    lv_task_once(task);\n    return LV_RES_OK;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\nstatic void lv_async_task_cb(lv_task_t *task)\n{\n    lv_async_info_t *info = (lv_async_info_t *)task->user_data;\n    \n    info->cb(info->user_data);\n    \n    lv_mem_free(info);\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_misc/lv_circ.c",
    "content": "/**\n * @file lv_circ.c\n * Circle drawing algorithm (with Bresenham)\n * Only a 1/8 circle is calculated. Use CIRC_OCT1_X, CIRC_OCT1_Y macros to get\n * the other octets.\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_misc/lv_circ.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Initialize the circle drawing\n * @param c pointer to a point. The coordinates will be calculated here\n * @param tmp point to a variable. It will store temporary data\n * @param radius radius of the circle\n */\nvoid lv_circ_init(lv_point_t * c, lv_coord_t * tmp, lv_coord_t radius)\n{\n    c->x = radius;\n    c->y = 0;\n    *tmp = 1 - radius;\n}\n\n/**\n * Test the circle drawing is ready or not\n * @param c same as in circ_init\n * @return true if the circle is not ready yet\n */\nbool lv_circ_cont(lv_point_t * c)\n{\n    return c->y <= c->x ? true : false;\n}\n\n/**\n * Get the next point from the circle\n * @param c same as in circ_init. The next point stored here.\n * @param tmp same as in circ_init.\n */\nvoid lv_circ_next(lv_point_t * c, lv_coord_t * tmp)\n{\n    c->y++;\n\n    if(*tmp <= 0) {\n        (*tmp) += 2 * c->y + 1; /*Change in decision criterion for y -> y+1*/\n    } else {\n        c->x--;\n        (*tmp) += 2 * (c->y - c->x) + 1; /*Change for y -> y+1, x -> x-1*/\n    }\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_misc/lv_color.c",
    "content": "/**\n * @file lv_color.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_misc/lv_color.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Convert a HSV color to RGB\n * @param h hue [0..359]\n * @param s saturation [0..100]\n * @param v value [0..100]\n * @return the given RGB color in RGB (with LV_COLOR_DEPTH depth)\n */\nlv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v)\n{\n    h = (uint32_t)((uint32_t)h * 255) / 360;\n    s = (uint16_t)((uint16_t)s * 255) / 100;\n    v = (uint16_t)((uint16_t)v * 255) / 100;\n\n    uint8_t r, g, b;\n\n    uint8_t region, remainder, p, q, t;\n\n    if(s == 0) {\n        r = v;\n        g = v;\n        b = v;\n        return lv_color_make(v, v, v);\n    }\n\n    region    = h / 43;\n    remainder = (h - (region * 43)) * 6;\n\n    p = (v * (255 - s)) >> 8;\n    q = (v * (255 - ((s * remainder) >> 8))) >> 8;\n    t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;\n\n    switch(region) {\n        case 0:\n            r = v;\n            g = t;\n            b = p;\n            break;\n        case 1:\n            r = q;\n            g = v;\n            b = p;\n            break;\n        case 2:\n            r = p;\n            g = v;\n            b = t;\n            break;\n        case 3:\n            r = p;\n            g = q;\n            b = v;\n            break;\n        case 4:\n            r = t;\n            g = p;\n            b = v;\n            break;\n        default:\n            r = v;\n            g = p;\n            b = q;\n            break;\n    }\n\n    lv_color_t result = lv_color_make(r, g, b);\n    return result;\n}\n\n/**\n * Convert an RGB color to HSV\n * @param r red\n * @param g green\n * @param b blue\n * @return the given RGB color n HSV\n */\nlv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b)\n{\n    lv_color_hsv_t hsv;\n    uint8_t rgbMin, rgbMax;\n\n    rgbMin = r < g ? (r < b ? r : b) : (g < b ? g : b);\n    rgbMax = r > g ? (r > b ? r : b) : (g > b ? g : b);\n\n    hsv.v = rgbMax;\n    if(hsv.v == 0) {\n        hsv.h = 0;\n        hsv.s = 0;\n        return hsv;\n    }\n\n    hsv.s = 255 * (long)(rgbMax - rgbMin) / hsv.v;\n    if(hsv.s == 0) {\n        hsv.h = 0;\n        return hsv;\n    }\n\n    if(rgbMax == r)\n        hsv.h = 0 + 43 * (g - b) / (rgbMax - rgbMin);\n    else if(rgbMax == g)\n        hsv.h = 85 + 43 * (b - r) / (rgbMax - rgbMin);\n    else\n        hsv.h = 171 + 43 * (r - g) / (rgbMax - rgbMin);\n\n    return hsv;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_misc/lv_fs.c",
    "content": "/**\n * @file lv_fs.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_misc/lv_fs.h\"\n#if LV_USE_FILESYSTEM\n\n#include \"libs/lvgl/lv_misc/lv_ll.h\"\n#include <string.h>\n#include \"libs/lvgl/lv_misc/lv_gc.h\"\n\n#if defined(LV_GC_INCLUDE)\n#include LV_GC_INCLUDE\n#endif /* LV_ENABLE_GC */\n\n/*********************\n *      DEFINES\n *********************/\n\n/* \"free\" is used as a function pointer (in lv_fs_drv_t).\n * We must make sure \"free\" was not defined to a platform specific\n * free function, otherwise compilation would fail.\n */\n#ifdef free\n#undef free\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic const char * lv_fs_get_real_path(const char * path);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Initialize the File system interface\n */\nvoid lv_fs_init(void)\n{\n    lv_ll_init(&LV_GC_ROOT(_lv_drv_ll), sizeof(lv_fs_drv_t));\n}\n\n/**\n * Test if a drive is rady or not. If the `ready` function was not initialized `true` will be\n * returned.\n * @param letter letter of the drive\n * @return true: drive is ready; false: drive is not ready\n */\nbool lv_fs_is_ready(char letter)\n{\n    lv_fs_drv_t * drv = lv_fs_get_drv(letter);\n\n    if(drv == NULL) return false; /*An unknown driver in not ready*/\n\n    if(drv->ready_cb == NULL) return true; /*Assume the driver is always ready if no handler provided*/\n\n    return drv->ready_cb(drv);\n}\n\n/**\n * Open a file\n * @param file_p pointer to a lv_fs_file_t variable\n * @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt)\n * @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mode)\n{\n    file_p->drv    = NULL;\n    file_p->file_d = NULL;\n\n    if(path == NULL) return LV_FS_RES_INV_PARAM;\n\n    char letter = path[0];\n\n    file_p->drv = lv_fs_get_drv(letter);\n\n    if(file_p->drv == NULL) {\n        file_p->file_d = NULL;\n        return LV_FS_RES_NOT_EX;\n    }\n\n    if(file_p->drv->ready_cb != NULL) {\n        if(file_p->drv->ready_cb(file_p->drv) == false) {\n            file_p->drv    = NULL;\n            file_p->file_d = NULL;\n            return LV_FS_RES_HW_ERR;\n        }\n    }\n\n    file_p->file_d = lv_mem_alloc(file_p->drv->file_size);\n    lv_mem_assert(file_p->file_d);\n    if(file_p->file_d == NULL) {\n        file_p->drv = NULL;\n        return LV_FS_RES_OUT_OF_MEM; /* Out of memory */\n    }\n\n    if(file_p->drv->open_cb == NULL) {\n        return LV_FS_RES_NOT_IMP;\n    }\n\n    const char * real_path = lv_fs_get_real_path(path);\n    lv_fs_res_t res        = file_p->drv->open_cb(file_p->drv, file_p->file_d, real_path, mode);\n\n    if(res != LV_FS_RES_OK) {\n        lv_mem_free(file_p->file_d);\n        file_p->file_d = NULL;\n        file_p->drv    = NULL;\n    }\n\n    return res;\n}\n\n/**\n * Close an already opened file\n * @param file_p pointer to a lv_fs_file_t variable\n * @return  LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_close(lv_fs_file_t * file_p)\n{\n    if(file_p->drv == NULL) {\n        return LV_FS_RES_INV_PARAM;\n    }\n\n    if(file_p->drv->close_cb == NULL) {\n        return LV_FS_RES_NOT_IMP;\n    }\n\n    lv_fs_res_t res = file_p->drv->close_cb(file_p->drv, file_p->file_d);\n\n    lv_mem_free(file_p->file_d); /*Clean up*/\n    file_p->file_d = NULL;\n    file_p->drv    = NULL;\n    file_p->file_d = NULL;\n\n    return res;\n}\n\n/**\n * Delete a file\n * @param path path of the file to delete\n * @return  LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_remove(const char * path)\n{\n    if(path == NULL) return LV_FS_RES_INV_PARAM;\n    lv_fs_drv_t * drv = NULL;\n\n    char letter = path[0];\n\n    drv = lv_fs_get_drv(letter);\n    if(drv == NULL) return LV_FS_RES_NOT_EX;\n    if(drv->ready_cb != NULL) {\n        if(drv->ready_cb(drv) == false) return LV_FS_RES_HW_ERR;\n    }\n\n    if(drv->remove_cb == NULL) return LV_FS_RES_NOT_IMP;\n\n    const char * real_path = lv_fs_get_real_path(path);\n    lv_fs_res_t res        = drv->remove_cb(drv, real_path);\n\n    return res;\n}\n\n/**\n * Read from a file\n * @param file_p pointer to a lv_fs_file_t variable\n * @param buf pointer to a buffer where the read bytes are stored\n * @param btr Bytes To Read\n * @param br the number of real read bytes (Bytes Read). NULL if unused.\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_read(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t * br)\n{\n    if(br != NULL) *br = 0;\n    if(file_p->drv == NULL) return LV_FS_RES_INV_PARAM;\n    if(file_p->drv->read_cb == NULL) return LV_FS_RES_NOT_IMP;\n\n    uint32_t br_tmp = 0;\n    lv_fs_res_t res = file_p->drv->read_cb(file_p->drv, file_p->file_d, buf, btr, &br_tmp);\n    if(br != NULL) *br = br_tmp;\n\n    return res;\n}\n\n/**\n * Write into a file\n * @param file_p pointer to a lv_fs_file_t variable\n * @param buf pointer to a buffer with the bytes to write\n * @param btr Bytes To Write\n * @param br the number of real written bytes (Bytes Written). NULL if unused.\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_write(lv_fs_file_t * file_p, const void * buf, uint32_t btw, uint32_t * bw)\n{\n    if(bw != NULL) *bw = 0;\n\n    if(file_p->drv == NULL) {\n        return LV_FS_RES_INV_PARAM;\n    }\n\n    if(file_p->drv->write_cb == NULL) {\n        return LV_FS_RES_NOT_IMP;\n    }\n\n    uint32_t bw_tmp = 0;\n    lv_fs_res_t res = file_p->drv->write_cb(file_p->drv, file_p->file_d, buf, btw, &bw_tmp);\n    if(bw != NULL) *bw = bw_tmp;\n\n    return res;\n}\n\n/**\n * Set the position of the 'cursor' (read write pointer) in a file\n * @param file_p pointer to a lv_fs_file_t variable\n * @param pos the new position expressed in bytes index (0: start of file)\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos)\n{\n    if(file_p->drv == NULL) {\n        return LV_FS_RES_INV_PARAM;\n    }\n\n    if(file_p->drv->seek_cb == NULL) {\n        return LV_FS_RES_NOT_IMP;\n    }\n\n    lv_fs_res_t res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, pos);\n\n    return res;\n}\n\n/**\n * Give the position of the read write pointer\n * @param file_p pointer to a lv_fs_file_t variable\n * @param pos_p pointer to store the position of the read write pointer\n * @return LV_FS_RES_OK or any error from 'fs_res_t'\n */\nlv_fs_res_t lv_fs_tell(lv_fs_file_t * file_p, uint32_t * pos)\n{\n    if(file_p->drv == NULL) {\n        pos = 0;\n        return LV_FS_RES_INV_PARAM;\n    }\n\n    if(file_p->drv->tell_cb == NULL) {\n        pos = 0;\n        return LV_FS_RES_NOT_IMP;\n    }\n\n    lv_fs_res_t res = file_p->drv->tell_cb(file_p->drv, file_p->file_d, pos);\n\n    return res;\n}\n\n/**\n * Truncate the file size to the current position of the read write pointer\n * @param file_p pointer to an 'ufs_file_t' variable. (opened with lv_fs_open )\n * @return LV_FS_RES_OK: no error, the file is read\n *         any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_trunc(lv_fs_file_t * file_p)\n{\n    if(file_p->drv == NULL) {\n        return LV_FS_RES_INV_PARAM;\n    }\n\n    if(file_p->drv->tell_cb == NULL) {\n        return LV_FS_RES_NOT_IMP;\n    }\n\n    lv_fs_res_t res = file_p->drv->trunc_cb(file_p->drv, file_p->file_d);\n\n    return res;\n}\n/**\n * Give the size of a file bytes\n * @param file_p pointer to a lv_fs_file_t variable\n * @param size pointer to a variable to store the size\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_size(lv_fs_file_t * file_p, uint32_t * size)\n{\n    if(file_p->drv == NULL) {\n        return LV_FS_RES_INV_PARAM;\n    }\n\n    if(file_p->drv->size_cb == NULL) return LV_FS_RES_NOT_IMP;\n\n    if(size == NULL) return LV_FS_RES_INV_PARAM;\n\n    lv_fs_res_t res = file_p->drv->size_cb(file_p->drv, file_p->file_d, size);\n\n    return res;\n}\n\n/**\n * Rename a file\n * @param oldname path to the file\n * @param newname path with the new name\n * @return LV_FS_RES_OK or any error from 'fs_res_t'\n */\nlv_fs_res_t lv_fs_rename(const char * oldname, const char * newname)\n{\n    if(!oldname || !newname) return LV_FS_RES_INV_PARAM;\n\n    char letter = oldname[0];\n\n    lv_fs_drv_t * drv = lv_fs_get_drv(letter);\n\n    if(!drv) {\n        return LV_FS_RES_NOT_EX;\n    }\n\n    if(drv->ready_cb != NULL) {\n        if(drv->ready_cb(drv) == false) {\n            return LV_FS_RES_HW_ERR;\n        }\n    }\n\n    if(drv->rename_cb == NULL) return LV_FS_RES_NOT_IMP;\n\n    const char * old_real = lv_fs_get_real_path(oldname);\n    const char * new_real = lv_fs_get_real_path(newname);\n\n    lv_fs_res_t res = drv->rename_cb(drv, old_real, new_real);\n\n    return res;\n}\n\n/**\n * Initialize a 'fs_read_dir_t' variable for directory reading\n * @param rddir_p pointer to a 'fs_read_dir_t' variable\n * @param path path to a directory\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path)\n{\n    if(path == NULL) return LV_FS_RES_INV_PARAM;\n\n    char letter = path[0];\n\n    rddir_p->drv = lv_fs_get_drv(letter);\n\n    if(rddir_p->drv == NULL) {\n        rddir_p->dir_d = NULL;\n        return LV_FS_RES_NOT_EX;\n    }\n\n    rddir_p->dir_d = lv_mem_alloc(rddir_p->drv->rddir_size);\n    lv_mem_assert(rddir_p->dir_d);\n    if(rddir_p->dir_d == NULL) {\n        rddir_p->dir_d = NULL;\n        return LV_FS_RES_OUT_OF_MEM; /* Out of memory */\n    }\n\n    if(rddir_p->drv->dir_open_cb == NULL) {\n        return LV_FS_RES_NOT_IMP;\n    }\n\n    const char * real_path = lv_fs_get_real_path(path);\n\n    lv_fs_res_t res = rddir_p->drv->dir_open_cb(rddir_p->drv, rddir_p->dir_d, real_path);\n\n    return res;\n}\n\n/**\n * Read the next filename form a directory.\n * The name of the directories will begin with '/'\n * @param rddir_p pointer to an initialized 'fs_read_dir_t' variable\n * @param fn pointer to a buffer to store the filename\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_dir_read(lv_fs_dir_t * rddir_p, char * fn)\n{\n    if(rddir_p->drv == NULL || rddir_p->dir_d == NULL) {\n        fn[0] = '\\0';\n        return LV_FS_RES_INV_PARAM;\n    }\n\n    if(rddir_p->drv->dir_read_cb == NULL) {\n        return LV_FS_RES_NOT_IMP;\n    }\n\n    lv_fs_res_t res = rddir_p->drv->dir_read_cb(rddir_p->drv, rddir_p->dir_d, fn);\n\n    return res;\n}\n\n/**\n * Close the directory reading\n * @param rddir_p pointer to an initialized 'fs_read_dir_t' variable\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_dir_close(lv_fs_dir_t * rddir_p)\n{\n    if(rddir_p->drv == NULL || rddir_p->dir_d == NULL) {\n        return LV_FS_RES_INV_PARAM;\n    }\n\n    lv_fs_res_t res;\n\n    if(rddir_p->drv->dir_close_cb == NULL) {\n        res = LV_FS_RES_NOT_IMP;\n    } else {\n        res = rddir_p->drv->dir_close_cb(rddir_p->drv, rddir_p->dir_d);\n    }\n\n    lv_mem_free(rddir_p->dir_d); /*Clean up*/\n    rddir_p->dir_d = NULL;\n    rddir_p->drv   = NULL;\n    rddir_p->dir_d = NULL;\n\n    return res;\n}\n\n/**\n * Get the free and total size of a driver in kB\n * @param letter the driver letter\n * @param total_p pointer to store the total size [kB]\n * @param free_p pointer to store the free size_cb [kB]\n * @return LV_FS_RES_OK or any error from lv_fs_res_t enum\n */\nlv_fs_res_t lv_fs_free_space(char letter, uint32_t * total_p, uint32_t * free_p)\n{\n    lv_fs_drv_t * drv = lv_fs_get_drv(letter);\n\n    if(drv == NULL) {\n        return LV_FS_RES_INV_PARAM;\n    }\n\n    lv_fs_res_t res;\n\n    if(drv->free_space_cb == NULL) {\n        res = LV_FS_RES_NOT_IMP;\n    } else {\n        uint32_t total_tmp = 0;\n        uint32_t free_tmp  = 0;\n        res                = drv->free_space_cb(drv, &total_tmp, &free_tmp);\n\n        if(total_p != NULL) *total_p = total_tmp;\n        if(free_p != NULL) *free_p = free_tmp;\n    }\n\n    return res;\n}\n\n/**\n * Initialize a file system driver with default values.\n * It is used to surly have known values in the fields ant not memory junk.\n * After it you can set the fields.\n * @param drv pointer to driver variable to initialize\n */\nvoid lv_fs_drv_init(lv_fs_drv_t * drv)\n{\n    memset(drv, 0, sizeof(lv_fs_drv_t));\n}\n\n/**\n * Add a new drive\n * @param drv_p pointer to an lv_fs_drv_t structure which is inited with the\n * corresponding function pointers. The data will be copied so the variable can be local.\n */\nvoid lv_fs_drv_register(lv_fs_drv_t * drv_p)\n{\n    /*Save the new driver*/\n    lv_fs_drv_t * new_drv;\n    new_drv = lv_ll_ins_head(&LV_GC_ROOT(_lv_drv_ll));\n    lv_mem_assert(new_drv);\n    if(new_drv == NULL) return;\n\n    memcpy(new_drv, drv_p, sizeof(lv_fs_drv_t));\n}\n\n/**\n * Give a pointer to a driver from its letter\n * @param letter the driver letter\n * @return pointer to a driver or NULL if not found\n */\nlv_fs_drv_t * lv_fs_get_drv(char letter)\n{\n    lv_fs_drv_t * drv;\n\n    LV_LL_READ(LV_GC_ROOT(_lv_drv_ll), drv)\n    {\n        if(drv->letter == letter) {\n            return drv;\n        }\n    }\n\n    return NULL;\n}\n/**\n * Fill a buffer with the letters of existing drivers\n * @param buf buffer to store the letters ('\\0' added after the last letter)\n * @return the buffer\n */\nchar * lv_fs_get_letters(char * buf)\n{\n    lv_fs_drv_t * drv;\n    uint8_t i = 0;\n\n    LV_LL_READ(LV_GC_ROOT(_lv_drv_ll), drv)\n    {\n        buf[i] = drv->letter;\n        i++;\n    }\n\n    buf[i] = '\\0';\n\n    return buf;\n}\n\n/**\n * Return with the extension of the filename\n * @param fn string with a filename\n * @return pointer to the beginning extension or empty string if no extension\n */\nconst char * lv_fs_get_ext(const char * fn)\n{\n    uint16_t i;\n    for(i = strlen(fn); i > 0; i--) {\n        if(fn[i] == '.') {\n            return &fn[i + 1];\n        } else if(fn[i] == '/' || fn[i] == '\\\\') {\n            return \"\"; /*No extension if a '\\' or '/' found*/\n        }\n    }\n\n    return \"\"; /*Empty string if no '.' in the file name. */\n}\n\n/**\n * Step up one level\n * @param path pointer to a file name\n * @return the truncated file name\n */\nchar * lv_fs_up(char * path)\n{\n    uint16_t len = strlen(path);\n    if(len == 0) return path;\n\n    len--; /*Go before the trailing '\\0'*/\n\n    /*Ignore trailing '/' or '\\'*/\n    while(path[len] == '/' || path[len] == '\\\\') {\n        path[len] = '\\0';\n        if(len > 0)\n            len--;\n        else\n            return path;\n    }\n\n    uint16_t i;\n    for(i = len; i > 0; i--) {\n        if(path[i] == '/' || path[i] == '\\\\') break;\n    }\n\n    if(i > 0) path[i] = '\\0';\n\n    return path;\n}\n\n/**\n * Get the last element of a path (e.g. U:/folder/file -> file)\n * @param path a character sting with the path to search in\n * @return pointer to the beginning of the last element in the path\n */\nconst char * lv_fs_get_last(const char * path)\n{\n    uint16_t len = strlen(path);\n    if(len == 0) return path;\n\n    len--; /*Go before the trailing '\\0'*/\n\n    /*Ignore trailing '/' or '\\'*/\n    while(path[len] == '/' || path[len] == '\\\\') {\n        if(len > 0)\n            len--;\n        else\n            return path;\n    }\n\n    uint16_t i;\n    for(i = len; i > 0; i--) {\n        if(path[i] == '/' || path[i] == '\\\\') break;\n    }\n\n    /*No '/' or '\\' in the path so return with path itself*/\n    if(i == 0) return path;\n\n    return &path[i + 1];\n}\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Leave the driver letters and / or \\ letters from beginning of the path\n * @param path path string (E.g. S:/folder/file.txt)\n * @return pointer to the beginning of the real path (E.g. folder/file.txt)\n */\nstatic const char * lv_fs_get_real_path(const char * path)\n{\n    /* Example path: \"S:/folder/file.txt\"\n     * Leave the letter and the : / \\ characters*/\n\n    path++; /*Ignore the driver letter*/\n\n    while(*path != '\\0') {\n        if(*path == ':' || *path == '\\\\' || *path == '/') {\n            path++;\n        } else {\n            break;\n        }\n    }\n\n    return path;\n}\n\n#endif /*LV_USE_FILESYSTEM*/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_misc/lv_gc.c",
    "content": "/**\n * @file lv_gc.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n\n#include \"libs/lvgl/lv_misc/lv_gc.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n#if(!defined(LV_ENABLE_GC)) || LV_ENABLE_GC == 0\nLV_ROOTS\n#endif /* LV_ENABLE_GC */\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_misc/lv_ll.c",
    "content": "/**\n * @file lv_ll.c\n * Handle linked lists.\n * The nodes are dynamically allocated by the 'lv_mem' module,\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include <stdint.h>\n#include <string.h>\n\n#include \"libs/lvgl/lv_misc/lv_ll.h\"\n#include \"libs/lvgl/lv_misc/lv_mem.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LL_NODE_META_SIZE (sizeof(lv_ll_node_t *) + sizeof(lv_ll_node_t *))\n#define LL_PREV_P_OFFSET(ll_p) (ll_p->n_size)\n#define LL_NEXT_P_OFFSET(ll_p) (ll_p->n_size + sizeof(lv_ll_node_t *))\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic void node_set_prev(lv_ll_t * ll_p, lv_ll_node_t * act, lv_ll_node_t * prev);\nstatic void node_set_next(lv_ll_t * ll_p, lv_ll_node_t * act, lv_ll_node_t * next);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Initialize linked list\n * @param ll_dsc pointer to ll_dsc variable\n * @param node_size the size of 1 node in bytes\n */\nvoid lv_ll_init(lv_ll_t * ll_p, uint32_t node_size)\n{\n    ll_p->head = NULL;\n    ll_p->tail = NULL;\n#ifdef LV_MEM_ENV64\n    /*Round the size up to 8*/\n    if(node_size & 0x7) {\n        node_size = node_size & (~0x7);\n        node_size += 8;\n    }\n#else\n    /*Round the size up to 4*/\n    if(node_size & 0x3) {\n        node_size = node_size & (~0x3);\n        node_size += 4;\n    }\n#endif\n\n    ll_p->n_size = node_size;\n}\n\n/**\n * Add a new head to a linked list\n * @param ll_p pointer to linked list\n * @return pointer to the new head\n */\nvoid * lv_ll_ins_head(lv_ll_t * ll_p)\n{\n    lv_ll_node_t * n_new;\n\n    n_new = lv_mem_alloc(ll_p->n_size + LL_NODE_META_SIZE);\n\n    if(n_new != NULL) {\n        node_set_prev(ll_p, n_new, NULL);       /*No prev. before the new head*/\n        node_set_next(ll_p, n_new, ll_p->head); /*After new comes the old head*/\n\n        if(ll_p->head != NULL) { /*If there is old head then before it goes the new*/\n            node_set_prev(ll_p, ll_p->head, n_new);\n        }\n\n        ll_p->head = n_new;      /*Set the new head in the dsc.*/\n        if(ll_p->tail == NULL) { /*If there is no tail (1. node) set the tail too*/\n            ll_p->tail = n_new;\n        }\n    }\n\n    return n_new;\n}\n\n/**\n * Insert a new node in front of the n_act node\n * @param ll_p pointer to linked list\n * @param n_act pointer a node\n * @return pointer to the new head\n */\nvoid * lv_ll_ins_prev(lv_ll_t * ll_p, void * n_act)\n{\n    lv_ll_node_t * n_new;\n    lv_ll_node_t * n_prev;\n\n    if(NULL == ll_p || NULL == n_act) return NULL;\n\n    if(lv_ll_get_head(ll_p) == n_act) {\n        n_new = lv_ll_ins_head(ll_p);\n        if(n_new == NULL) return NULL;\n    } else {\n        n_new = lv_mem_alloc(ll_p->n_size + LL_NODE_META_SIZE);\n        if(n_new == NULL) return NULL;\n\n        n_prev = lv_ll_get_prev(ll_p, n_act);\n        node_set_next(ll_p, n_prev, n_new);\n        node_set_prev(ll_p, n_new, n_prev);\n        node_set_prev(ll_p, n_act, n_new);\n        node_set_next(ll_p, n_new, n_act);\n    }\n\n    return n_new;\n}\n\n/**\n * Add a new tail to a linked list\n * @param ll_p pointer to linked list\n * @return pointer to the new tail\n */\nvoid * lv_ll_ins_tail(lv_ll_t * ll_p)\n{\n    lv_ll_node_t * n_new;\n\n    n_new = lv_mem_alloc(ll_p->n_size + LL_NODE_META_SIZE);\n    if(n_new == NULL) return NULL;\n\n    if(n_new != NULL) {\n        node_set_next(ll_p, n_new, NULL);       /*No next after the new tail*/\n        node_set_prev(ll_p, n_new, ll_p->tail); /*The prev. before new is tho old tail*/\n        if(ll_p->tail != NULL) {                /*If there is old tail then the new comes after it*/\n            node_set_next(ll_p, ll_p->tail, n_new);\n        }\n\n        ll_p->tail = n_new;      /*Set the new tail in the dsc.*/\n        if(ll_p->head == NULL) { /*If there is no head (1. node) set the head too*/\n            ll_p->head = n_new;\n        }\n    }\n\n    return n_new;\n}\n\n/**\n * Remove the node 'node_p' from 'll_p' linked list.\n * It does not free the the memory of node.\n * @param ll_p pointer to the linked list of 'node_p'\n * @param node_p pointer to node in 'll_p' linked list\n */\nvoid lv_ll_rem(lv_ll_t * ll_p, void * node_p)\n{\n    if(lv_ll_get_head(ll_p) == node_p) {\n        /*The new head will be the node after 'n_act'*/\n        ll_p->head = lv_ll_get_next(ll_p, node_p);\n        if(ll_p->head == NULL) {\n            ll_p->tail = NULL;\n        } else {\n            node_set_prev(ll_p, ll_p->head, NULL);\n        }\n    } else if(lv_ll_get_tail(ll_p) == node_p) {\n        /*The new tail will be the  node before 'n_act'*/\n        ll_p->tail = lv_ll_get_prev(ll_p, node_p);\n        if(ll_p->tail == NULL) {\n            ll_p->head = NULL;\n        } else {\n            node_set_next(ll_p, ll_p->tail, NULL);\n        }\n    } else {\n        lv_ll_node_t * n_prev = lv_ll_get_prev(ll_p, node_p);\n        lv_ll_node_t * n_next = lv_ll_get_next(ll_p, node_p);\n\n        node_set_next(ll_p, n_prev, n_next);\n        node_set_prev(ll_p, n_next, n_prev);\n    }\n}\n\n/**\n * Remove and free all elements from a linked list. The list remain valid but become empty.\n * @param ll_p pointer to linked list\n */\nvoid lv_ll_clear(lv_ll_t * ll_p)\n{\n    void * i;\n    void * i_next;\n\n    i      = lv_ll_get_head(ll_p);\n    i_next = NULL;\n\n    while(i != NULL) {\n        i_next = lv_ll_get_next(ll_p, i);\n\n        lv_ll_rem(ll_p, i);\n        lv_mem_free(i);\n\n        i = i_next;\n    }\n}\n\n/**\n * Move a node to a new linked list\n * @param ll_ori_p pointer to the original (old) linked list\n * @param ll_new_p pointer to the new linked list\n * @param node pointer to a node\n * @param head true: be the head in the new list\n *             false be the head in the new list\n */\nvoid lv_ll_chg_list(lv_ll_t * ll_ori_p, lv_ll_t * ll_new_p, void * node, bool head)\n{\n    lv_ll_rem(ll_ori_p, node);\n\n    if(head) {\n        /*Set node as head*/\n        node_set_prev(ll_new_p, node, NULL);\n        node_set_next(ll_new_p, node, ll_new_p->head);\n\n        if(ll_new_p->head != NULL) { /*If there is old head then before it goes the new*/\n            node_set_prev(ll_new_p, ll_new_p->head, node);\n        }\n\n        ll_new_p->head = node;       /*Set the new head in the dsc.*/\n        if(ll_new_p->tail == NULL) { /*If there is no tail (first node) set the tail too*/\n            ll_new_p->tail = node;\n        }\n    } else {\n        /*Set node as tail*/\n        node_set_prev(ll_new_p, node, ll_new_p->tail);\n        node_set_next(ll_new_p, node, NULL);\n\n        if(ll_new_p->tail != NULL) { /*If there is old tail then after it goes the new*/\n            node_set_next(ll_new_p, ll_new_p->tail, node);\n        }\n\n        ll_new_p->tail = node;       /*Set the new tail in the dsc.*/\n        if(ll_new_p->head == NULL) { /*If there is no head (first node) set the head too*/\n            ll_new_p->head = node;\n        }\n    }\n}\n\n/**\n * Return with head node of the linked list\n * @param ll_p pointer to linked list\n * @return pointer to the head of 'll_p'\n */\nvoid * lv_ll_get_head(const lv_ll_t * ll_p)\n{\n    void * head = NULL;\n\n    if(ll_p != NULL) {\n        head = ll_p->head;\n    }\n\n    return head;\n}\n\n/**\n * Return with tail node of the linked list\n * @param ll_p pointer to linked list\n * @return pointer to the head of 'll_p'\n */\nvoid * lv_ll_get_tail(const lv_ll_t * ll_p)\n{\n    void * tail = NULL;\n\n    if(ll_p != NULL) {\n        tail = ll_p->tail;\n    }\n\n    return tail;\n}\n\n/**\n * Return with the pointer of the next node after 'n_act'\n * @param ll_p pointer to linked list\n * @param n_act pointer a node\n * @return pointer to the next node\n */\nvoid * lv_ll_get_next(const lv_ll_t * ll_p, const void * n_act)\n{\n    void * next = NULL;\n\n    if(ll_p != NULL) {\n        const lv_ll_node_t * n_act_d = n_act;\n        memcpy(&next, n_act_d + LL_NEXT_P_OFFSET(ll_p), sizeof(void *));\n    }\n\n    return next;\n}\n\n/**\n * Return with the pointer of the previous node after 'n_act'\n * @param ll_p pointer to linked list\n * @param n_act pointer a node\n * @return pointer to the previous node\n */\nvoid * lv_ll_get_prev(const lv_ll_t * ll_p, const void * n_act)\n{\n    void * prev = NULL;\n\n    if(ll_p != NULL) {\n        const lv_ll_node_t * n_act_d = n_act;\n        memcpy(&prev, n_act_d + LL_PREV_P_OFFSET(ll_p), sizeof(void *));\n    }\n\n    return prev;\n}\n\n/**\n * Return the length of the linked list.\n * @param ll_p pointer to linked list\n * @return length of the linked list\n */\nuint32_t lv_ll_get_len(const lv_ll_t * ll_p)\n{\n    uint32_t len = 0;\n    void * node;\n\n    for(node = lv_ll_get_head(ll_p); node != NULL; node = lv_ll_get_next(ll_p, node)) {\n        len++;\n    }\n\n    return len;\n}\n\nvoid lv_ll_swap(lv_ll_t * ll_p, void * n1_p, void * n2_p)\n{\n    (void)(ll_p);\n    (void)(n1_p);\n    (void)(n2_p);\n    /*TODO*/\n}\n\n/**\n * Move a nodw before an other node in the same linked list\n * @param ll_p pointer to a linked list\n * @param n_act pointer to node to move\n * @param n_after pointer to a node which should be after `n_act`\n */\nvoid lv_ll_move_before(lv_ll_t * ll_p, void * n_act, void * n_after)\n{\n    if(n_act == n_after) return; /*Can't move before itself*/\n\n    void * n_before;\n    if(n_after != NULL)\n        n_before = lv_ll_get_prev(ll_p, n_after);\n    else\n        n_before = lv_ll_get_tail(ll_p); /*if `n_after` is NULL `n_act` should be the new tail*/\n\n    if(n_act == n_before) return; /*Already before `n_after`*/\n\n    /*It's much easier to remove from the list and add again*/\n    lv_ll_rem(ll_p, n_act);\n\n    /*Add again by setting the prev. and next nodes*/\n    node_set_next(ll_p, n_before, n_act);\n    node_set_prev(ll_p, n_act, n_before);\n    node_set_prev(ll_p, n_after, n_act);\n    node_set_next(ll_p, n_act, n_after);\n\n    /*If `n_act` was moved before NULL then it become the new tail*/\n    if(n_after == NULL) ll_p->tail = n_act;\n\n    /*If `n_act` was moved before `NULL` then it's the new head*/\n    if(n_before == NULL) ll_p->head = n_act;\n}\n\n/**\n * Check if a linked list is empty\n * @param ll_p pointer to a linked list\n * @return true: the linked list is empty; false: not empty\n */\nbool lv_ll_is_empty(lv_ll_t * ll_p)\n{\n    if(ll_p == NULL) return true;\n\n    if(ll_p->head == NULL && ll_p->tail == NULL) return true;\n\n    return false;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Set the 'pervious node pointer' of a node\n * @param ll_p pointer to linked list\n * @param act pointer to a node which prev. node pointer should be set\n * @param prev pointer to a node which should be the previous node before 'act'\n */\nstatic void node_set_prev(lv_ll_t * ll_p, lv_ll_node_t * act, lv_ll_node_t * prev)\n{\n    if(act == NULL) return; /*Can't set the prev node of `NULL`*/\n\n    uint32_t node_p_size = sizeof(lv_ll_node_t *);\n    if(prev)\n        memcpy(act + LL_PREV_P_OFFSET(ll_p), &prev, node_p_size);\n    else\n        memset(act + LL_PREV_P_OFFSET(ll_p), 0, node_p_size);\n}\n\n/**\n * Set the 'next node pointer' of a node\n * @param ll_p pointer to linked list\n * @param act pointer to a node which next node pointer should be set\n * @param next pointer to a node which should be the next node before 'act'\n */\nstatic void node_set_next(lv_ll_t * ll_p, lv_ll_node_t * act, lv_ll_node_t * next)\n{\n    if(act == NULL) return; /*Can't set the next node of `NULL`*/\n\n    uint32_t node_p_size = sizeof(lv_ll_node_t *);\n    if(next)\n        memcpy(act + LL_NEXT_P_OFFSET(ll_p), &next, node_p_size);\n    else\n        memset(act + LL_NEXT_P_OFFSET(ll_p), 0, node_p_size);\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_misc/lv_log.c",
    "content": "/**\n * @file lv_log.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_misc/lv_log.h\"\n#if LV_USE_LOG\n\n#if LV_LOG_PRINTF\n#include <stdio.h>\n#endif\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_log_print_g_cb_t custom_print_cb;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Register custom print/write function to call when a log is added.\n * It can format its \"File path\", \"Line number\" and \"Description\" as required\n * and send the formatted log message to a consol or serial port.\n * @param print_cb a function pointer to print a log\n */\nvoid lv_log_register_print_cb(lv_log_print_g_cb_t print_cb)\n{\n    custom_print_cb = print_cb;\n}\n\n/**\n * Add a log\n * @param level the level of log. (From `lv_log_level_t` enum)\n * @param file name of the file when the log added\n * @param line line number in the source code where the log added\n * @param dsc description of the log\n */\nvoid lv_log_add(lv_log_level_t level, const char * file, int line, const char * dsc)\n{\n    if(level >= _LV_LOG_LEVEL_NUM) return; /*Invalid level*/\n\n    if(level >= LV_LOG_LEVEL) {\n\n#if LV_LOG_PRINTF\n        static const char * lvl_prefix[] = {\"Trace\", \"Info\", \"Warn\", \"Error\"};\n        printf(\"%s: %s \\t(%s #%d)\\n\", lvl_prefix[level], dsc, file, line);\n#else\n        if(custom_print_cb) custom_print_cb(level, file, line, dsc);\n#endif\n    }\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n#endif /*LV_USE_LOG*/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_misc/lv_math.c",
    "content": "/**\n * @file lv_math.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n#include \"utils/types.h\"\n#include <stdlib.h>\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic int16_t sin0_90_table[] = {\n    0,     572,   1144,  1715,  2286,  2856,  3425,  3993,  4560,  5126,  5690,  6252,  6813,  7371,  7927,  8481,\n    9032,  9580,  10126, 10668, 11207, 11743, 12275, 12803, 13328, 13848, 14364, 14876, 15383, 15886, 16383, 16876,\n    17364, 17846, 18323, 18794, 19260, 19720, 20173, 20621, 21062, 21497, 21925, 22347, 22762, 23170, 23571, 23964,\n    24351, 24730, 25101, 25465, 25821, 26169, 26509, 26841, 27165, 27481, 27788, 28087, 28377, 28659, 28932, 29196,\n    29451, 29697, 29934, 30162, 30381, 30591, 30791, 30982, 31163, 31335, 31498, 31650, 31794, 31927, 32051, 32165,\n    32269, 32364, 32448, 32523, 32587, 32642, 32687, 32722, 32747, 32762, 32767};\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Return with sinus of an angle\n * @param angle\n * @return sinus of 'angle'. sin(-90) = -32767, sin(90) = 32767\n */\nint16_t lv_trigo_sin(int16_t angle)\n{\n    int16_t ret = 0;\n    angle       = angle % 360;\n\n    if(angle < 0) angle = 360 + angle;\n\n    if(angle < 90) {\n        ret = sin0_90_table[angle];\n    } else if(angle >= 90 && angle < 180) {\n        angle = 180 - angle;\n        ret   = sin0_90_table[angle];\n    } else if(angle >= 180 && angle < 270) {\n        angle = angle - 180;\n        ret   = -sin0_90_table[angle];\n    } else { /*angle >=270*/\n        angle = 360 - angle;\n        ret   = -sin0_90_table[angle];\n    }\n\n    return ret;\n}\n\n/**\n * Calculate a value of a Cubic Bezier function.\n * @param t time in range of [0..LV_BEZIER_VAL_MAX]\n * @param u0 start values in range of [0..LV_BEZIER_VAL_MAX]\n * @param u1 control value 1 values in range of [0..LV_BEZIER_VAL_MAX]\n * @param u2 control value 2 in range of [0..LV_BEZIER_VAL_MAX]\n * @param u3 end values in range of [0..LV_BEZIER_VAL_MAX]\n * @return the value calculated from the given parameters in range of [0..LV_BEZIER_VAL_MAX]\n */\nint32_t lv_bezier3(uint32_t t, int32_t u0, int32_t u1, int32_t u2, int32_t u3)\n{\n    uint32_t t_rem  = 1024 - t;\n    uint32_t t_rem2 = (t_rem * t_rem) >> 10;\n    uint32_t t_rem3 = (t_rem2 * t_rem) >> 10;\n    uint32_t t2     = (t * t) >> 10;\n    uint32_t t3     = (t2 * t) >> 10;\n\n    uint32_t v1 = ((uint32_t)t_rem3 * u0) >> 10;\n    uint32_t v2 = ((uint32_t)3 * t_rem2 * t * u1) >> 20;\n    uint32_t v3 = ((uint32_t)3 * t_rem * t2 * u2) >> 20;\n    uint32_t v4 = ((uint32_t)t3 * u3) >> 10;\n\n    return v1 + v2 + v3 + v4;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_misc/lv_mem.c",
    "content": "/**\n * @file lv_mem.c\n * General and portable implementation of malloc and free.\n * The dynamic memory monitoring is also supported.\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_misc/lv_mem.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n#include <string.h>\n\n#if LV_MEM_CUSTOM != 0\n#include LV_MEM_CUSTOM_INCLUDE\n#endif\n\n/*********************\n *      DEFINES\n *********************/\n/*Add memory junk on alloc (0xaa) and free(0xbb) (just for testing purposes)*/\n#define LV_MEM_ADD_JUNK 1\n\n#ifdef LV_MEM_ENV64\n#define MEM_UNIT uint64_t\n#else\n#define MEM_UNIT uint32_t\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n#if LV_ENABLE_GC == 0 /*gc custom allocations must not include header*/\n\n/*The size of this union must be 4 bytes (uint32_t)*/\ntypedef union\n{\n    struct\n    {\n        MEM_UNIT used : 1;    /* 1: if the entry is used*/\n        MEM_UNIT d_size : 31; /* Size off the data (1 means 4 bytes)*/\n    } s;\n    MEM_UNIT header; /* The header (used + d_size)*/\n} lv_mem_header_t;\n\ntypedef struct\n{\n    lv_mem_header_t header;\n    uint8_t first_data; /*First data byte in the allocated data (Just for easily create a pointer)*/\n} lv_mem_ent_t;\n\n#endif /* LV_ENABLE_GC */\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n#if LV_MEM_CUSTOM == 0\nstatic lv_mem_ent_t * ent_get_next(lv_mem_ent_t * act_e);\nstatic void * ent_alloc(lv_mem_ent_t * e, uint32_t size);\nstatic void ent_trunc(lv_mem_ent_t * e, uint32_t size);\n#endif\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n#if LV_MEM_CUSTOM == 0\nstatic uint8_t * work_mem;\n#endif\n\nstatic uint32_t zero_mem; /*Give the address of this variable if 0 byte should be allocated*/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Initiaiize the dyn_mem module (work memory and other variables)\n */\nvoid lv_mem_init(void)\n{\n#if LV_MEM_CUSTOM == 0\n\n#if LV_MEM_ADR == 0\n    /*Allocate a large array to store the dynamically allocated data*/\n    static LV_MEM_ATTR MEM_UNIT work_mem_int[LV_MEM_SIZE / sizeof(MEM_UNIT)];\n    work_mem = (uint8_t *)work_mem_int;\n#else\n    work_mem = (uint8_t *)LV_MEM_ADR;\n#endif\n\n    lv_mem_ent_t * full = (lv_mem_ent_t *)work_mem;\n    full->header.s.used = 0;\n    /*The total mem size id reduced by the first header and the close patterns */\n    full->header.s.d_size = LV_MEM_SIZE - sizeof(lv_mem_header_t);\n#endif\n}\n\n/**\n * Allocate a memory dynamically\n * @param size size of the memory to allocate in bytes\n * @return pointer to the allocated memory\n */\nvoid * lv_mem_alloc(uint32_t size)\n{\n    if(size == 0) {\n        return &zero_mem;\n    }\n\n#ifdef LV_MEM_ENV64\n    /*Round the size up to 8*/\n    if(size & 0x7) {\n        size = size & (~0x7);\n        size += 8;\n    }\n#else\n    /*Round the size up to 4*/\n    if(size & 0x3) {\n        size = size & (~0x3);\n        size += 4;\n    }\n#endif\n    void * alloc = NULL;\n\n#if LV_MEM_CUSTOM == 0\n    /*Use the built-in allocators*/\n    lv_mem_ent_t * e = NULL;\n\n    /* Search for a appropriate entry*/\n    do {\n        /* Get the next entry*/\n        e = ent_get_next(e);\n\n        /*If there is next entry then try to allocate there*/\n        if(e != NULL) {\n            alloc = ent_alloc(e, size);\n        }\n        /* End if there is not next entry OR the alloc. is successful*/\n    } while(e != NULL && alloc == NULL);\n\n#else\n/*Use custom, user defined malloc function*/\n#if LV_ENABLE_GC == 1 /*gc must not include header*/\n    alloc = LV_MEM_CUSTOM_ALLOC(size);\n#else                 /* LV_ENABLE_GC */\n    /*Allocate a header too to store the size*/\n    alloc = LV_MEM_CUSTOM_ALLOC(size + sizeof(lv_mem_header_t));\n    if(alloc != NULL) {\n        ((lv_mem_ent_t *)alloc)->header.s.d_size = size;\n        ((lv_mem_ent_t *)alloc)->header.s.used   = 1;\n\n        alloc = &((lv_mem_ent_t *)alloc)->first_data;\n    }\n#endif                /* LV_ENABLE_GC */\n#endif                /* LV_MEM_CUSTOM */\n\n#if LV_MEM_ADD_JUNK\n    if(alloc != NULL) memset(alloc, 0xaa, size);\n#endif\n\n    if(alloc == NULL) LV_LOG_WARN(\"Couldn't allocate memory\");\n\n    return alloc;\n}\n\n/**\n * Free an allocated data\n * @param data pointer to an allocated memory\n */\nvoid lv_mem_free(const void * data)\n{\n    if(data == &zero_mem) return;\n    if(data == NULL) return;\n\n#if LV_MEM_ADD_JUNK\n    memset((void *)data, 0xbb, lv_mem_get_size(data));\n#endif\n\n#if LV_ENABLE_GC == 0\n    /*e points to the header*/\n    lv_mem_ent_t * e = (lv_mem_ent_t *)((uint8_t *)data - sizeof(lv_mem_header_t));\n    e->header.s.used = 0;\n#endif\n\n#if LV_MEM_CUSTOM == 0\n#if LV_MEM_AUTO_DEFRAG\n    /* Make a simple defrag.\n     * Join the following free entries after this*/\n    lv_mem_ent_t * e_next;\n    e_next = ent_get_next(e);\n    while(e_next != NULL) {\n        if(e_next->header.s.used == 0) {\n            e->header.s.d_size += e_next->header.s.d_size + sizeof(e->header);\n        } else {\n            break;\n        }\n        e_next = ent_get_next(e_next);\n    }\n#endif\n#else /*Use custom, user defined free function*/\n#if LV_ENABLE_GC == 0\n    LV_MEM_CUSTOM_FREE(e);\n#else\n    LV_MEM_CUSTOM_FREE((void *)data);\n#endif /*LV_ENABLE_GC*/\n#endif\n}\n\n/**\n * Reallocate a memory with a new size. The old content will be kept.\n * @param data pointer to an allocated memory.\n * Its content will be copied to the new memory block and freed\n * @param new_size the desired new size in byte\n * @return pointer to the new memory\n */\n\n#if LV_ENABLE_GC == 0\n\nvoid * lv_mem_realloc(void * data_p, uint32_t new_size)\n{\n    /*data_p could be previously freed pointer (in this case it is invalid)*/\n    if(data_p != NULL) {\n        lv_mem_ent_t * e = (lv_mem_ent_t *)((uint8_t *)data_p - sizeof(lv_mem_header_t));\n        if(e->header.s.used == 0) {\n            data_p = NULL;\n        }\n    }\n\n    uint32_t old_size = lv_mem_get_size(data_p);\n    if(old_size == new_size) return data_p; /*Also avoid reallocating the same memory*/\n\n#if LV_MEM_CUSTOM == 0\n    /* Truncate the memory if the new size is smaller. */\n    if(new_size < old_size) {\n        lv_mem_ent_t * e = (lv_mem_ent_t *)((uint8_t *)data_p - sizeof(lv_mem_header_t));\n        ent_trunc(e, new_size);\n        return &e->first_data;\n    }\n#endif\n\n    void * new_p;\n    new_p = lv_mem_alloc(new_size);\n\n    if(new_p != NULL && data_p != NULL) {\n        /*Copy the old data to the new. Use the smaller size*/\n        if(old_size != 0) {\n            memcpy(new_p, data_p, LV_MATH_MIN(new_size, old_size));\n            lv_mem_free(data_p);\n        }\n    }\n\n    if(new_p == NULL) LV_LOG_WARN(\"Couldn't allocate memory\");\n\n    return new_p;\n}\n\n#else /* LV_ENABLE_GC */\n\nvoid * lv_mem_realloc(void * data_p, uint32_t new_size)\n{\n    void * new_p = LV_MEM_CUSTOM_REALLOC(data_p, new_size);\n    if(new_p == NULL) LV_LOG_WARN(\"Couldn't allocate memory\");\n    return new_p;\n}\n\n#endif /* lv_enable_gc */\n\n/**\n * Join the adjacent free memory blocks\n */\nvoid lv_mem_defrag(void)\n{\n#if LV_MEM_CUSTOM == 0\n    lv_mem_ent_t * e_free;\n    lv_mem_ent_t * e_next;\n    e_free = ent_get_next(NULL);\n\n    while(1) {\n        /*Search the next free entry*/\n        while(e_free != NULL) {\n            if(e_free->header.s.used != 0) {\n                e_free = ent_get_next(e_free);\n            } else {\n                break;\n            }\n        }\n\n        if(e_free == NULL) return;\n\n        /*Joint the following free entries to the free*/\n        e_next = ent_get_next(e_free);\n        while(e_next != NULL) {\n            if(e_next->header.s.used == 0) {\n                e_free->header.s.d_size += e_next->header.s.d_size + sizeof(e_next->header);\n            } else {\n                break;\n            }\n\n            e_next = ent_get_next(e_next);\n        }\n\n        if(e_next == NULL) return;\n\n        /*Continue from the lastly checked entry*/\n        e_free = e_next;\n    }\n#endif\n}\n\n/**\n * Give information about the work memory of dynamic allocation\n * @param mon_p pointer to a dm_mon_p variable,\n *              the result of the analysis will be stored here\n */\nvoid lv_mem_monitor(lv_mem_monitor_t * mon_p)\n{\n    /*Init the data*/\n    memset(mon_p, 0, sizeof(lv_mem_monitor_t));\n#if LV_MEM_CUSTOM == 0\n    lv_mem_ent_t * e;\n    e = NULL;\n\n    e = ent_get_next(e);\n\n    while(e != NULL) {\n        if(e->header.s.used == 0) {\n            mon_p->free_cnt++;\n            mon_p->free_size += e->header.s.d_size;\n            if(e->header.s.d_size > mon_p->free_biggest_size) {\n                mon_p->free_biggest_size = e->header.s.d_size;\n            }\n        } else {\n            mon_p->used_cnt++;\n        }\n\n        e = ent_get_next(e);\n    }\n    mon_p->total_size = LV_MEM_SIZE;\n    mon_p->used_pct   = 100 - (100U * mon_p->free_size) / mon_p->total_size;\n    mon_p->frag_pct   = (uint32_t)mon_p->free_biggest_size * 100U / mon_p->free_size;\n    mon_p->frag_pct   = 100 - mon_p->frag_pct;\n#endif\n}\n\n/**\n * Give the size of an allocated memory\n * @param data pointer to an allocated memory\n * @return the size of data memory in bytes\n */\n\n#if LV_ENABLE_GC == 0\n\nuint32_t lv_mem_get_size(const void * data)\n{\n    if(data == NULL) return 0;\n    if(data == &zero_mem) return 0;\n\n    lv_mem_ent_t * e = (lv_mem_ent_t *)((uint8_t *)data - sizeof(lv_mem_header_t));\n\n    return e->header.s.d_size;\n}\n\n#else /* LV_ENABLE_GC */\n\nuint32_t lv_mem_get_size(const void * data)\n{\n    return LV_MEM_CUSTOM_GET_SIZE(data);\n}\n\n#endif /*LV_ENABLE_GC*/\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n#if LV_MEM_CUSTOM == 0\n/**\n * Give the next entry after 'act_e'\n * @param act_e pointer to an entry\n * @return pointer to an entry after 'act_e'\n */\nstatic lv_mem_ent_t * ent_get_next(lv_mem_ent_t * act_e)\n{\n    lv_mem_ent_t * next_e = NULL;\n\n    if(act_e == NULL) { /*NULL means: get the first entry*/\n        next_e = (lv_mem_ent_t *)work_mem;\n    } else { /*Get the next entry */\n        uint8_t * data = &act_e->first_data;\n        next_e         = (lv_mem_ent_t *)&data[act_e->header.s.d_size];\n\n        if(&next_e->first_data >= &work_mem[LV_MEM_SIZE]) next_e = NULL;\n    }\n\n    return next_e;\n}\n\n/**\n * Try to do the real allocation with a given size\n * @param e try to allocate to this entry\n * @param size size of the new memory in bytes\n * @return pointer to the allocated memory or NULL if not enough memory in the entry\n */\nstatic void * ent_alloc(lv_mem_ent_t * e, uint32_t size)\n{\n    void * alloc = NULL;\n\n    /*If the memory is free and big enough then use it */\n    if(e->header.s.used == 0 && e->header.s.d_size >= size) {\n        /*Truncate the entry to the desired size */\n        ent_trunc(e, size),\n\n            e->header.s.used = 1;\n\n        /*Save the allocated data*/\n        alloc = &e->first_data;\n    }\n\n    return alloc;\n}\n\n/**\n * Truncate the data of entry to the given size\n * @param e Pointer to an entry\n * @param size new size in bytes\n */\nstatic void ent_trunc(lv_mem_ent_t * e, uint32_t size)\n{\n#ifdef LV_MEM_ENV64\n    /*Round the size up to 8*/\n    if(size & 0x7) {\n        size = size & (~0x7);\n        size += 8;\n    }\n#else\n    /*Round the size up to 4*/\n    if(size & 0x3) {\n        size = size & (~0x3);\n        size += 4;\n    }\n#endif\n\n    /*Don't let empty space only for a header without data*/\n    if(e->header.s.d_size == size + sizeof(lv_mem_header_t)) {\n        size = e->header.s.d_size;\n    }\n\n    /* Create the new entry after the current if there is space for it */\n    if(e->header.s.d_size != size) {\n        uint8_t * e_data             = &e->first_data;\n        lv_mem_ent_t * after_new_e   = (lv_mem_ent_t *)&e_data[size];\n        after_new_e->header.s.used   = 0;\n        after_new_e->header.s.d_size = e->header.s.d_size - size - sizeof(lv_mem_header_t);\n    }\n\n    /* Set the new size for the original entry */\n    e->header.s.d_size = size;\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_misc/lv_misc.mk",
    "content": "CSRCS += lv_circ.c\nCSRCS += lv_area.c\nCSRCS += lv_task.c\nCSRCS += lv_fs.c\nCSRCS += lv_anim.c\nCSRCS += lv_mem.c\nCSRCS += lv_ll.c\nCSRCS += lv_color.c\nCSRCS += lv_txt.c\nCSRCS += lv_math.c\nCSRCS += lv_log.c\nCSRCS += lv_gc.c\nCSRCS += lv_utils.c\nCSRCS += lv_async.c\n\nDEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_misc\nVPATH += :$(LVGL_DIR)/lvgl/src/lv_misc\n\nCFLAGS += \"-I$(LVGL_DIR)/lvgl/src/lv_misc\"\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_misc/lv_task.c",
    "content": "/**\n * @file lv_task.c\n * An 'lv_task'  is a void (*fp) (void* param) type function which will be called periodically.\n * A priority (5 levels + disable) can be assigned to lv_tasks.\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include <stddef.h>\n#include \"libs/lvgl/lv_misc/lv_task.h\"\n#include \"libs/lvgl/lv_hal/lv_hal_tick.h\"\n#include \"libs/lvgl/lv_misc/lv_gc.h\"\n\n#if defined(LV_GC_INCLUDE)\n#include LV_GC_INCLUDE\n#endif /* LV_ENABLE_GC */\n\n/*********************\n *      DEFINES\n *********************/\n#define IDLE_MEAS_PERIOD 500 /*[ms]*/\n#define DEF_PRIO LV_TASK_PRIO_MID\n#define DEF_PERIOD 500\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_task_exec(lv_task_t * task);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic bool lv_task_run  = false;\nstatic uint8_t idle_last = 0;\nstatic bool task_deleted;\nstatic bool task_created;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Init the lv_task module\n */\nvoid lv_task_core_init(void)\n{\n    lv_ll_init(&LV_GC_ROOT(_lv_task_ll), sizeof(lv_task_t));\n\n    /*Initially enable the lv_task handling*/\n    lv_task_enable(true);\n}\n\n/**\n * Call it  periodically to handle lv_tasks.\n */\nLV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void)\n{\n    LV_LOG_TRACE(\"lv_task_handler started\");\n\n    /*Avoid concurrent running of the task handler*/\n    static bool task_handler_mutex = false;\n    if(task_handler_mutex) return;\n    task_handler_mutex = true;\n\n    static uint32_t idle_period_start = 0;\n    static uint32_t handler_start     = 0;\n    static uint32_t busy_time         = 0;\n\n    if(lv_task_run == false) {\n        task_handler_mutex = false; /*Release mutex*/\n        return;\n    }\n\n    handler_start = lv_tick_get();\n\n    /* Run all task from the highest to the lowest priority\n     * If a lower priority task is executed check task again from the highest priority\n     * but on the priority of executed tasks don't run tasks before the executed*/\n    lv_task_t * task_interrupter = NULL;\n    lv_task_t * next;\n    bool end_flag;\n    do {\n        end_flag                 = true;\n        task_deleted             = false;\n        task_created             = false;\n        LV_GC_ROOT(_lv_task_act) = lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll));\n        while(LV_GC_ROOT(_lv_task_act)) {\n            /* The task might be deleted if it runs only once ('once = 1')\n             * So get next element until the current is surely valid*/\n            next = lv_ll_get_next(&LV_GC_ROOT(_lv_task_ll), LV_GC_ROOT(_lv_task_act));\n\n            /*We reach priority of the turned off task. There is nothing more to do.*/\n            if(((lv_task_t *)LV_GC_ROOT(_lv_task_act))->prio == LV_TASK_PRIO_OFF) {\n                break;\n            }\n\n            /*Here is the interrupter task. Don't execute it again.*/\n            if(LV_GC_ROOT(_lv_task_act) == task_interrupter) {\n                task_interrupter = NULL; /*From this point only task after the interrupter comes, so\n                                            the interrupter is not interesting anymore*/\n                LV_GC_ROOT(_lv_task_act) = next;\n                continue; /*Load the next task*/\n            }\n\n            /*Just try to run the tasks with highest priority.*/\n            if(((lv_task_t *)LV_GC_ROOT(_lv_task_act))->prio == LV_TASK_PRIO_HIGHEST) {\n                lv_task_exec(LV_GC_ROOT(_lv_task_act));\n            }\n            /*Tasks with higher priority then the interrupted shall be run in every case*/\n            else if(task_interrupter) {\n                if(((lv_task_t *)LV_GC_ROOT(_lv_task_act))->prio > task_interrupter->prio) {\n                    if(lv_task_exec(LV_GC_ROOT(_lv_task_act))) {\n                        task_interrupter =\n                            LV_GC_ROOT(_lv_task_act); /*Check all tasks again from the highest priority */\n                        end_flag = false;\n                        break;\n                    }\n                }\n            }\n            /* It is no interrupter task or we already reached it earlier.\n             * Just run the remaining tasks*/\n            else {\n                if(lv_task_exec(LV_GC_ROOT(_lv_task_act))) {\n                    task_interrupter = LV_GC_ROOT(_lv_task_act); /*Check all tasks again from the highest priority */\n                    end_flag         = false;\n                    break;\n                }\n            }\n\n            if(task_deleted) break; /*If a task was deleted then this or the next item might be corrupted*/\n            if(task_created) break; /*If a task was created then this or the next item might be corrupted*/\n\n            LV_GC_ROOT(_lv_task_act) = next; /*Load the next task*/\n        }\n    } while(!end_flag);\n\n    busy_time += lv_tick_elaps(handler_start);\n    uint32_t idle_period_time = lv_tick_elaps(idle_period_start);\n    if(idle_period_time >= IDLE_MEAS_PERIOD) {\n\n        idle_last         = (uint32_t)((uint32_t)busy_time * 100) / IDLE_MEAS_PERIOD; /*Calculate the busy percentage*/\n        idle_last         = idle_last > 100 ? 0 : 100 - idle_last;                    /*But we need idle time*/\n        busy_time         = 0;\n        idle_period_start = lv_tick_get();\n    }\n\n    task_handler_mutex = false; /*Release the mutex*/\n\n    LV_LOG_TRACE(\"lv_task_handler ready\");\n}\n/**\n * Create an \"empty\" task. It needs to initialzed with at least\n * `lv_task_set_cb` and `lv_task_set_period`\n * @return pointer to the craeted task\n */\nlv_task_t * lv_task_create_basic(void)\n{\n    lv_task_t * new_task = NULL;\n    lv_task_t * tmp;\n\n    /*Create task lists in order of priority from high to low*/\n    tmp = lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll));\n\n    /*It's the first task*/\n    if(NULL == tmp) {\n        new_task = lv_ll_ins_head(&LV_GC_ROOT(_lv_task_ll));\n        lv_mem_assert(new_task);\n        if(new_task == NULL) return NULL;\n    }\n    /*Insert the new task to proper place according to its priority*/\n    else {\n        do {\n            if(tmp->prio <= DEF_PRIO) {\n                new_task = lv_ll_ins_prev(&LV_GC_ROOT(_lv_task_ll), tmp);\n                lv_mem_assert(new_task);\n                if(new_task == NULL) return NULL;\n                break;\n            }\n            tmp = lv_ll_get_next(&LV_GC_ROOT(_lv_task_ll), tmp);\n        } while(tmp != NULL);\n\n        /*Only too high priority tasks were found. Add the task to the end*/\n        if(tmp == NULL) {\n            new_task = lv_ll_ins_tail(&LV_GC_ROOT(_lv_task_ll));\n            lv_mem_assert(new_task);\n            if(new_task == NULL) return NULL;\n        }\n    }\n\n    new_task->period  = DEF_PERIOD;\n    new_task->task_cb = NULL;\n    new_task->prio    = DEF_PRIO;\n\n    new_task->once     = 0;\n    new_task->last_run = lv_tick_get();\n\n    new_task->user_data = NULL;\n\n    task_created = true;\n\n    return new_task;\n}\n\n/**\n * Create a new lv_task\n * @param task_xcb a callback which is the task itself. It will be called periodically.\n *                 (the 'x' in the argument name indicates that its not a fully generic function because it not follows\n *                  the `func_name(object, callback, ...)` convention)\n * @param period call period in ms unit\n * @param prio priority of the task (LV_TASK_PRIO_OFF means the task is stopped)\n * @param user_data custom parameter\n * @return pointer to the new task\n */\nlv_task_t * lv_task_create(lv_task_cb_t task_cb, uint32_t period, lv_task_prio_t prio, void * user_data)\n{\n    lv_task_t * new_task = lv_task_create_basic();\n    lv_mem_assert(new_task);\n    if(new_task == NULL) return NULL;\n\n    lv_task_set_cb(new_task, task_cb);\n    lv_task_set_period(new_task, period);\n    lv_task_set_prio(new_task, prio);\n    new_task->user_data = user_data;\n\n    return new_task;\n}\n\n/**\n * Set the callback the task (the function to call periodically)\n * @param task pointer to a task\n * @param task_cb teh function to call periodically\n */\nvoid lv_task_set_cb(lv_task_t * task, lv_task_cb_t task_cb)\n{\n    task->task_cb = task_cb;\n}\n\n/**\n * Delete a lv_task\n * @param task pointer to task created by task\n */\nvoid lv_task_del(lv_task_t * task)\n{\n    lv_ll_rem(&LV_GC_ROOT(_lv_task_ll), task);\n\n    lv_mem_free(task);\n\n    if(LV_GC_ROOT(_lv_task_act) == task) task_deleted = true; /*The active task was deleted*/\n}\n\n/**\n * Set new priority for a lv_task\n * @param task pointer to a lv_task\n * @param prio the new priority\n */\nvoid lv_task_set_prio(lv_task_t * task, lv_task_prio_t prio)\n{\n    if(task->prio == prio) return;\n\n    /*Find the tasks with new priority*/\n    lv_task_t * i;\n    LV_LL_READ(LV_GC_ROOT(_lv_task_ll), i)\n    {\n        if(i->prio <= prio) {\n            if(i != task) lv_ll_move_before(&LV_GC_ROOT(_lv_task_ll), task, i);\n            break;\n        }\n    }\n\n    /*There was no such a low priority so far then add the node to the tail*/\n    if(i == NULL) {\n        lv_ll_move_before(&LV_GC_ROOT(_lv_task_ll), task, NULL);\n    }\n\n    task->prio = prio;\n}\n\n/**\n * Set new period for a lv_task\n * @param task pointer to a lv_task\n * @param period the new period\n */\nvoid lv_task_set_period(lv_task_t * task, uint32_t period)\n{\n    task->period = period;\n}\n\n/**\n * Make a lv_task ready. It will not wait its period.\n * @param task pointer to a lv_task.\n */\nvoid lv_task_ready(lv_task_t * task)\n{\n    task->last_run = lv_tick_get() - task->period - 1;\n}\n\n/**\n * Delete the lv_task after one call\n * @param task pointer to a lv_task.\n */\nvoid lv_task_once(lv_task_t * task)\n{\n    task->once = 1;\n}\n\n/**\n * Reset a lv_task.\n * It will be called the previously set period milliseconds later.\n * @param task pointer to a lv_task.\n */\nvoid lv_task_reset(lv_task_t * task)\n{\n    task->last_run = lv_tick_get();\n}\n\n/**\n * Enable or disable the whole lv_task handling\n * @param en: true: lv_task handling is running, false: lv_task handling is suspended\n */\nvoid lv_task_enable(bool en)\n{\n    lv_task_run = en;\n}\n\n/**\n * Get idle percentage\n * @return the lv_task idle in percentage\n */\nuint8_t lv_task_get_idle(void)\n{\n    return idle_last;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Execute task if its the priority is appropriate\n * @param task pointer to lv_task\n * @return true: execute, false: not executed\n */\nstatic bool lv_task_exec(lv_task_t * task)\n{\n    bool exec = false;\n\n    /*Execute if at least 'period' time elapsed*/\n    uint32_t elp = lv_tick_elaps(task->last_run);\n    if(elp >= task->period) {\n        task->last_run = lv_tick_get();\n        task_deleted   = false;\n        task_created   = false;\n        if(task->task_cb) task->task_cb(task);\n\n        /*Delete if it was a one shot lv_task*/\n        if(task_deleted == false) { /*The task might be deleted by itself as well*/\n            if(task->once != 0) {\n                lv_task_del(task);\n            }\n        }\n        exec = true;\n    }\n\n    return exec;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_misc/lv_templ.c",
    "content": "/**\n * @file lv_templ.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/* This typedef exists purely to keep -Wpedantic happy when the file is empty. */\n/* It can be removed. */\ntypedef int keep_pedantic_happy;\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_misc/lv_txt.c",
    "content": "/**\n * @file lv_text.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_misc/lv_txt.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define NO_BREAK_FOUND UINT32_MAX\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic inline bool is_break_char(uint32_t letter);\n\n#if LV_TXT_ENC == LV_TXT_ENC_UTF8\nstatic uint8_t lv_txt_utf8_size(const char * str);\nstatic uint32_t lv_txt_unicode_to_utf8(uint32_t letter_uni);\nstatic uint32_t lv_txt_utf8_conv_wc(uint32_t c);\nstatic uint32_t lv_txt_utf8_next(const char * txt, uint32_t * i);\nstatic uint32_t lv_txt_utf8_prev(const char * txt, uint32_t * i_start);\nstatic uint32_t lv_txt_utf8_get_byte_id(const char * txt, uint32_t utf8_id);\nstatic uint32_t lv_txt_utf8_get_char_id(const char * txt, uint32_t byte_id);\nstatic uint32_t lv_txt_utf8_get_length(const char * txt);\n#elif LV_TXT_ENC == LV_TXT_ENC_ASCII\nstatic uint8_t lv_txt_iso8859_1_size(const char * str);\nstatic uint32_t lv_txt_unicode_to_iso8859_1(uint32_t letter_uni);\nstatic uint32_t lv_txt_iso8859_1_conv_wc(uint32_t c);\nstatic uint32_t lv_txt_iso8859_1_next(const char * txt, uint32_t * i);\nstatic uint32_t lv_txt_iso8859_1_prev(const char * txt, uint32_t * i_start);\nstatic uint32_t lv_txt_iso8859_1_get_byte_id(const char * txt, uint32_t utf8_id);\nstatic uint32_t lv_txt_iso8859_1_get_char_id(const char * txt, uint32_t byte_id);\nstatic uint32_t lv_txt_iso8859_1_get_length(const char * txt);\n#endif\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *  GLOBAL VARIABLES\n **********************/\n#if LV_TXT_ENC == LV_TXT_ENC_UTF8\nuint8_t (*lv_txt_encoded_size)(const char *)                   = lv_txt_utf8_size;\nuint32_t (*lv_txt_unicode_to_encoded)(uint32_t)                = lv_txt_unicode_to_utf8;\nuint32_t (*lv_txt_encoded_conv_wc)(uint32_t)                   = lv_txt_utf8_conv_wc;\nuint32_t (*lv_txt_encoded_next)(const char *, uint32_t *)      = lv_txt_utf8_next;\nuint32_t (*lv_txt_encoded_prev)(const char *, uint32_t *)      = lv_txt_utf8_prev;\nuint32_t (*lv_txt_encoded_get_byte_id)(const char *, uint32_t) = lv_txt_utf8_get_byte_id;\nuint32_t (*lv_encoded_get_char_id)(const char *, uint32_t)     = lv_txt_utf8_get_char_id;\nuint32_t (*lv_txt_get_encoded_length)(const char *)            = lv_txt_utf8_get_length;\n#elif LV_TXT_ENC == LV_TXT_ENC_ASCII\nuint8_t (*lv_txt_encoded_size)(const char *)                   = lv_txt_iso8859_1_size;\nuint32_t (*lv_txt_unicode_to_encoded)(uint32_t)                = lv_txt_unicode_to_iso8859_1;\nuint32_t (*lv_txt_encoded_conv_wc)(uint32_t)                   = lv_txt_iso8859_1_conv_wc;\nuint32_t (*lv_txt_encoded_next)(const char *, uint32_t *)      = lv_txt_iso8859_1_next;\nuint32_t (*lv_txt_encoded_prev)(const char *, uint32_t *)      = lv_txt_iso8859_1_prev;\nuint32_t (*lv_txt_encoded_get_byte_id)(const char *, uint32_t) = lv_txt_iso8859_1_get_byte_id;\nuint32_t (*lv_encoded_get_char_id)(const char *, uint32_t)     = lv_txt_iso8859_1_get_char_id;\nuint32_t (*lv_txt_get_encoded_length)(const char *)            = lv_txt_iso8859_1_get_length;\n\n#endif\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Get size of a text\n * @param size_res pointer to a 'point_t' variable to store the result\n * @param text pointer to a text\n * @param font pinter to font of the text\n * @param letter_space letter space of the text\n * @param txt.line_space line space of the text\n * @param flags settings for the text from 'txt_flag_t' enum\n * @param max_width max with of the text (break the lines to fit this size) Set CORD_MAX to avoid\n * line breaks\n */\nvoid lv_txt_get_size(lv_point_t * size_res, const char * text, const lv_font_t * font, lv_coord_t letter_space,\n                     lv_coord_t line_space, lv_coord_t max_width, lv_txt_flag_t flag)\n{\n    size_res->x = 0;\n    size_res->y = 0;\n\n    if(text == NULL) return;\n    if(font == NULL) return;\n\n    if(flag & LV_TXT_FLAG_EXPAND) max_width = LV_COORD_MAX;\n\n    uint32_t line_start     = 0;\n    uint32_t new_line_start = 0;\n    lv_coord_t act_line_length;\n    uint8_t letter_height = lv_font_get_line_height(font);\n\n    /*Calc. the height and longest line*/\n    while(text[line_start] != '\\0') {\n        new_line_start += lv_txt_get_next_line(&text[line_start], font, letter_space, max_width, flag);\n        size_res->y += letter_height;\n        size_res->y += line_space;\n\n        /*Calculate the the longest line*/\n        act_line_length = lv_txt_get_width(&text[line_start], new_line_start - line_start, font, letter_space, flag);\n\n        size_res->x = LV_MATH_MAX(act_line_length, size_res->x);\n        line_start  = new_line_start;\n    }\n\n    /*Ma ke the text one line taller if the last character is '\\n' or '\\r'*/\n    if((line_start != 0) && (text[line_start - 1] == '\\n' || text[line_start - 1] == '\\r')) {\n        size_res->y += letter_height + line_space;\n    }\n\n    /*Correction with the last line space or set the height manually if the text is empty*/\n    if(size_res->y == 0)\n        size_res->y = letter_height;\n    else\n        size_res->y -= line_space;\n}\n\n/**\n * Get the next line of text. Check line length and break chars too.\n * @param txt a '\\0' terminated string\n * @param font pointer to a font\n * @param letter_space letter space\n * @param max_width max with of the text (break the lines to fit this size) Set CORD_MAX to avoid line breaks\n * @param flags settings for the text from 'txt_flag_type' enum\n * @return the index of the first char of the new line (in byte index not letter index. With UTF-8 they are different)\n */\nuint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font, lv_coord_t letter_space, lv_coord_t max_width,\n                              lv_txt_flag_t flag)\n{\n    if(txt == NULL) return 0;\n    if(font == NULL) return 0;\n\n    if(flag & LV_TXT_FLAG_EXPAND) max_width = LV_COORD_MAX;\n\n    uint32_t i                   = 0;\n    uint32_t i_next              = 0;\n    lv_coord_t cur_w             = 0;\n    uint32_t last_break          = NO_BREAK_FOUND;\n    lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT;\n    uint32_t letter_w;\n    uint32_t letter      = 0;\n    uint32_t letter_next = 0;\n\n    letter_next = lv_txt_encoded_next(txt, &i_next);\n\n    while(txt[i] != '\\0') {\n        letter      = letter_next;\n        i           = i_next;\n        letter_next = lv_txt_encoded_next(txt, &i_next);\n\n        /*Handle the recolor command*/\n        if((flag & LV_TXT_FLAG_RECOLOR) != 0) {\n            if(lv_txt_is_cmd(&cmd_state, letter) != false) {\n                continue; /*Skip the letter is it is part of a command*/\n            }\n        }\n\n        /*Check for new line chars*/\n        if(letter == '\\n' || letter == '\\r') {\n            /*Return with the first letter of the next line*/\n            if(letter == '\\r' && letter_next == '\\n')\n                return i_next;\n            else\n                return i;\n        } else { /*Check the actual length*/\n            letter_w = lv_font_get_glyph_width(font, letter, letter_next);\n            cur_w += letter_w;\n\n            /*If the txt is too long then finish, this is the line end*/\n            if(cur_w > max_width) {\n                /*If a break character was already found break there*/\n                if(last_break != NO_BREAK_FOUND) {\n                    i = last_break;\n                } else {\n                    /* Now this character is out of the area so it will be first character of the next line*/\n                    /* But 'i' already points to the next character (because of lv_txt_utf8_next) step beck one*/\n                    lv_txt_encoded_prev(txt, &i);\n                }\n\n                /* Do not let to return without doing nothing.\n                 * Find at least one character (Avoid infinite loop )*/\n                if(i == 0) lv_txt_encoded_next(txt, &i);\n\n                return i;\n            }\n            /*If this char still can fit to this line then check if\n             * txt can be broken here later */\n            else if(is_break_char(letter)) {\n                last_break = i; /*Save the first char index after break*/\n            }\n        }\n\n        if(letter_w > 0) {\n            cur_w += letter_space;\n        }\n    }\n\n    return i;\n}\n\n/**\n * Give the length of a text with a given font\n * @param txt a '\\0' terminate string\n * @param length length of 'txt' in byte count and not characters (Á is 1 character but 2 bytes in\n * UTF-8)\n * @param font pointer to a font\n * @param letter_space letter space\n * @param flags settings for the text from 'txt_flag_t' enum\n * @return length of a char_num long text\n */\nlv_coord_t lv_txt_get_width(const char * txt, uint16_t length, const lv_font_t * font, lv_coord_t letter_space,\n                            lv_txt_flag_t flag)\n{\n    if(txt == NULL) return 0;\n    if(font == NULL) return 0;\n\n    uint32_t i                   = 0;\n    lv_coord_t width             = 0;\n    lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT;\n    uint32_t letter;\n    uint32_t letter_next;\n\n    if(length != 0) {\n        while(i < length) {\n            letter      = lv_txt_encoded_next(txt, &i);\n            letter_next = lv_txt_encoded_next(&txt[i], NULL);\n            if((flag & LV_TXT_FLAG_RECOLOR) != 0) {\n                if(lv_txt_is_cmd(&cmd_state, letter) != false) {\n                    continue;\n                }\n            }\n\n            lv_coord_t char_width = lv_font_get_glyph_width(font, letter, letter_next);\n            if(char_width > 0) {\n                width += char_width;\n                width += letter_space;\n            }\n        }\n\n        if(width > 0) {\n            width -= letter_space; /*Trim the last letter space. Important if the text is center\n                                      aligned */\n        }\n    }\n\n    return width;\n}\n\n/**\n * Check next character in a string and decide if the character is part of the command or not\n * @param state pointer to a txt_cmd_state_t variable which stores the current state of command\n * processing (Initied. to TXT_CMD_STATE_WAIT )\n * @param c the current character\n * @return true: the character is part of a command and should not be written,\n *         false: the character should be written\n */\nbool lv_txt_is_cmd(lv_txt_cmd_state_t * state, uint32_t c)\n{\n    bool ret = false;\n\n    if(c == (uint32_t)LV_TXT_COLOR_CMD[0]) {\n        if(*state == LV_TXT_CMD_STATE_WAIT) { /*Start char*/\n            *state = LV_TXT_CMD_STATE_PAR;\n            ret    = true;\n        }\n        /*Other start char in parameter is escaped cmd. char */\n        else if(*state == LV_TXT_CMD_STATE_PAR) {\n            *state = LV_TXT_CMD_STATE_WAIT;\n        }\n        /*Command end */\n        else if(*state == LV_TXT_CMD_STATE_IN) {\n            *state = LV_TXT_CMD_STATE_WAIT;\n            ret    = true;\n        }\n    }\n\n    /*Skip the color parameter and wait the space after it*/\n    if(*state == LV_TXT_CMD_STATE_PAR) {\n        if(c == ' ') {\n            *state = LV_TXT_CMD_STATE_IN; /*After the parameter the text is in the command*/\n        }\n        ret = true;\n    }\n\n    return ret;\n}\n\n/**\n * Insert a string into an other\n * @param txt_buf the original text (must be big enough for the result text)\n * @param pos position to insert. Expressed in character index and not byte index (Different in\n * UTF-8) 0: before the original text, 1: after the first char etc.\n * @param ins_txt text to insert\n */\nvoid lv_txt_ins(char * txt_buf, uint32_t pos, const char * ins_txt)\n{\n    uint32_t old_len = strlen(txt_buf);\n    uint32_t ins_len = strlen(ins_txt);\n    uint32_t new_len = ins_len + old_len;\n    pos              = lv_txt_encoded_get_byte_id(txt_buf, pos); /*Convert to byte index instead of letter index*/\n\n    /*Copy the second part into the end to make place to text to insert*/\n    uint32_t i;\n    for(i = new_len; i >= pos + ins_len; i--) {\n        txt_buf[i] = txt_buf[i - ins_len];\n    }\n\n    /* Copy the text into the new space*/\n    memcpy(txt_buf + pos, ins_txt, ins_len);\n}\n\n/**\n * Delete a part of a string\n * @param txt string to modify\n * @param pos position where to start the deleting (0: before the first char, 1: after the first\n * char etc.)\n * @param len number of characters to delete\n */\nvoid lv_txt_cut(char * txt, uint32_t pos, uint32_t len)\n{\n\n    uint32_t old_len = strlen(txt);\n\n    pos = lv_txt_encoded_get_byte_id(txt, pos); /*Convert to byte index instead of letter index*/\n    len = lv_txt_encoded_get_byte_id(&txt[pos], len);\n\n    /*Copy the second part into the end to make place to text to insert*/\n    uint32_t i;\n    for(i = pos; i <= old_len - len; i++) {\n        txt[i] = txt[i + len];\n    }\n}\n\n#if LV_TXT_ENC == LV_TXT_ENC_UTF8\n/*******************************\n *   UTF-8 ENCODER/DECOER\n ******************************/\n\n/**\n * Give the size of an UTF-8 coded character\n * @param str pointer to a character in a string\n * @return length of the UTF-8 character (1,2,3 or 4). O on invalid code\n */\nstatic uint8_t lv_txt_utf8_size(const char * str)\n{\n    if((str[0] & 0x80) == 0)\n        return 1;\n    else if((str[0] & 0xE0) == 0xC0)\n        return 2;\n    else if((str[0] & 0xF0) == 0xE0)\n        return 3;\n    else if((str[0] & 0xF8) == 0xF0)\n        return 4;\n    return 1; /*If the char was invalid step tell it's 1 byte long*/\n}\n\n/**\n * Convert an Unicode letter to UTF-8.\n * @param letter_uni an Unicode letter\n * @return UTF-8 coded character in Little Endian to be compatible with C chars (e.g. 'Á', 'Ű')\n */\nstatic uint32_t lv_txt_unicode_to_utf8(uint32_t letter_uni)\n{\n    if(letter_uni < 128) return letter_uni;\n    uint8_t bytes[4];\n\n    if(letter_uni < 0x0800) {\n        bytes[0] = ((letter_uni >> 6) & 0x1F) | 0xC0;\n        bytes[1] = ((letter_uni >> 0) & 0x3F) | 0x80;\n        bytes[2] = 0;\n        bytes[3] = 0;\n    } else if(letter_uni < 0x010000) {\n        bytes[0] = ((letter_uni >> 12) & 0x0F) | 0xE0;\n        bytes[1] = ((letter_uni >> 6) & 0x3F) | 0x80;\n        bytes[2] = ((letter_uni >> 0) & 0x3F) | 0x80;\n        bytes[3] = 0;\n    } else if(letter_uni < 0x110000) {\n        bytes[0] = ((letter_uni >> 18) & 0x07) | 0xF0;\n        bytes[1] = ((letter_uni >> 12) & 0x3F) | 0x80;\n        bytes[2] = ((letter_uni >> 6) & 0x3F) | 0x80;\n        bytes[3] = ((letter_uni >> 0) & 0x3F) | 0x80;\n    }\n\n    uint32_t * res_p = (uint32_t *)bytes;\n    return *res_p;\n}\n\n/**\n * Convert a wide character, e.g. 'Á' little endian to be UTF-8 compatible\n * @param c a wide character or a  Little endian number\n * @return `c` in big endian\n */\nstatic uint32_t lv_txt_utf8_conv_wc(uint32_t c)\n{\n    /*Swap the bytes (UTF-8 is big endian, but the MCUs are little endian)*/\n    if((c & 0x80) != 0) {\n        uint32_t swapped;\n        uint8_t c8[4];\n        memcpy(c8, &c, 4);\n        swapped = (c8[0] << 24) + (c8[1] << 16) + (c8[2] << 8) + (c8[3]);\n        uint8_t i;\n        for(i = 0; i < 4; i++) {\n            if((swapped & 0xFF) == 0)\n                swapped = (swapped >> 8); /*Ignore leading zeros (they were in the end originally)*/\n        }\n        c = swapped;\n    }\n\n    return c;\n}\n\n/**\n * Decode an UTF-8 character from a string.\n * @param txt pointer to '\\0' terminated string\n * @param i start byte index in 'txt' where to start.\n *          After call it will point to the next UTF-8 char in 'txt'.\n *          NULL to use txt[0] as index\n * @return the decoded Unicode character or 0 on invalid UTF-8 code\n */\nstatic uint32_t lv_txt_utf8_next(const char * txt, uint32_t * i)\n{\n    /* Unicode to UTF-8\n     * 00000000 00000000 00000000 0xxxxxxx -> 0xxxxxxx\n     * 00000000 00000000 00000yyy yyxxxxxx -> 110yyyyy 10xxxxxx\n     * 00000000 00000000 zzzzyyyy yyxxxxxx -> 1110zzzz 10yyyyyy 10xxxxxx\n     * 00000000 000wwwzz zzzzyyyy yyxxxxxx -> 11110www 10zzzzzz 10yyyyyy 10xxxxxx\n     * */\n\n    uint32_t result = 0;\n\n    /*Dummy 'i' pointer is required*/\n    uint32_t i_tmp = 0;\n    if(i == NULL) i = &i_tmp;\n\n    /*Normal ASCII*/\n    if((txt[*i] & 0x80) == 0) {\n        result = txt[*i];\n        (*i)++;\n    }\n    /*Real UTF-8 decode*/\n    else {\n        /*2 bytes UTF-8 code*/\n        if((txt[*i] & 0xE0) == 0xC0) {\n            result = (uint32_t)(txt[*i] & 0x1F) << 6;\n            (*i)++;\n            if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/\n            result += (txt[*i] & 0x3F);\n            (*i)++;\n        }\n        /*3 bytes UTF-8 code*/\n        else if((txt[*i] & 0xF0) == 0xE0) {\n            result = (uint32_t)(txt[*i] & 0x0F) << 12;\n            (*i)++;\n\n            if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/\n            result += (uint32_t)(txt[*i] & 0x3F) << 6;\n            (*i)++;\n\n            if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/\n            result += (txt[*i] & 0x3F);\n            (*i)++;\n        }\n        /*4 bytes UTF-8 code*/\n        else if((txt[*i] & 0xF8) == 0xF0) {\n            result = (uint32_t)(txt[*i] & 0x07) << 18;\n            (*i)++;\n\n            if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/\n            result += (uint32_t)(txt[*i] & 0x3F) << 12;\n            (*i)++;\n\n            if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/\n            result += (uint32_t)(txt[*i] & 0x3F) << 6;\n            (*i)++;\n\n            if((txt[*i] & 0xC0) != 0x80) return 0; /*Invalid UTF-8 code*/\n            result += txt[*i] & 0x3F;\n            (*i)++;\n        } else {\n            (*i)++; /*Not UTF-8 char. Go the next.*/\n        }\n    }\n    return result;\n}\n\n/**\n * Get previous UTF-8 character form a string.\n * @param txt pointer to '\\0' terminated string\n * @param i start byte index in 'txt' where to start. After the call it will point to the previous\n * UTF-8 char in 'txt'.\n * @return the decoded Unicode character or 0 on invalid UTF-8 code\n */\nstatic uint32_t lv_txt_utf8_prev(const char * txt, uint32_t * i)\n{\n    uint8_t c_size;\n    uint8_t cnt = 0;\n\n    /*Try to find a !0 long UTF-8 char by stepping one character back*/\n    (*i)--;\n    do {\n        if(cnt >= 4) return 0; /*No UTF-8 char found before the initial*/\n\n        c_size = lv_txt_encoded_size(&txt[*i]);\n        if(c_size == 0) {\n            if(*i != 0)\n                (*i)--;\n            else\n                return 0;\n        }\n        cnt++;\n    } while(c_size == 0);\n\n    uint32_t i_tmp  = *i;\n    uint32_t letter = lv_txt_encoded_next(txt, &i_tmp); /*Character found, get it*/\n\n    return letter;\n}\n\n/**\n * Convert a character index (in an UTF-8 text) to byte index.\n * E.g. in \"AÁRT\" index of 'R' is 2th char but start at byte 3 because 'Á' is 2 bytes long\n * @param txt a '\\0' terminated UTF-8 string\n * @param utf8_id character index\n * @return byte index of the 'utf8_id'th letter\n */\nstatic uint32_t lv_txt_utf8_get_byte_id(const char * txt, uint32_t utf8_id)\n{\n    uint32_t i;\n    uint32_t byte_cnt = 0;\n    for(i = 0; i < utf8_id; i++) {\n        byte_cnt += lv_txt_encoded_size(&txt[byte_cnt]);\n    }\n\n    return byte_cnt;\n}\n\n/**\n * Convert a byte index (in an UTF-8 text) to character index.\n * E.g. in \"AÁRT\" index of 'R' is 2th char but start at byte 3 because 'Á' is 2 bytes long\n * @param txt a '\\0' terminated UTF-8 string\n * @param byte_id byte index\n * @return character index of the letter at 'byte_id'th position\n */\nstatic uint32_t lv_txt_utf8_get_char_id(const char * txt, uint32_t byte_id)\n{\n    uint32_t i        = 0;\n    uint32_t char_cnt = 0;\n\n    while(i < byte_id) {\n        lv_txt_encoded_next(txt, &i); /*'i' points to the next letter so use the prev. value*/\n        char_cnt++;\n    }\n\n    return char_cnt;\n}\n\n/**\n * Get the number of characters (and NOT bytes) in a string. Decode it with UTF-8 if enabled.\n * E.g.: \"ÁBC\" is 3 characters (but 4 bytes)\n * @param txt a '\\0' terminated char string\n * @return number of characters\n */\nstatic uint32_t lv_txt_utf8_get_length(const char * txt)\n{\n    uint32_t len = 0;\n    uint32_t i   = 0;\n\n    while(txt[i] != '\\0') {\n        lv_txt_encoded_next(txt, &i);\n        len++;\n    }\n\n    return len;\n}\n\n#elif LV_TXT_ENC == LV_TXT_ENC_ASCII\n/*******************************\n *  ASCII ENCODER/DECOER\n ******************************/\n\n/**\n * Give the size of an ISO8859-1 coded character\n * @param str pointer to a character in a string\n * @return length of the UTF-8 character (1,2,3 or 4). O on invalid code\n */\nstatic uint8_t lv_txt_iso8859_1_size(const char * str)\n{\n    (void)str; /*Unused*/\n    return 1;\n}\n\n/**\n * Convert an Unicode letter to ISO8859-1.\n * @param letter_uni an Unicode letter\n * @return ISO8859-1 coded character in Little Endian to be compatible with C chars (e.g. 'Á', 'Ű')\n */\nstatic uint32_t lv_txt_unicode_to_iso8859_1(uint32_t letter_uni)\n{\n    if(letter_uni < 128)\n        return letter_uni;\n    else\n        return ' ';\n}\n\n/**\n * Convert wide characters to ASCII, however wide characters in ASCII range (e.g. 'A') are ASCII compatible by default.\n * So this function does nothing just returns with `c`.\n * @param c a character, e.g. 'A'\n * @return same as `c`\n */\nstatic uint32_t lv_txt_iso8859_1_conv_wc(uint32_t c)\n{\n    return c;\n}\n\n/**\n * Decode an ISO8859-1 character from a string.\n * @param txt pointer to '\\0' terminated string\n * @param i start byte index in 'txt' where to start.\n *          After call it will point to the next UTF-8 char in 'txt'.\n *          NULL to use txt[0] as index\n * @return the decoded Unicode character or 0 on invalid UTF-8 code\n */\nstatic uint32_t lv_txt_iso8859_1_next(const char * txt, uint32_t * i)\n{\n    if(i == NULL) return txt[1]; /*Get the next char */\n\n    uint8_t letter = txt[*i];\n    (*i)++;\n    return letter;\n}\n\n/**\n * Get previous ISO8859-1 character form a string.\n * @param txt pointer to '\\0' terminated string\n * @param i start byte index in 'txt' where to start. After the call it will point to the previous UTF-8 char in 'txt'.\n * @return the decoded Unicode character or 0 on invalid UTF-8 code\n */\nstatic uint32_t lv_txt_iso8859_1_prev(const char * txt, uint32_t * i)\n{\n    if(i == NULL) return *(txt - 1); /*Get the prev. char */\n\n    (*i)--;\n    uint8_t letter = txt[*i];\n\n    return letter;\n}\n\n/**\n * Convert a character index (in an ISO8859-1 text) to byte index.\n * E.g. in \"AÁRT\" index of 'R' is 2th char but start at byte 3 because 'Á' is 2 bytes long\n * @param txt a '\\0' terminated UTF-8 string\n * @param utf8_id character index\n * @return byte index of the 'utf8_id'th letter\n */\nstatic uint32_t lv_txt_iso8859_1_get_byte_id(const char * txt, uint32_t utf8_id)\n{\n    (void)txt;      /*Unused*/\n    return utf8_id; /*In Non encoded no difference*/\n}\n\n/**\n * Convert a byte index (in an ISO8859-1 text) to character index.\n * E.g. in \"AÁRT\" index of 'R' is 2th char but start at byte 3 because 'Á' is 2 bytes long\n * @param txt a '\\0' terminated UTF-8 string\n * @param byte_id byte index\n * @return character index of the letter at 'byte_id'th position\n */\nstatic uint32_t lv_txt_iso8859_1_get_char_id(const char * txt, uint32_t byte_id)\n{\n    (void)txt;      /*Unused*/\n    return byte_id; /*In Non encoded no difference*/\n}\n\n/**\n * Get the number of characters (and NOT bytes) in a string. Decode it with UTF-8 if enabled.\n * E.g.: \"ÁBC\" is 3 characters (but 4 bytes)\n * @param txt a '\\0' terminated char string\n * @return number of characters\n */\nstatic uint32_t lv_txt_iso8859_1_get_length(const char * txt)\n{\n    return strlen(txt);\n}\n#else\n\n#error \"Invalid character encoding. See `LV_TXT_ENC` in `lv_conf.h`\"\n\n#endif\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Test if char is break char or not (a text can broken here or not)\n * @param letter a letter\n * @return false: 'letter' is not break char\n */\nstatic inline bool is_break_char(uint32_t letter)\n{\n    uint8_t i;\n    bool ret = false;\n\n    /*Compare the letter to TXT_BREAK_CHARS*/\n    for(i = 0; LV_TXT_BREAK_CHARS[i] != '\\0'; i++) {\n        if(letter == (uint32_t)LV_TXT_BREAK_CHARS[i]) {\n            ret = true; /*If match then it is break char*/\n            break;\n        }\n    }\n\n    return ret;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_misc/lv_utils.c",
    "content": "/**\n * @file lv_utils.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"utils/types.h\"\n\n#include \"libs/lvgl/lv_misc/lv_utils.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Convert a number to string\n * @param num a number\n * @param buf pointer to a `char` buffer. The result will be stored here (max 10 elements)\n * @return same as `buf` (just for convenience)\n */\nchar * lv_utils_num_to_str(int32_t num, char * buf)\n{\n    if(num == 0) {\n        buf[0] = '0';\n        buf[1] = '\\0';\n        return buf;\n    }\n    int8_t digitCount = 0;\n    int8_t i          = 0;\n    if(num < 0) {\n        buf[digitCount++] = '-';\n        num               = LV_MATH_ABS(num);\n        ++i;\n    }\n    while(num) {\n        char digit        = num % 10;\n        buf[digitCount++] = digit + 48;\n        num /= 10;\n    }\n    buf[digitCount] = '\\0';\n    digitCount--;\n    while(digitCount > i) {\n        char temp       = buf[i];\n        buf[i]          = buf[digitCount];\n        buf[digitCount] = temp;\n        digitCount--;\n        i++;\n    }\n    return buf;\n}\n\n/** Searches base[0] to base[n - 1] for an item that matches *key.\n *\n * @note The function cmp must return negative if its first\n *  argument (the search key) is less that its second (a table entry),\n *  zero if equal, and positive if greater.\n *\n *  @note Items in the array must be in ascending order.\n *\n * @param key    Pointer to item being searched for\n * @param base   Pointer to first element to search\n * @param n      Number of elements\n * @param size   Size of each element\n * @param cmp    Pointer to comparison function (see #lv_font_codeCompare as a comparison function\n * example)\n *\n * @return a pointer to a matching item, or NULL if none exists.\n */\nvoid * lv_utils_bsearch(const void * key, const void * base, uint32_t n, uint32_t size,\n                        int32_t (*cmp)(const void * pRef, const void * pElement))\n{\n    const char * middle;\n    int32_t c;\n\n    for(middle = base; n != 0;) {\n        middle += (n / 2) * size;\n        if((c = (*cmp)(key, middle)) > 0) {\n            n    = (n / 2) - ((n & 1) == 0);\n            base = (middle += size);\n        } else if(c < 0) {\n            n /= 2;\n            middle = base;\n        } else {\n            return (char *)middle;\n        }\n    }\n    return NULL;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_arc.c",
    "content": "/**\n * @file lv_arc.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_arc.h\"\n#if LV_USE_ARC != 0\n\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n#include \"libs/lvgl/lv_draw/lv_draw_arc.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_arc_design(lv_obj_t * arc, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\nstatic lv_design_cb_t ancestor_design;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a arc object\n * @param par pointer to an object, it will be the parent of the new arc\n * @param copy pointer to a arc object, if not NULL then the new object will be copied from it\n * @return pointer to the created arc\n */\nlv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n\n    LV_LOG_TRACE(\"arc create started\");\n\n    /*Create the ancestor of arc*/\n    lv_obj_t * new_arc = lv_obj_create(par, copy);\n    lv_mem_assert(new_arc);\n    if(new_arc == NULL) return NULL;\n\n    /*Allocate the arc type specific extended data*/\n    lv_arc_ext_t * ext = lv_obj_allocate_ext_attr(new_arc, sizeof(lv_arc_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_arc);\n    if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_arc);\n\n    /*Initialize the allocated 'ext' */\n    ext->angle_start = 45;\n    ext->angle_end   = 315;\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_cb(new_arc, lv_arc_signal);\n    lv_obj_set_design_cb(new_arc, lv_arc_design);\n\n    /*Init the new arc arc*/\n    if(copy == NULL) {\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_arc_set_style(new_arc, LV_ARC_STYLE_MAIN, th->style.arc);\n        } else {\n            lv_arc_set_style(new_arc, LV_ARC_STYLE_MAIN, &lv_style_plain_color);\n        }\n\n    }\n    /*Copy an existing arc*/\n    else {\n        lv_arc_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->angle_start        = copy_ext->angle_start;\n        ext->angle_end          = copy_ext->angle_end;\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_arc);\n    }\n\n    LV_LOG_INFO(\"arc created\");\n\n    return new_arc;\n}\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/*\n * New object specific \"add\" or \"remove\" functions come here\n */\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the start and end angles of an arc. 0 deg: bottom, 90 deg: right etc.\n * @param arc pointer to an arc object\n * @param start the start angle [0..360]\n * @param end the end angle [0..360]\n */\nvoid lv_arc_set_angles(lv_obj_t * arc, uint16_t start, uint16_t end)\n{\n    lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc);\n\n    if(start > 360) start = 360;\n    if(end > 360) end = 360;\n\n    ext->angle_start = start;\n    ext->angle_end   = end;\n\n    lv_obj_invalidate(arc);\n}\n\n/**\n * Set a style of a arc.\n * @param arc pointer to arc object\n * @param type which style should be set\n * @param style pointer to a style\n *  */\nvoid lv_arc_set_style(lv_obj_t * arc, lv_arc_style_t type, const lv_style_t * style)\n{\n    switch(type) {\n        case LV_ARC_STYLE_MAIN: lv_obj_set_style(arc, style); break;\n    }\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the start angle of an arc.\n * @param arc pointer to an arc object\n * @return the start angle [0..360]\n */\nuint16_t lv_arc_get_angle_start(lv_obj_t * arc)\n{\n    lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc);\n\n    return ext->angle_start;\n}\n\n/**\n * Get the end angle of an arc.\n * @param arc pointer to an arc object\n * @return the end angle [0..360]\n */\nuint16_t lv_arc_get_angle_end(lv_obj_t * arc)\n{\n    lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc);\n\n    return ext->angle_end;\n}\n\n/**\n * Get style of a arc.\n * @param arc pointer to arc object\n * @param type which style should be get\n * @return style pointer to the style\n *  */\nconst lv_style_t * lv_arc_get_style(const lv_obj_t * arc, lv_arc_style_t type)\n{\n    const lv_style_t * style = NULL;\n\n    switch(type) {\n        case LV_ARC_STYLE_MAIN: style = lv_obj_get_style(arc); break;\n        default: style = NULL; break;\n    }\n\n    return style;\n}\n\n/*=====================\n * Other functions\n *====================*/\n\n/*\n * New object specific \"other\" functions come here\n */\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the arcs\n * @param arc pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_arc_design(lv_obj_t * arc, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    /*Return false if the object is not covers the mask_p area*/\n    if(mode == LV_DESIGN_COVER_CHK) {\n        return false;\n    }\n    /*Draw the object*/\n    else if(mode == LV_DESIGN_DRAW_MAIN) {\n        lv_arc_ext_t * ext       = lv_obj_get_ext_attr(arc);\n        const lv_style_t * style = lv_arc_get_style(arc, LV_ARC_STYLE_MAIN);\n\n        lv_coord_t r       = (LV_MATH_MIN(lv_obj_get_width(arc), lv_obj_get_height(arc))) / 2;\n        lv_coord_t x       = arc->coords.x1 + lv_obj_get_width(arc) / 2;\n        lv_coord_t y       = arc->coords.y1 + lv_obj_get_height(arc) / 2;\n        lv_opa_t opa_scale = lv_obj_get_opa_scale(arc);\n        lv_draw_arc(x, y, r, mask, ext->angle_start, ext->angle_end, style, opa_scale);\n\n        /*Draw circle on the ends if enabled */\n        if(style->line.rounded) {\n            lv_coord_t thick_half = style->line.width / 2;\n            lv_coord_t cir_x      = ((r - thick_half) * lv_trigo_sin(ext->angle_start) >> LV_TRIGO_SHIFT);\n            lv_coord_t cir_y      = ((r - thick_half) * lv_trigo_sin(ext->angle_start + 90) >> LV_TRIGO_SHIFT);\n\n            lv_style_t cir_style;\n            lv_style_copy(&cir_style, &lv_style_plain);\n            cir_style.body.grad_color = style->line.color;\n            cir_style.body.main_color = cir_style.body.grad_color;\n            cir_style.body.radius     = LV_RADIUS_CIRCLE;\n            lv_area_t cir_area;\n            cir_area.x1 = cir_x + x - thick_half;\n            cir_area.y1 = cir_y + y - thick_half;\n            cir_area.x2 = cir_x + x + thick_half;\n            cir_area.y2 = cir_y + y + thick_half;\n\n            lv_draw_rect(&cir_area, mask, &cir_style, opa_scale);\n\n            cir_x = ((r - thick_half) * lv_trigo_sin(ext->angle_end) >> LV_TRIGO_SHIFT);\n            cir_y = ((r - thick_half) * lv_trigo_sin(ext->angle_end + 90) >> LV_TRIGO_SHIFT);\n\n            cir_area.x1 = cir_x + x - thick_half;\n            cir_area.y1 = cir_y + y - thick_half;\n            cir_area.x2 = cir_x + x + thick_half;\n            cir_area.y2 = cir_y + y + thick_half;\n\n            lv_draw_rect(&cir_area, mask, &cir_style, opa_scale);\n        }\n\n    }\n    /*Post draw when the children are drawn*/\n    else if(mode == LV_DESIGN_DRAW_POST) {\n    }\n\n    return true;\n}\n\n/**\n * Signal function of the arc\n * @param arc pointer to a arc object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(arc, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    if(sign == LV_SIGNAL_CLEANUP) {\n        /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_arc\";\n    }\n\n    return res;\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_bar.c",
    "content": "\n\n/**\n * @file lv_bar.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_bar.h\"\n#if LV_USE_BAR != 0\n\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_misc/lv_anim.h\"\n#include <stdio.h>\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_bar_design(lv_obj_t * bar, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param);\n\n#if LV_USE_ANIMATION\nstatic void lv_bar_anim(void * bar, lv_anim_value_t value);\nstatic void lv_bar_anim_ready(lv_anim_t * a);\n#endif\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_design_cb_t ancestor_design_f;\nstatic lv_signal_cb_t ancestor_signal;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a bar objects\n * @param par pointer to an object, it will be the parent of the new bar\n * @param copy pointer to a bar object, if not NULL then the new object will be copied from it\n * @return pointer to the created bar\n */\nlv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"lv_bar create started\");\n\n    /*Create the ancestor basic object*/\n    lv_obj_t * new_bar = lv_obj_create(par, copy);\n    lv_mem_assert(new_bar);\n    if(new_bar == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_bar);\n    if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_cb(new_bar);\n\n    /*Allocate the object type specific extended data*/\n    lv_bar_ext_t * ext = lv_obj_allocate_ext_attr(new_bar, sizeof(lv_bar_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    ext->min_value = 0;\n    ext->max_value = 100;\n    ext->cur_value = 0;\n#if LV_USE_ANIMATION\n    ext->anim_time  = 200;\n    ext->anim_start = 0;\n    ext->anim_end   = 0;\n    ext->anim_state = LV_BAR_ANIM_STATE_INV;\n#endif\n    ext->sym         = 0;\n    ext->style_indic = &lv_style_pretty_color;\n\n    lv_obj_set_signal_cb(new_bar, lv_bar_signal);\n    lv_obj_set_design_cb(new_bar, lv_bar_design);\n\n    /*Init the new  bar object*/\n    if(copy == NULL) {\n        lv_obj_set_click(new_bar, false);\n        lv_obj_set_size(new_bar, LV_DPI * 2, LV_DPI / 3);\n        lv_bar_set_value(new_bar, ext->cur_value, false);\n\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_bar_set_style(new_bar, LV_BAR_STYLE_BG, th->style.bar.bg);\n            lv_bar_set_style(new_bar, LV_BAR_STYLE_INDIC, th->style.bar.indic);\n        } else {\n            lv_obj_set_style(new_bar, &lv_style_pretty);\n        }\n    } else {\n        lv_bar_ext_t * ext_copy = lv_obj_get_ext_attr(copy);\n        ext->min_value          = ext_copy->min_value;\n        ext->max_value          = ext_copy->max_value;\n        ext->cur_value          = ext_copy->cur_value;\n        ext->style_indic        = ext_copy->style_indic;\n        ext->sym                = ext_copy->sym;\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_bar);\n\n        lv_bar_set_value(new_bar, ext->cur_value, false);\n    }\n\n    LV_LOG_INFO(\"bar created\");\n\n    return new_bar;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a new value on the bar\n * @param bar pointer to a bar object\n * @param value new value\n * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediatelly\n */\nvoid lv_bar_set_value(lv_obj_t * bar, int16_t value, lv_anim_enable_t anim)\n{\n#if LV_USE_ANIMATION == 0\n    anim = false;\n#endif\n    lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);\n    if(ext->cur_value == value) return;\n\n    int16_t new_value;\n    new_value = value > ext->max_value ? ext->max_value : value;\n    new_value = new_value < ext->min_value ? ext->min_value : new_value;\n\n    if(ext->cur_value == new_value) return;\n\n    if(anim == LV_ANIM_OFF) {\n        ext->cur_value = new_value;\n        lv_obj_invalidate(bar);\n    } else {\n#if LV_USE_ANIMATION\n        /*No animation in progress -> simply set the values*/\n        if(ext->anim_state == LV_BAR_ANIM_STATE_INV) {\n            ext->anim_start = ext->cur_value;\n            ext->anim_end   = new_value;\n        }\n        /*Animation in progress. Start from the animation end value*/\n        else {\n            ext->anim_start = ext->anim_end;\n            ext->anim_end   = new_value;\n        }\n\n        lv_anim_t a;\n        a.var            = bar;\n        a.start          = LV_BAR_ANIM_STATE_START;\n        a.end            = LV_BAR_ANIM_STATE_END;\n        a.exec_cb        = (lv_anim_exec_xcb_t)lv_bar_anim;\n        a.path_cb        = lv_anim_path_linear;\n        a.ready_cb       = lv_bar_anim_ready;\n        a.act_time       = 0;\n        a.time           = ext->anim_time;\n        a.playback       = 0;\n        a.playback_pause = 0;\n        a.repeat         = 0;\n        a.repeat_pause   = 0;\n\n        lv_anim_create(&a);\n#endif\n    }\n}\n\n/**\n * Set minimum and the maximum values of a bar\n * @param bar pointer to the bar object\n * @param min minimum value\n * @param max maximum value\n */\nvoid lv_bar_set_range(lv_obj_t * bar, int16_t min, int16_t max)\n{\n    lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);\n    if(ext->min_value == min && ext->max_value == max) return;\n\n    ext->max_value = max;\n    ext->min_value = min;\n    if(ext->cur_value > max) {\n        ext->cur_value = max;\n        lv_bar_set_value(bar, ext->cur_value, false);\n    }\n    if(ext->cur_value < min) {\n        ext->cur_value = min;\n        lv_bar_set_value(bar, ext->cur_value, false);\n    }\n    lv_obj_invalidate(bar);\n}\n\n/**\n * Make the bar symmetric to zero. The indicator will grow from zero instead of the minimum\n * position.\n * @param bar pointer to a bar object\n * @param en true: enable disable symmetric behavior; false: disable\n */\nvoid lv_bar_set_sym(lv_obj_t * bar, bool en)\n{\n    lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);\n    ext->sym           = en ? 1 : 0;\n}\n\n/**\n * Set the animation time of the bar\n * @param bar pointer to a bar object\n * @param anim_time the animation time in milliseconds.\n */\nvoid lv_bar_set_anim_time(lv_obj_t * bar, uint16_t anim_time)\n{\n#if LV_USE_ANIMATION\n    lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);\n    ext->anim_time     = anim_time;\n#else\n    (void)bar;       /*Unused*/\n    (void)anim_time; /*Unused*/\n#endif\n}\n\n/**\n * Set a style of a bar\n * @param bar pointer to a bar object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_bar_set_style(lv_obj_t * bar, lv_bar_style_t type, const lv_style_t * style)\n{\n    lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);\n\n    switch(type) {\n        case LV_BAR_STYLE_BG: lv_obj_set_style(bar, style); break;\n        case LV_BAR_STYLE_INDIC:\n            ext->style_indic = style;\n            lv_obj_refresh_ext_draw_pad(bar);\n            break;\n    }\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the value of a bar\n * @param bar pointer to a bar object\n * @return the value of the bar\n */\nint16_t lv_bar_get_value(const lv_obj_t * bar)\n{\n    lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);\n    /*If animated tell that it's already at the end value*/\n#if LV_USE_ANIMATION\n    if(ext->anim_state != LV_BAR_ANIM_STATE_INV) return ext->anim_end;\n#endif\n    /*No animation, simple return the current value*/\n    return ext->cur_value;\n}\n\n/**\n * Get the minimum value of a bar\n * @param bar pointer to a bar object\n * @return the minimum value of the bar\n */\nint16_t lv_bar_get_min_value(const lv_obj_t * bar)\n{\n    lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);\n    return ext->min_value;\n}\n\n/**\n * Get the maximum value of a bar\n * @param bar pointer to a bar object\n * @return the maximum value of the bar\n */\nint16_t lv_bar_get_max_value(const lv_obj_t * bar)\n{\n    lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);\n    return ext->max_value;\n}\n\n/**\n * Get whether the bar is symmetric or not.\n * @param bar pointer to a bar object\n * @return true: symmetric is enabled; false: disable\n */\nbool lv_bar_get_sym(lv_obj_t * bar)\n{\n    lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);\n    return ext->sym ? true : false;\n}\n\n/**\n * Get the animation time of the bar\n * @param bar pointer to a bar object\n * @return the animation time in milliseconds.\n */\nuint16_t lv_bar_get_anim_time(lv_obj_t * bar)\n{\n#if LV_USE_ANIMATION\n    lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);\n    return ext->anim_time;\n#else\n    (void)bar;       /*Unused*/\n    return 0;\n#endif\n}\n\n/**\n * Get a style of a bar\n * @param bar pointer to a bar object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_bar_get_style(const lv_obj_t * bar, lv_bar_style_t type)\n{\n    const lv_style_t * style = NULL;\n    lv_bar_ext_t * ext       = lv_obj_get_ext_attr(bar);\n\n    switch(type) {\n        case LV_BAR_STYLE_BG: style = lv_obj_get_style(bar); break;\n        case LV_BAR_STYLE_INDIC: style = ext->style_indic; break;\n        default: style = NULL; break;\n    }\n\n    return style;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the bars\n * @param bar pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_bar_design(lv_obj_t * bar, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    if(mode == LV_DESIGN_COVER_CHK) {\n        /*Return false if the object is not covers the mask area*/\n        return ancestor_design_f(bar, mask, mode);\n    } else if(mode == LV_DESIGN_DRAW_MAIN) {\n        lv_opa_t opa_scale = lv_obj_get_opa_scale(bar);\n\n#if LV_USE_GROUP == 0\n        ancestor_design_f(bar, mask, mode);\n#else\n        /* Draw the borders later if the bar is focused.\n         * At value = 100% the indicator can cover to whole background and the focused style won't\n         * be visible*/\n        if(lv_obj_is_focused(bar)) {\n            const lv_style_t * style_bg = lv_bar_get_style(bar, LV_BAR_STYLE_BG);\n            lv_style_t style_tmp;\n            lv_style_copy(&style_tmp, style_bg);\n            style_tmp.body.border.width = 0;\n            lv_draw_rect(&bar->coords, mask, &style_tmp, opa_scale);\n        } else {\n            ancestor_design_f(bar, mask, mode);\n        }\n#endif\n        lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);\n\n        if(ext->cur_value != ext->min_value || ext->sym\n#if LV_USE_ANIMATION\n           || ext->anim_start != LV_BAR_ANIM_STATE_INV\n#endif\n        ) {\n            const lv_style_t * style_indic = lv_bar_get_style(bar, LV_BAR_STYLE_INDIC);\n            lv_area_t indic_area;\n            lv_area_copy(&indic_area, &bar->coords);\n            indic_area.x1 += style_indic->body.padding.left;\n            indic_area.x2 -= style_indic->body.padding.right;\n            indic_area.y1 += style_indic->body.padding.top;\n            indic_area.y2 -= style_indic->body.padding.bottom;\n\n            lv_coord_t w = lv_area_get_width(&indic_area);\n            lv_coord_t h = lv_area_get_height(&indic_area);\n\n            if(w >= h) {\n                /*Horizontal*/\n#if LV_USE_ANIMATION\n                if(ext->anim_state != LV_BAR_ANIM_STATE_INV) {\n                    /*Calculate the coordinates of anim. start and end*/\n                    lv_coord_t anim_start_x =\n                        (int32_t)((int32_t)w * (ext->anim_start - ext->min_value)) / (ext->max_value - ext->min_value);\n                    lv_coord_t anim_end_x =\n                        (int32_t)((int32_t)w * (ext->anim_end - ext->min_value)) / (ext->max_value - ext->min_value);\n\n                    /*Calculate the real position based on `anim_state` (between `anim_start` and\n                     * `anim_end`)*/\n                    indic_area.x2 =\n                        anim_start_x + (((anim_end_x - anim_start_x) * ext->anim_state) >> LV_BAR_ANIM_STATE_NORM);\n                } else\n#endif\n                {\n                    indic_area.x2 =\n                        (int32_t)((int32_t)w * (ext->cur_value - ext->min_value)) / (ext->max_value - ext->min_value);\n                }\n\n                indic_area.x2 = indic_area.x1 + indic_area.x2 - 1;\n                if(ext->sym && ext->min_value < 0 && ext->max_value > 0) {\n                    /*Calculate the coordinate of the zero point*/\n                    lv_coord_t zero;\n                    zero = indic_area.x1 + (-ext->min_value * w) / (ext->max_value - ext->min_value);\n                    if(indic_area.x2 > zero)\n                        indic_area.x1 = zero;\n                    else {\n                        indic_area.x1 = indic_area.x2;\n                        indic_area.x2 = zero;\n                    }\n                }\n            } else {\n#if LV_USE_ANIMATION\n                if(ext->anim_state != LV_BAR_ANIM_STATE_INV) {\n                    /*Calculate the coordinates of anim. start and end*/\n                    lv_coord_t anim_start_y =\n                        (int32_t)((int32_t)h * (ext->anim_start - ext->min_value)) / (ext->max_value - ext->min_value);\n                    lv_coord_t anim_end_y =\n                        (int32_t)((int32_t)h * (ext->anim_end - ext->min_value)) / (ext->max_value - ext->min_value);\n\n                    /*Calculate the real position based on `anim_state` (between `anim_start` and\n                     * `anim_end`)*/\n                    indic_area.y1 =\n                        anim_start_y + (((anim_end_y - anim_start_y) * ext->anim_state) >> LV_BAR_ANIM_STATE_NORM);\n                } else\n#endif\n                {\n                    indic_area.y1 =\n                        (int32_t)((int32_t)h * (ext->cur_value - ext->min_value)) / (ext->max_value - ext->min_value);\n                }\n\n                indic_area.y1 = indic_area.y2 - indic_area.y1 + 1;\n\n                if(ext->sym && ext->min_value < 0 && ext->max_value > 0) {\n                    /*Calculate the coordinate of the zero point*/\n                    lv_coord_t zero;\n                    zero = indic_area.y2 - (-ext->min_value * h) / (ext->max_value - ext->min_value);\n                    if(indic_area.y1 < zero)\n                        indic_area.y2 = zero;\n                    else {\n                        indic_area.y2 = indic_area.y1;\n                        indic_area.y1 = zero;\n                    }\n                }\n            }\n\n            /*Draw the indicator*/\n            lv_draw_rect(&indic_area, mask, style_indic, opa_scale);\n        }\n    } else if(mode == LV_DESIGN_DRAW_POST) {\n#if LV_USE_GROUP\n        /*Draw the border*/\n        if(lv_obj_is_focused(bar)) {\n            lv_opa_t opa_scale          = lv_obj_get_opa_scale(bar);\n            const lv_style_t * style_bg = lv_bar_get_style(bar, LV_BAR_STYLE_BG);\n            lv_style_t style_tmp;\n            lv_style_copy(&style_tmp, style_bg);\n            style_tmp.body.opa          = LV_OPA_TRANSP;\n            style_tmp.body.shadow.width = 0;\n            lv_draw_rect(&bar->coords, mask, &style_tmp, opa_scale);\n        }\n#endif\n    }\n    return true;\n}\n\n/**\n * Signal function of the bar\n * @param bar pointer to a bar object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(bar, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {\n        const lv_style_t * style_indic = lv_bar_get_style(bar, LV_BAR_STYLE_INDIC);\n        if(style_indic->body.shadow.width > bar->ext_draw_pad) bar->ext_draw_pad = style_indic->body.shadow.width;\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_bar\";\n    }\n\n    return res;\n}\n\n#if LV_USE_ANIMATION\nstatic void lv_bar_anim(void * bar, lv_anim_value_t value)\n{\n    lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);\n    ext->anim_state    = value;\n    lv_obj_invalidate(bar);\n}\n\nstatic void lv_bar_anim_ready(lv_anim_t * a)\n{\n    lv_bar_ext_t * ext = lv_obj_get_ext_attr(a->var);\n    ext->anim_state    = LV_BAR_ANIM_STATE_INV;\n    lv_bar_set_value(a->var, ext->anim_end, false);\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_btn.c",
    "content": "/**\n * @file lv_btn.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n\n#include \"libs/lvgl/lv_objx/lv_btn.h\"\n#if LV_USE_BTN != 0\n\n#include <string.h>\n#include \"libs/lvgl/lv_core/lv_group.h\"\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_misc/lv_area.h\"\n#include \"libs/lvgl/lv_misc/lv_color.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_BTN_INK_VALUE_MAX 256\n#define LV_BTN_INK_VALUE_MAX_SHIFT 8\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_btn_design(lv_obj_t * btn, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param);\n\n#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT\nstatic void lv_btn_ink_effect_anim(lv_obj_t * btn, lv_anim_value_t val);\nstatic void lv_btn_ink_effect_anim_ready(lv_anim_t * a);\n#endif\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\nstatic lv_design_cb_t ancestor_design;\n\n#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT\nstatic lv_coord_t ink_act_value;\nstatic lv_obj_t * ink_obj;\nstatic lv_btn_state_t ink_bg_state;\nstatic lv_btn_state_t ink_top_state;\nstatic bool ink_ready;\nstatic bool ink_playback;\nstatic lv_point_t ink_point;\n#endif\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a button object\n * @param par pointer to an object, it will be the parent of the new button\n * @param copy pointer to a button object, if not NULL then the new object will be copied from it\n * @return pointer to the created button\n */\nlv_obj_t * lv_btn_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"button create started\");\n\n    lv_obj_t * new_btn;\n\n    new_btn = lv_cont_create(par, copy);\n    lv_mem_assert(new_btn);\n    if(new_btn == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_btn);\n    if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_btn);\n\n    /*Allocate the extended data*/\n    lv_btn_ext_t * ext = lv_obj_allocate_ext_attr(new_btn, sizeof(lv_btn_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    ext->state = LV_BTN_STATE_REL;\n\n    ext->styles[LV_BTN_STATE_REL]     = &lv_style_btn_rel;\n    ext->styles[LV_BTN_STATE_PR]      = &lv_style_btn_pr;\n    ext->styles[LV_BTN_STATE_TGL_REL] = &lv_style_btn_tgl_rel;\n    ext->styles[LV_BTN_STATE_TGL_PR]  = &lv_style_btn_tgl_pr;\n    ext->styles[LV_BTN_STATE_INA]     = &lv_style_btn_ina;\n\n    ext->toggle = 0;\n#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT\n    ext->ink_in_time   = 0;\n    ext->ink_wait_time = 0;\n    ext->ink_out_time  = 0;\n#endif\n\n    lv_obj_set_signal_cb(new_btn, lv_btn_signal);\n    lv_obj_set_design_cb(new_btn, lv_btn_design);\n\n    /*If no copy do the basic initialization*/\n    if(copy == NULL) {\n        /*Set layout if the button is not a screen*/\n        if(par != NULL) {\n            lv_btn_set_layout(new_btn, LV_LAYOUT_CENTER);\n        }\n\n        lv_obj_set_click(new_btn, true); /*Be sure the button is clickable*/\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_btn_set_style(new_btn, LV_BTN_STYLE_REL, th->style.btn.rel);\n            lv_btn_set_style(new_btn, LV_BTN_STYLE_PR, th->style.btn.pr);\n            lv_btn_set_style(new_btn, LV_BTN_STYLE_TGL_REL, th->style.btn.tgl_rel);\n            lv_btn_set_style(new_btn, LV_BTN_STYLE_TGL_PR, th->style.btn.tgl_pr);\n            lv_btn_set_style(new_btn, LV_BTN_STYLE_INA, th->style.btn.ina);\n        } else {\n            lv_obj_set_style(new_btn, ext->styles[LV_BTN_STATE_REL]);\n        }\n    }\n    /*Copy 'copy'*/\n    else {\n        lv_btn_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->state              = copy_ext->state;\n        ext->toggle             = copy_ext->toggle;\n#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT\n        ext->ink_in_time   = copy_ext->ink_in_time;\n        ext->ink_wait_time = copy_ext->ink_wait_time;\n        ext->ink_out_time  = copy_ext->ink_out_time;\n#endif\n        memcpy(ext->styles, copy_ext->styles, sizeof(ext->styles));\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_btn);\n    }\n\n    LV_LOG_INFO(\"button created\");\n\n    return new_btn;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Enable the toggled states\n * @param btn pointer to a button object\n * @param tgl true: enable toggled states, false: disable\n */\nvoid lv_btn_set_toggle(lv_obj_t * btn, bool tgl)\n{\n    lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);\n\n    ext->toggle = tgl != false ? 1 : 0;\n}\n\n/**\n * Set the state of the button\n * @param btn pointer to a button object\n * @param state the new state of the button (from lv_btn_state_t enum)\n */\nvoid lv_btn_set_state(lv_obj_t * btn, lv_btn_state_t state)\n{\n    lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);\n    if(ext->state != state) {\n        ext->state = state;\n        lv_obj_set_style(btn, ext->styles[state]);\n    }\n}\n\n/**\n * Toggle the state of the button (ON->OFF, OFF->ON)\n * @param btn pointer to a button object\n */\nvoid lv_btn_toggle(lv_obj_t * btn)\n{\n    lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);\n    switch(ext->state) {\n        case LV_BTN_STATE_REL: lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL); break;\n        case LV_BTN_STATE_PR: lv_btn_set_state(btn, LV_BTN_STATE_TGL_PR); break;\n        case LV_BTN_STATE_TGL_REL: lv_btn_set_state(btn, LV_BTN_STATE_REL); break;\n        case LV_BTN_STATE_TGL_PR: lv_btn_set_state(btn, LV_BTN_STATE_PR); break;\n        default: break;\n    }\n}\n\n/**\n * Set time of the ink effect (draw a circle on click to animate in the new state)\n * @param btn pointer to a button object\n * @param time the time of the ink animation\n */\nvoid lv_btn_set_ink_in_time(lv_obj_t * btn, uint16_t time)\n{\n#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT\n    lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);\n    ext->ink_in_time   = time;\n#else\n    (void)btn;  /*Unused*/\n    (void)time; /*Unused*/\n    LV_LOG_WARN(\"`lv_btn_set_ink_ink_time` has no effect if LV_BTN_INK_EFEFCT or LV_USE_ANIMATION \"\n                \"is disabled\")\n#endif\n}\n\n/**\n * Set the wait time before the ink disappears\n * @param btn pointer to a button object\n * @param time the time of the ink animation\n */\nvoid lv_btn_set_ink_wait_time(lv_obj_t * btn, uint16_t time)\n{\n\n#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT\n    lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);\n    ext->ink_wait_time = time;\n#else\n    (void)btn;  /*Unused*/\n    (void)time; /*Unused*/\n    LV_LOG_WARN(\"`lv_btn_set_ink_wait_time` has no effect if LV_BTN_INK_EFEFCT or LV_USE_ANIMATION \"\n                \"is disabled\")\n#endif\n}\n\n/**\n * Set time of the ink out effect (animate to the released state)\n * @param btn pointer to a button object\n * @param time the time of the ink animation\n */\nvoid lv_btn_set_ink_out_time(lv_obj_t * btn, uint16_t time)\n{\n#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT\n    lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);\n    ext->ink_out_time  = time;\n#else\n    (void)btn;  /*Unused*/\n    (void)time; /*Unused*/\n    LV_LOG_WARN(\"`lv_btn_set_ink_out_time` has no effect if LV_BTN_INK_EFEFCT or LV_USE_ANIMATION \"\n                \"is disabled\")\n#endif\n}\n\n/**\n * Set a style of a button\n * @param btn pointer to a button object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_btn_set_style(lv_obj_t * btn, lv_btn_style_t type, const lv_style_t * style)\n{\n    lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);\n\n    switch(type) {\n        case LV_BTN_STYLE_REL: ext->styles[LV_BTN_STATE_REL] = style; break;\n        case LV_BTN_STYLE_PR: ext->styles[LV_BTN_STATE_PR] = style; break;\n        case LV_BTN_STYLE_TGL_REL: ext->styles[LV_BTN_STATE_TGL_REL] = style; break;\n        case LV_BTN_STYLE_TGL_PR: ext->styles[LV_BTN_STATE_TGL_PR] = style; break;\n        case LV_BTN_STYLE_INA: ext->styles[LV_BTN_STATE_INA] = style; break;\n    }\n\n    /*Refresh the object with the new style*/\n    lv_obj_set_style(btn, ext->styles[ext->state]);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the current state of the button\n * @param btn pointer to a button object\n * @return the state of the button (from lv_btn_state_t enum)\n */\nlv_btn_state_t lv_btn_get_state(const lv_obj_t * btn)\n{\n    lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);\n    return ext->state;\n}\n\n/**\n * Get the toggle enable attribute of the button\n * @param btn pointer to a button object\n * @return true: toggle enabled, false: disabled\n */\nbool lv_btn_get_toggle(const lv_obj_t * btn)\n{\n    lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);\n\n    return ext->toggle != 0 ? true : false;\n}\n\n/**\n * Get time of the ink in effect (draw a circle on click to animate in the new state)\n * @param btn pointer to a button object\n * @return the time of the ink animation\n */\nuint16_t lv_btn_get_ink_in_time(const lv_obj_t * btn)\n{\n#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT\n    lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);\n    return ext->ink_in_time;\n#else\n    (void)btn; /*Unused*/\n    return 0;\n#endif\n}\n\n/**\n * Get the wait time before the ink disappears\n * @param btn pointer to a button object\n * @return the time of the ink animation\n */\nuint16_t lv_btn_get_ink_wait_time(const lv_obj_t * btn)\n{\n#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT\n    lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);\n    return ext->ink_wait_time;\n#else\n    (void)btn; /*Unused*/\n    return 0;\n#endif\n}\n/**\n * Get time of the ink out effect (animate to the releases state)\n * @param btn pointer to a button object\n * @return the time of the ink animation\n */\nuint16_t lv_btn_get_ink_out_time(const lv_obj_t * btn)\n{\n#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT\n    lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);\n    return ext->ink_in_time;\n#else\n    (void)btn; /*Unused*/\n    return 0;\n#endif\n}\n\n/**\n * Get a style of a button\n * @param btn pointer to a button object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_btn_get_style(const lv_obj_t * btn, lv_btn_style_t type)\n{\n    const lv_style_t * style = NULL;\n    lv_btn_ext_t * ext       = lv_obj_get_ext_attr(btn);\n    lv_btn_state_t state     = lv_btn_get_state(btn);\n\n    /* If the style of the current state is asked then return object style.\n     * If the button is focused then this style is updated by the group's\n     * `style_mod_cb` function */\n    if((type == LV_BTN_STYLE_REL && state == LV_BTN_STATE_REL) ||\n       (type == LV_BTN_STYLE_PR && state == LV_BTN_STATE_PR) ||\n       (type == LV_BTN_STYLE_TGL_REL && state == LV_BTN_STATE_TGL_REL) ||\n       (type == LV_BTN_STYLE_TGL_PR && state == LV_BTN_STATE_TGL_PR) ||\n       (type == LV_BTN_STYLE_INA && state == LV_BTN_STATE_INA)) {\n\n        style = lv_obj_get_style(btn);\n    } else {\n        switch(type) {\n            case LV_BTN_STYLE_REL: style = ext->styles[LV_BTN_STATE_REL]; break;\n            case LV_BTN_STYLE_PR: style = ext->styles[LV_BTN_STATE_PR]; break;\n            case LV_BTN_STYLE_TGL_REL: style = ext->styles[LV_BTN_STATE_TGL_REL]; break;\n            case LV_BTN_STYLE_TGL_PR: style = ext->styles[LV_BTN_STATE_TGL_PR]; break;\n            case LV_BTN_STYLE_INA: style = ext->styles[LV_BTN_STATE_INA]; break;\n            default: style = NULL; break;\n        }\n    }\n\n    return style;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the drop down lists\n * @param btn pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_btn_design(lv_obj_t * btn, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    if(mode == LV_DESIGN_COVER_CHK) {\n        return false;\n    } else if(mode == LV_DESIGN_DRAW_MAIN) {\n\n#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT\n        if(btn != ink_obj) {\n            ancestor_design(btn, mask, mode);\n        } else {\n            lv_opa_t opa_scale = lv_obj_get_opa_scale(btn);\n            lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);\n\n            /*Draw the normal button*/\n            if(ink_playback == false) {\n                lv_style_t style_tmp;\n                lv_style_copy(&style_tmp, ext->styles[ink_bg_state]);\n                style_tmp.body.shadow.width = ext->styles[ink_top_state]->body.shadow.width;\n                lv_draw_rect(&btn->coords, mask, &style_tmp, opa_scale);\n\n                lv_coord_t w     = lv_obj_get_width(btn);\n                lv_coord_t h     = lv_obj_get_height(btn);\n                lv_coord_t r_max = LV_MATH_MIN(w, h) / 2;\n\n                /*In the first part of the animation increase the size of the circle (ink effect) */\n                lv_area_t cir_area;\n\n                lv_coord_t coord_state =\n                    ink_act_value < LV_BTN_INK_VALUE_MAX / 2 ? ink_act_value : LV_BTN_INK_VALUE_MAX / 2;\n                lv_point_t p_act;\n                p_act.x          = ink_point.x;\n                p_act.y          = ink_point.y;\n                lv_coord_t x_err = (btn->coords.x1 + w / 2) - p_act.x;\n                lv_coord_t y_err = (btn->coords.y1 + h / 2) - p_act.y;\n\n                p_act.x += (x_err * coord_state) >> (LV_BTN_INK_VALUE_MAX_SHIFT - 1);\n                p_act.y += (y_err * coord_state) >> (LV_BTN_INK_VALUE_MAX_SHIFT - 1);\n\n                lv_coord_t half_side = LV_MATH_MAX(w, h) / 2;\n                cir_area.x1          = p_act.x - ((half_side * coord_state) >> (LV_BTN_INK_VALUE_MAX_SHIFT - 1));\n                cir_area.y1          = p_act.y - ((half_side * coord_state) >> (LV_BTN_INK_VALUE_MAX_SHIFT - 1));\n                cir_area.x2          = p_act.x + ((half_side * coord_state) >> (LV_BTN_INK_VALUE_MAX_SHIFT - 1));\n                cir_area.y2          = p_act.y + ((half_side * coord_state) >> (LV_BTN_INK_VALUE_MAX_SHIFT - 1));\n\n                lv_area_intersect(&cir_area, &btn->coords,\n                                  &cir_area); /*Limit the area. (It might be too big on the smaller side)*/\n\n                /*In the second part animate the radius. Circle -> body.radius*/\n                lv_coord_t r_state =\n                    ink_act_value > LV_BTN_INK_VALUE_MAX / 2 ? ink_act_value - LV_BTN_INK_VALUE_MAX / 2 : 0;\n\n                lv_style_copy(&style_tmp, ext->styles[ink_top_state]);\n                style_tmp.body.radius       = r_max + (((ext->styles[ink_bg_state]->body.radius - r_max) * r_state) >>\n                                                 (LV_BTN_INK_VALUE_MAX_SHIFT - 1));\n                style_tmp.body.border.width = 0;\n\n                /*Draw the circle*/\n                lv_draw_rect(&cir_area, mask, &style_tmp, opa_scale);\n            } else {\n                lv_style_t res;\n                lv_style_copy(&res, ext->styles[ink_bg_state]);\n                lv_style_mix(ext->styles[ink_bg_state], ext->styles[ink_top_state], &res, ink_act_value);\n                lv_draw_rect(&btn->coords, mask, &res, opa_scale);\n            }\n        }\n#else\n        ancestor_design(btn, mask, mode);\n#endif\n    } else if(mode == LV_DESIGN_DRAW_POST) {\n        ancestor_design(btn, mask, mode);\n    }\n\n    return true;\n}\n\n/**\n * Signal function of the button\n * @param btn pointer to a button object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(btn, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);\n    bool tgl           = lv_btn_get_toggle(btn);\n\n    if(sign == LV_SIGNAL_PRESSED) {\n        /*Refresh the state*/\n        if(ext->state == LV_BTN_STATE_REL) {\n            lv_btn_set_state(btn, LV_BTN_STATE_PR);\n#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT\n            ink_bg_state  = LV_BTN_STATE_REL;\n            ink_top_state = LV_BTN_STATE_PR;\n#endif\n        } else if(ext->state == LV_BTN_STATE_TGL_REL) {\n            lv_btn_set_state(btn, LV_BTN_STATE_TGL_PR);\n#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT\n            ink_bg_state  = LV_BTN_STATE_TGL_REL;\n            ink_top_state = LV_BTN_STATE_TGL_PR;\n#endif\n        }\n\n#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT\n        /*Forget the old inked button*/\n        if(ink_obj != NULL && ink_obj != btn) {\n            lv_anim_del(ink_obj, (lv_anim_exec_xcb_t)lv_btn_ink_effect_anim);\n            lv_obj_invalidate(ink_obj);\n            ink_obj = NULL;\n        }\n        /*Save the new data for inking and start it's animation if enabled*/\n        if(ext->ink_in_time > 0) {\n            ink_obj      = btn;\n            ink_playback = false;\n            ink_ready    = false;\n            lv_indev_get_point(lv_indev_get_act(), &ink_point);\n\n            lv_anim_t a;\n            a.var            = btn;\n            a.start          = 0;\n            a.end            = LV_BTN_INK_VALUE_MAX;\n            a.exec_cb        = (lv_anim_exec_xcb_t)lv_btn_ink_effect_anim;\n            a.path_cb        = lv_anim_path_linear;\n            a.ready_cb       = lv_btn_ink_effect_anim_ready;\n            a.act_time       = 0;\n            a.time           = ext->ink_in_time;\n            a.playback       = 0;\n            a.playback_pause = 0;\n            a.repeat         = 0;\n            a.repeat_pause   = 0;\n            lv_anim_create(&a);\n        }\n#endif\n    } else if(sign == LV_SIGNAL_PRESS_LOST) {\n        /*Refresh the state*/\n        if(ext->state == LV_BTN_STATE_PR)\n            lv_btn_set_state(btn, LV_BTN_STATE_REL);\n        else if(ext->state == LV_BTN_STATE_TGL_PR)\n            lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);\n    } else if(sign == LV_SIGNAL_PRESSING) {\n        /*When the button begins to drag revert pressed states to released*/\n        if(lv_indev_is_dragging(param) != false) {\n            if(ext->state == LV_BTN_STATE_PR)\n                lv_btn_set_state(btn, LV_BTN_STATE_REL);\n            else if(ext->state == LV_BTN_STATE_TGL_PR)\n                lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);\n        }\n    } else if(sign == LV_SIGNAL_RELEASED) {\n        /*If not dragged and it was not long press action then\n         *change state and run the action*/\n        if(lv_indev_is_dragging(param) == false) {\n            uint32_t toggled = 0;\n            if(ext->state == LV_BTN_STATE_PR && tgl == false) {\n                lv_btn_set_state(btn, LV_BTN_STATE_REL);\n                toggled = 0;\n            } else if(ext->state == LV_BTN_STATE_TGL_PR && tgl == false) {\n                lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);\n                toggled = 1;\n            } else if(ext->state == LV_BTN_STATE_PR && tgl == true) {\n                lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);\n                toggled = 1;\n            } else if(ext->state == LV_BTN_STATE_TGL_PR && tgl == true) {\n                lv_btn_set_state(btn, LV_BTN_STATE_REL);\n                toggled = 0;\n            }\n\n            if(tgl) {\n                res = lv_event_send(btn, LV_EVENT_VALUE_CHANGED, &toggled);\n                if(res != LV_RES_OK) return res;\n            }\n\n        } else { /*If dragged change back the state*/\n            if(ext->state == LV_BTN_STATE_PR) {\n                lv_btn_set_state(btn, LV_BTN_STATE_REL);\n            } else if(ext->state == LV_BTN_STATE_TGL_PR) {\n                lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);\n            }\n        }\n\n#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT\n        /*Draw the toggled state in the inking instead*/\n        if(ext->toggle) {\n            ink_top_state = ext->state;\n        }\n        /*If not a toggle button and the \"IN\" inking is ready then start an \"OUT\" inking*/\n        else if(ink_ready && ext->ink_out_time > 0) {\n            ink_obj      = btn;\n            ink_playback = true; /*It is the playback. If not set `lv_btn_ink_effect_anim_ready`\n                                    will start its own playback*/\n            lv_indev_get_point(lv_indev_get_act(), &ink_point);\n\n            lv_anim_t a;\n            a.var            = ink_obj;\n            a.start          = LV_BTN_INK_VALUE_MAX;\n            a.end            = 0;\n            a.exec_cb        = (lv_anim_exec_xcb_t)lv_btn_ink_effect_anim;\n            a.path_cb        = lv_anim_path_linear;\n            a.ready_cb       = lv_btn_ink_effect_anim_ready;\n            a.act_time       = 0;\n            a.time           = ext->ink_out_time;\n            a.playback       = 0;\n            a.playback_pause = 0;\n            a.repeat         = 0;\n            a.repeat_pause   = 0;\n            lv_anim_create(&a);\n        }\n#endif\n    } else if(sign == LV_SIGNAL_CONTROL) {\n        char c = *((char *)param);\n        if(c == LV_KEY_RIGHT || c == LV_KEY_UP) {\n            if(lv_btn_get_toggle(btn)) {\n                lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);\n\n                uint32_t state = 1;\n                res            = lv_event_send(btn, LV_EVENT_VALUE_CHANGED, &state);\n                if(res != LV_RES_OK) return res;\n            }\n\n        } else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) {\n            if(lv_btn_get_toggle(btn)) {\n                lv_btn_set_state(btn, LV_BTN_STATE_REL);\n\n                uint32_t state = 0;\n                res            = lv_event_send(btn, LV_EVENT_VALUE_CHANGED, &state);\n                if(res != LV_RES_OK) return res;\n            }\n        }\n    } else if(sign == LV_SIGNAL_CLEANUP) {\n#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT\n        if(btn == ink_obj) {\n            lv_anim_del(ink_obj, (lv_anim_exec_xcb_t)lv_btn_ink_effect_anim);\n            ink_obj = NULL;\n        }\n#endif\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_btn\";\n    }\n\n    return res;\n}\n\n#if LV_USE_ANIMATION && LV_BTN_INK_EFFECT\n\n/**\n * The animator function of inking. CAlled to increase the radius of ink\n * @param btn pointer to the animated button\n * @param val the new radius\n */\nstatic void lv_btn_ink_effect_anim(lv_obj_t * btn, lv_anim_value_t val)\n{\n    if(btn) {\n        ink_act_value = val;\n        lv_obj_invalidate(btn);\n    }\n}\n\n/**\n * Called to clean up when the ink animation is ready\n * @param a unused\n */\nstatic void lv_btn_ink_effect_anim_ready(lv_anim_t * a)\n{\n    (void)a; /*Unused*/\n\n    lv_btn_ext_t * ext   = lv_obj_get_ext_attr(ink_obj);\n    lv_btn_state_t state = lv_btn_get_state(ink_obj);\n\n    lv_obj_invalidate(ink_obj);\n    ink_ready = true;\n\n    if((state == LV_BTN_STATE_REL || state == LV_BTN_STATE_TGL_REL) && ext->toggle == 0 && ink_playback == false) {\n        lv_anim_t new_a;\n        new_a.var            = ink_obj;\n        new_a.start          = LV_BTN_INK_VALUE_MAX;\n        new_a.end            = 0;\n        new_a.exec_cb        = (lv_anim_exec_xcb_t)lv_btn_ink_effect_anim;\n        new_a.path_cb        = lv_anim_path_linear;\n        new_a.ready_cb       = lv_btn_ink_effect_anim_ready;\n        new_a.act_time       = -ext->ink_wait_time;\n        new_a.time           = ext->ink_out_time;\n        new_a.playback       = 0;\n        new_a.playback_pause = 0;\n        new_a.repeat         = 0;\n        new_a.repeat_pause   = 0;\n        lv_anim_create(&new_a);\n\n        ink_playback = true;\n    } else {\n        ink_obj = NULL;\n    }\n}\n#endif /*LV_USE_ANIMATION*/\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_btnm.c",
    "content": "/**\n * @file lv_btnm.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_btnm.h\"\n#if LV_USE_BTNM != 0\n\n#include \"libs/lvgl/lv_core/lv_group.h\"\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_core/lv_refr.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_misc/lv_txt.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param);\nstatic bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mode_t mode);\nstatic uint8_t get_button_width(lv_btnm_ctrl_t ctrl_bits);\nstatic bool button_is_hidden(lv_btnm_ctrl_t ctrl_bits);\nstatic bool button_is_repeat_disabled(lv_btnm_ctrl_t ctrl_bits);\nstatic bool button_is_inactive(lv_btnm_ctrl_t ctrl_bits);\nstatic bool button_is_click_trig(lv_btnm_ctrl_t ctrl_bits);\nstatic bool button_is_tgl_enabled(lv_btnm_ctrl_t ctrl_bits);\nstatic bool button_get_tgl_state(lv_btnm_ctrl_t ctrl_bits);\nstatic uint16_t get_button_from_point(lv_obj_t * btnm, lv_point_t * p);\nstatic void allocate_btn_areas_and_controls(const lv_obj_t * btnm, const char ** map);\nstatic void invalidate_button_area(const lv_obj_t * btnm, uint16_t btn_idx);\nstatic bool maps_are_identical(const char ** map1, const char ** map2);\nstatic void make_one_button_toggled(lv_obj_t * btnm, uint16_t btn_idx);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic const char * lv_btnm_def_map[] = {\"Btn1\", \"Btn2\", \"Btn3\", \"\\n\", \"Btn4\", \"Btn5\", \"\"};\n\nstatic lv_design_cb_t ancestor_design_f;\nstatic lv_signal_cb_t ancestor_signal;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a button matrix objects\n * @param par pointer to an object, it will be the parent of the new button matrix\n * @param copy pointer to a button matrix object, if not NULL then the new object will be copied\n * from it\n * @return pointer to the created button matrix\n */\nlv_obj_t * lv_btnm_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"button matrix create started\");\n\n    /*Create the ancestor object*/\n    lv_obj_t * new_btnm = lv_obj_create(par, copy);\n    lv_mem_assert(new_btnm);\n    if(new_btnm == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_btnm);\n\n    /*Allocate the object type specific extended data*/\n    lv_btnm_ext_t * ext = lv_obj_allocate_ext_attr(new_btnm, sizeof(lv_btnm_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    ext->btn_cnt                          = 0;\n    ext->btn_id_pr                        = LV_BTNM_BTN_NONE;\n    ext->btn_id_act                       = LV_BTNM_BTN_NONE;\n    ext->button_areas                     = NULL;\n    ext->ctrl_bits                        = NULL;\n    ext->map_p                            = NULL;\n    ext->recolor                          = 0;\n    ext->one_toggle                       = 0;\n    ext->styles_btn[LV_BTN_STATE_REL]     = &lv_style_btn_rel;\n    ext->styles_btn[LV_BTN_STATE_PR]      = &lv_style_btn_pr;\n    ext->styles_btn[LV_BTN_STATE_TGL_REL] = &lv_style_btn_tgl_rel;\n    ext->styles_btn[LV_BTN_STATE_TGL_PR]  = &lv_style_btn_tgl_pr;\n    ext->styles_btn[LV_BTN_STATE_INA]     = &lv_style_btn_ina;\n\n    if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_cb(new_btnm);\n\n    lv_obj_set_signal_cb(new_btnm, lv_btnm_signal);\n    lv_obj_set_design_cb(new_btnm, lv_btnm_design);\n\n    /*Init the new button matrix object*/\n    if(copy == NULL) {\n        lv_obj_set_size(new_btnm, LV_DPI * 3, LV_DPI * 2);\n        lv_btnm_set_map(new_btnm, lv_btnm_def_map);\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_btnm_set_style(new_btnm, LV_BTNM_STYLE_BG, th->style.btnm.bg);\n            lv_btnm_set_style(new_btnm, LV_BTNM_STYLE_BTN_REL, th->style.btnm.btn.rel);\n            lv_btnm_set_style(new_btnm, LV_BTNM_STYLE_BTN_PR, th->style.btnm.btn.pr);\n            lv_btnm_set_style(new_btnm, LV_BTNM_STYLE_BTN_TGL_REL, th->style.btnm.btn.tgl_rel);\n            lv_btnm_set_style(new_btnm, LV_BTNM_STYLE_BTN_TGL_PR, th->style.btnm.btn.tgl_pr);\n            lv_btnm_set_style(new_btnm, LV_BTNM_STYLE_BTN_INA, th->style.btnm.btn.ina);\n        } else {\n            lv_obj_set_style(new_btnm, &lv_style_pretty);\n        }\n    }\n    /*Copy an existing object*/\n    else {\n        lv_btnm_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        memcpy(ext->styles_btn, copy_ext->styles_btn, sizeof(ext->styles_btn));\n        lv_btnm_set_map(new_btnm, lv_btnm_get_map_array(copy));\n    }\n\n    LV_LOG_INFO(\"button matrix created\");\n\n    return new_btnm;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a new map. Buttons will be created/deleted according to the map. The\n * button matrix keeps a reference to the map and so the string array must not\n * be deallocated during the life of the matrix.\n * @param btnm pointer to a button matrix object\n * @param map pointer a string array. The last string has to be: \"\". Use \"\\n\" to make a line break.\n */\nvoid lv_btnm_set_map(const lv_obj_t * btnm, const char * map[])\n{\n    if(map == NULL) return;\n\n    /*\n     * lv_btnm_set_map is called on receipt of signals such as\n     * LV_SIGNAL_CORD_CHG regardless of whether the map has changed (e.g.\n     * calling lv_obj_align on the map will trigger this).\n     *\n     * We check if the map has changed here to avoid overwriting changes made\n     * to hidden/longpress/disabled states after the map was originally set.\n     *\n     * TODO: separate all map set/allocation from layout code below and skip\n     * set/allocation when map hasn't changed.\n     */\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n    if(!maps_are_identical(ext->map_p, map)) {\n\n        /*Analyze the map and create the required number of buttons*/\n        allocate_btn_areas_and_controls(btnm, map);\n    }\n    ext->map_p = map;\n\n    /*Set size and positions of the buttons*/\n    const lv_style_t * style_bg = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BG);\n    lv_coord_t max_w            = lv_obj_get_width(btnm) - style_bg->body.padding.left - style_bg->body.padding.right;\n    lv_coord_t max_h            = lv_obj_get_height(btnm) - style_bg->body.padding.top - style_bg->body.padding.bottom;\n    lv_coord_t act_y            = style_bg->body.padding.top;\n\n    /*Count the lines to calculate button height*/\n    uint8_t line_cnt = 1;\n    uint8_t li;\n    for(li = 0; strlen(map[li]) != 0; li++) {\n        if(strcmp(map[li], \"\\n\") == 0) line_cnt++;\n    }\n\n    lv_coord_t btn_h = max_h - ((line_cnt - 1) * style_bg->body.padding.inner);\n    btn_h            = btn_h / line_cnt;\n    btn_h--; /*-1 because e.g. height = 100 means 101 pixels (0..100)*/\n\n    /* Count the units and the buttons in a line\n     * (A button can be 1,2,3... unit wide)*/\n    uint16_t unit_cnt;           /*Number of units in a row*/\n    uint16_t unit_act_cnt;       /*Number of units currently put in a row*/\n    uint16_t btn_cnt;            /*Number of buttons in a row*/\n    uint16_t i_tot          = 0; /*Act. index in the str map*/\n    uint16_t btn_i          = 0; /*Act. index of button areas*/\n    const char ** map_p_tmp = map;\n\n    /*Count the units and the buttons in a line*/\n    while(1) {\n        unit_cnt = 0;\n        btn_cnt  = 0;\n        /*Count the buttons in a line*/\n        while(strcmp(map_p_tmp[btn_cnt], \"\\n\") != 0 && strlen(map_p_tmp[btn_cnt]) != 0) { /*Check a line*/\n            unit_cnt += get_button_width(ext->ctrl_bits[btn_i + btn_cnt]);\n            btn_cnt++;\n        }\n\n        /*Make sure the last row is at the bottom of 'btnm'*/\n        if(map_p_tmp[btn_cnt][0] == '\\0') { /*Last row?*/\n            btn_h = max_h - act_y + style_bg->body.padding.bottom - 1;\n        }\n\n        /*Only deal with the non empty lines*/\n        if(btn_cnt != 0) {\n            /*Calculate the width of all units*/\n            lv_coord_t all_unit_w = max_w - ((btn_cnt - 1) * style_bg->body.padding.inner);\n\n            /*Set the button size and positions and set the texts*/\n            uint16_t i;\n            lv_coord_t act_x = style_bg->body.padding.left;\n            lv_coord_t act_unit_w;\n            unit_act_cnt = 0;\n            for(i = 0; i < btn_cnt; i++) {\n                /* one_unit_w = all_unit_w / unit_cnt\n                 * act_unit_w = one_unit_w * button_width\n                 * do this two operations but the multiply first to divide a greater number */\n                act_unit_w = (all_unit_w * get_button_width(ext->ctrl_bits[btn_i])) / unit_cnt;\n                act_unit_w--; /*-1 because e.g. width = 100 means 101 pixels (0..100)*/\n\n                /*Always recalculate act_x because of rounding errors */\n                act_x = (unit_act_cnt * all_unit_w) / unit_cnt + i * style_bg->body.padding.inner +\n                        style_bg->body.padding.left;\n\n                /* Set the button's area.\n                 * If inner padding is zero then use the prev. button x2 as x1 to avoid rounding\n                 * errors*/\n                if(style_bg->body.padding.inner == 0 && act_x != style_bg->body.padding.left) {\n                    lv_area_set(&ext->button_areas[btn_i], ext->button_areas[btn_i - 1].x2, act_y, act_x + act_unit_w,\n                                act_y + btn_h);\n                } else {\n                    lv_area_set(&ext->button_areas[btn_i], act_x, act_y, act_x + act_unit_w, act_y + btn_h);\n                }\n\n                unit_act_cnt += get_button_width(ext->ctrl_bits[btn_i]);\n\n                i_tot++;\n                btn_i++;\n            }\n        }\n        act_y += btn_h + style_bg->body.padding.inner;\n\n        if(strlen(map_p_tmp[btn_cnt]) == 0) break; /*Break on end of map*/\n        map_p_tmp = &map_p_tmp[btn_cnt + 1];       /*Set the map to the next line*/\n        i_tot++;                                   /*Skip the '\\n'*/\n    }\n\n    lv_obj_invalidate(btnm);\n}\n\n/**\n * Set the button control map (hidden, disabled etc.) for a button matrix. The\n * control map array will be copied and so may be deallocated after this\n * function returns.\n * @param btnm pointer to a button matrix object\n * @param ctrl_map pointer to an array of `lv_btn_ctrl_t` control bytes. The\n *                 length of the array and position of the elements must match\n *                 the number and order of the individual buttons (i.e. excludes\n *                 newline entries).\n *                 An element of the map should look like e.g.:\n *                 `ctrl_map[0] = width | LV_BTNM_CTRL_NO_REPEAT |  LV_BTNM_CTRL_TGL_ENABLE`\n */\nvoid lv_btnm_set_ctrl_map(const lv_obj_t * btnm, const lv_btnm_ctrl_t ctrl_map[])\n{\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n    memcpy(ext->ctrl_bits, ctrl_map, sizeof(lv_btnm_ctrl_t) * ext->btn_cnt);\n\n    lv_btnm_set_map(btnm, ext->map_p);\n}\n\n/**\n * Set the pressed button i.e. visually highlight it.\n * Mainly used a when the btnm is in a group to show the selected button\n * @param btnm pointer to button matrix object\n * @param id index of the currently pressed button (`LV_BTNM_BTN_NONE` to unpress)\n */\nvoid lv_btnm_set_pressed(const lv_obj_t * btnm, uint16_t id)\n{\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n\n    if(id >= ext->btn_cnt && id != LV_BTNM_BTN_NONE) return;\n\n    if(id == ext->btn_id_pr) return;\n\n    ext->btn_id_pr = id;\n    lv_obj_invalidate(btnm);\n}\n\n/**\n * Set a style of a button matrix\n * @param btnm pointer to a button matrix object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_btnm_set_style(lv_obj_t * btnm, lv_btnm_style_t type, const lv_style_t * style)\n{\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n\n    switch(type) {\n        case LV_BTNM_STYLE_BG: lv_obj_set_style(btnm, style); break;\n        case LV_BTNM_STYLE_BTN_REL:\n            ext->styles_btn[LV_BTN_STATE_REL] = style;\n            lv_obj_invalidate(btnm);\n            break;\n        case LV_BTNM_STYLE_BTN_PR:\n            ext->styles_btn[LV_BTN_STATE_PR] = style;\n            lv_obj_invalidate(btnm);\n            break;\n        case LV_BTNM_STYLE_BTN_TGL_REL:\n            ext->styles_btn[LV_BTN_STATE_TGL_REL] = style;\n            lv_obj_invalidate(btnm);\n            break;\n        case LV_BTNM_STYLE_BTN_TGL_PR:\n            ext->styles_btn[LV_BTN_STATE_TGL_PR] = style;\n            lv_obj_invalidate(btnm);\n            break;\n        case LV_BTNM_STYLE_BTN_INA:\n            ext->styles_btn[LV_BTN_STATE_INA] = style;\n            lv_obj_invalidate(btnm);\n            break;\n    }\n}\n\n/**\n * Enable recoloring of button's texts\n * @param btnm pointer to button matrix object\n * @param en true: enable recoloring; false: disable\n */\nvoid lv_btnm_set_recolor(const lv_obj_t * btnm, bool en)\n{\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n\n    ext->recolor = en;\n    lv_obj_invalidate(btnm);\n}\n\n/**\n * Set the attributes of a button of the button matrix\n * @param btnm pointer to button matrix object\n * @param btn_id 0 based index of the button to modify. (Not counting new lines)\n */\nvoid lv_btnm_set_btn_ctrl(const lv_obj_t * btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl)\n{\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n\n    if(btn_id >= ext->btn_cnt) return;\n\n    ext->ctrl_bits[btn_id] |= ctrl;\n    invalidate_button_area(btnm, btn_id);\n}\n\n/**\n * Clear the attributes of a button of the button matrix\n * @param btnm pointer to button matrix object\n * @param btn_id 0 based index of the button to modify. (Not counting new lines)\n */\nvoid lv_btnm_clear_btn_ctrl(const lv_obj_t * btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl)\n{\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n\n    if(btn_id >= ext->btn_cnt) return;\n\n    ext->ctrl_bits[btn_id] &= (~ctrl);\n    invalidate_button_area(btnm, btn_id);\n}\n\n/**\n * Set the attributes of all buttons of a button matrix\n * @param btnm pointer to a button matrix object\n * @param ctrl attribute(s) to set from `lv_btnm_ctrl_t`. Values can be ORed.\n */\nvoid lv_btnm_set_btn_ctrl_all(lv_obj_t * btnm, lv_btnm_ctrl_t ctrl)\n{\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n    uint16_t i;\n    for(i = 0; i < ext->btn_cnt; i++) {\n        lv_btnm_set_btn_ctrl(btnm, i, ctrl);\n    }\n}\n\n/**\n * Clear the attributes of all buttons of a button matrix\n * @param btnm pointer to a button matrix object\n * @param ctrl attribute(s) to set from `lv_btnm_ctrl_t`. Values can be ORed.\n * @param en true: set the attributes; false: clear the attributes\n */\nvoid lv_btnm_clear_btn_ctrl_all(lv_obj_t * btnm, lv_btnm_ctrl_t ctrl)\n{\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n    uint16_t i;\n    for(i = 0; i < ext->btn_cnt; i++) {\n        lv_btnm_clear_btn_ctrl(btnm, i, ctrl);\n    }\n}\n\n/**\n * Set a single buttons relative width.\n * This method will cause the matrix be regenerated and is a relatively\n * expensive operation. It is recommended that initial width be specified using\n * `lv_btnm_set_ctrl_map` and this method only be used for dynamic changes.\n * @param btnm pointer to button matrix object\n * @param btn_id 0 based index of the button to modify.\n * @param width Relative width compared to the buttons in the same row. [1..7]\n */\nvoid lv_btnm_set_btn_width(const lv_obj_t * btnm, uint16_t btn_id, uint8_t width)\n{\n\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n    if(btn_id >= ext->btn_cnt) return;\n    ext->ctrl_bits[btn_id] &= (~LV_BTNM_WIDTH_MASK);\n    ext->ctrl_bits[btn_id] |= (LV_BTNM_WIDTH_MASK & width);\n\n    lv_btnm_set_map(btnm, ext->map_p);\n}\n\n/**\n * Make the button matrix like a selector widget (only one button may be toggled at a time).\n *\n * Toggling must be enabled on the buttons you want to be selected with `lv_btnm_set_ctrl` or\n * `lv_btnm_set_btn_ctrl_all`.\n *\n * @param btnm Button matrix object\n * @param one_toggle Whether \"one toggle\" mode is enabled\n */\nvoid lv_btnm_set_one_toggle(lv_obj_t * btnm, bool one_toggle)\n{\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n    ext->one_toggle     = one_toggle;\n\n    /*If more than one button is toggled only the first one should be*/\n    make_one_button_toggled(btnm, 0);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the current map of a button matrix\n * @param btnm pointer to a button matrix object\n * @return the current map\n */\nconst char ** lv_btnm_get_map_array(const lv_obj_t * btnm)\n{\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n    return ext->map_p;\n}\n\n/**\n * Check whether the button's text can use recolor or not\n * @param btnm pointer to button matrix object\n * @return true: text recolor enable; false: disabled\n */\nbool lv_btnm_get_recolor(const lv_obj_t * btnm)\n{\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n\n    return ext->recolor;\n}\n\n/**\n * Get the index of the lastly \"activated\" button by the user (pressed, released etc)\n * Useful in the the `event_cb` to get the text of the button, check if hidden etc.\n * @param btnm pointer to button matrix object\n * @return  index of the last released button (LV_BTNM_BTN_NONE: if unset)\n */\nuint16_t lv_btnm_get_active_btn(const lv_obj_t * btnm)\n{\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n    return ext->btn_id_act;\n}\n\n/**\n * Get the text of the lastly \"activated\" button by the user (pressed, released etc)\n * Useful in the the `event_cb`\n * @param btnm pointer to button matrix object\n * @return text of the last released button (NULL: if unset)\n */\nconst char * lv_btnm_get_active_btn_text(const lv_obj_t * btnm)\n{\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n    if(ext->btn_id_act != LV_BTNM_BTN_NONE) {\n        return lv_btnm_get_btn_text(btnm, ext->btn_id_act);\n    } else {\n        return NULL;\n    }\n}\n\n/**\n * Get the pressed button's index.\n * The button be really pressed by the user or manually set to pressed with `lv_btnm_set_pressed`\n * @param btnm pointer to button matrix object\n * @return  index of the pressed button (LV_BTNM_BTN_NONE: if unset)\n */\nuint16_t lv_btnm_get_pressed_btn(const lv_obj_t * btnm)\n{\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n    return ext->btn_id_pr;\n}\n\n/**\n * Get the button's text\n * @param btnm pointer to button matrix object\n * @param btn_id the index a button not counting new line characters. (The return value of\n * lv_btnm_get_pressed/released)\n * @return  text of btn_index` button\n */\nconst char * lv_btnm_get_btn_text(const lv_obj_t * btnm, uint16_t btn_id)\n{\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n    if(btn_id > ext->btn_cnt) return NULL;\n\n    uint16_t txt_i = 0;\n    uint16_t btn_i = 0;\n\n    /* Search the text of ext->btn_pr the buttons text in the map\n     * Skip \"\\n\"-s*/\n    while(btn_i != btn_id) {\n        btn_i++;\n        txt_i++;\n        if(strcmp(ext->map_p[txt_i], \"\\n\") == 0) txt_i++;\n    }\n\n    if(btn_i == ext->btn_cnt) return NULL;\n\n    return ext->map_p[txt_i];\n}\n\n/**\n * Get the whether a control value is enabled or disabled for button of a button matrix\n * @param btnm pointer to a button matrix object\n * @param btn_id the index a button not counting new line characters. (E.g. the return value of\n * lv_btnm_get_pressed/released)\n * @param ctrl control values to check (ORed value can be used)\n * @return true: long press repeat is disabled; false: long press repeat enabled\n */\nbool lv_btnm_get_btn_ctrl(lv_obj_t * btnm, uint16_t btn_id, lv_btnm_ctrl_t ctrl)\n{\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n    if(btn_id >= ext->btn_cnt) return false;\n\n    return ext->ctrl_bits[btn_id] & ctrl ? true : false;\n}\n\n/**\n * Get a style of a button matrix\n * @param btnm pointer to a button matrix object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_btnm_get_style(const lv_obj_t * btnm, lv_btnm_style_t type)\n{\n    const lv_style_t * style = NULL;\n    lv_btnm_ext_t * ext      = lv_obj_get_ext_attr(btnm);\n\n    switch(type) {\n        case LV_BTNM_STYLE_BG: style = lv_obj_get_style(btnm); break;\n        case LV_BTNM_STYLE_BTN_REL: style = ext->styles_btn[LV_BTN_STATE_REL]; break;\n        case LV_BTNM_STYLE_BTN_PR: style = ext->styles_btn[LV_BTN_STATE_PR]; break;\n        case LV_BTNM_STYLE_BTN_TGL_REL: style = ext->styles_btn[LV_BTN_STATE_TGL_REL]; break;\n        case LV_BTNM_STYLE_BTN_TGL_PR: style = ext->styles_btn[LV_BTN_STATE_TGL_PR]; break;\n        case LV_BTNM_STYLE_BTN_INA: style = ext->styles_btn[LV_BTN_STATE_INA]; break;\n        default: style = NULL; break;\n    }\n\n    return style;\n}\n\n/**\n * Find whether \"one toggle\" mode is enabled.\n * @param btnm Button matrix object\n * @return whether \"one toggle\" mode is enabled\n */\nbool lv_btnm_get_one_toggle(const lv_obj_t * btnm)\n{\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n\n    return ext->one_toggle;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the button matrixs\n * @param btnm pointer to a button matrix object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    if(mode == LV_DESIGN_COVER_CHK) {\n        return ancestor_design_f(btnm, mask, mode);\n        /*Return false if the object is not covers the mask_p area*/\n    }\n    /*Draw the object*/\n    else if(mode == LV_DESIGN_DRAW_MAIN) {\n\n        ancestor_design_f(btnm, mask, mode);\n\n        lv_btnm_ext_t * ext         = lv_obj_get_ext_attr(btnm);\n        const lv_style_t * bg_style = lv_obj_get_style(btnm);\n        const lv_style_t * btn_style;\n        lv_opa_t opa_scale = lv_obj_get_opa_scale(btnm);\n\n        lv_area_t area_btnm;\n        lv_obj_get_coords(btnm, &area_btnm);\n\n        lv_area_t area_tmp;\n        lv_coord_t btn_w;\n        lv_coord_t btn_h;\n\n        uint16_t btn_i = 0;\n        uint16_t txt_i = 0;\n        lv_style_t style_tmp;\n        lv_txt_flag_t txt_flag = LV_TXT_FLAG_NONE;\n\n        if(ext->recolor) txt_flag = LV_TXT_FLAG_RECOLOR;\n\n        for(btn_i = 0; btn_i < ext->btn_cnt; btn_i++, txt_i++) {\n            /*Search the next valid text in the map*/\n            while(strcmp(ext->map_p[txt_i], \"\\n\") == 0) {\n                txt_i++;\n            }\n\n            /*Skip hidden buttons*/\n            if(button_is_hidden(ext->ctrl_bits[btn_i])) continue;\n\n            lv_area_copy(&area_tmp, &ext->button_areas[btn_i]);\n            area_tmp.x1 += area_btnm.x1;\n            area_tmp.y1 += area_btnm.y1;\n            area_tmp.x2 += area_btnm.x1;\n            area_tmp.y2 += area_btnm.y1;\n\n            btn_w = lv_area_get_width(&area_tmp);\n            btn_h = lv_area_get_height(&area_tmp);\n\n            /*Load the style*/\n            bool tgl_state = button_get_tgl_state(ext->ctrl_bits[btn_i]);\n            if(button_is_inactive(ext->ctrl_bits[btn_i]))\n                btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_INA);\n            else if(btn_i != ext->btn_id_pr && tgl_state == false)\n                btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_REL);\n            else if(btn_i == ext->btn_id_pr && tgl_state == false)\n                btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_PR);\n            else if(btn_i != ext->btn_id_pr && tgl_state == true)\n                btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_TGL_REL);\n            else if(btn_i == ext->btn_id_pr && tgl_state == true)\n                btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_TGL_PR);\n            else\n                btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_REL); /*Not possible option, just to be sure*/\n\n            lv_style_copy(&style_tmp, btn_style);\n\n            /*Remove borders on the edges if `LV_BORDER_INTERNAL`*/\n            if(style_tmp.body.border.part & LV_BORDER_INTERNAL) {\n                if(area_tmp.y1 == btnm->coords.y1 + bg_style->body.padding.top) {\n                    style_tmp.body.border.part &= ~LV_BORDER_TOP;\n                }\n                if(area_tmp.y2 == btnm->coords.y2 - bg_style->body.padding.bottom) {\n                    style_tmp.body.border.part &= ~LV_BORDER_BOTTOM;\n                }\n\n                if(txt_i == 0) {\n                    style_tmp.body.border.part &= ~LV_BORDER_LEFT;\n                } else if(strcmp(ext->map_p[txt_i - 1], \"\\n\") == 0) {\n                    style_tmp.body.border.part &= ~LV_BORDER_LEFT;\n                }\n\n                if(ext->map_p[txt_i + 1][0] == '\\0' || strcmp(ext->map_p[txt_i + 1], \"\\n\") == 0) {\n                    style_tmp.body.border.part &= ~LV_BORDER_RIGHT;\n                }\n            }\n            lv_draw_rect(&area_tmp, mask, &style_tmp, opa_scale);\n\n            /*Calculate the size of the text*/\n            if(btn_style->glass) btn_style = bg_style;\n            const lv_font_t * font = btn_style->text.font;\n            lv_point_t txt_size;\n            lv_txt_get_size(&txt_size, ext->map_p[txt_i], font, btn_style->text.letter_space,\n                            btn_style->text.line_space, lv_area_get_width(&area_btnm), txt_flag);\n\n            area_tmp.x1 += (btn_w - txt_size.x) / 2;\n            area_tmp.y1 += (btn_h - txt_size.y) / 2;\n            area_tmp.x2 = area_tmp.x1 + txt_size.x;\n            area_tmp.y2 = area_tmp.y1 + txt_size.y;\n\n            lv_draw_label(&area_tmp, mask, btn_style, opa_scale, ext->map_p[txt_i], txt_flag, NULL, -1, -1, NULL);\n        }\n    }\n    return true;\n}\n\n/**\n * Signal function of the button matrix\n * @param btnm pointer to a button matrix object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(btnm, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n    lv_point_t p;\n    if(sign == LV_SIGNAL_CLEANUP) {\n        lv_mem_free(ext->button_areas);\n        lv_mem_free(ext->ctrl_bits);\n    } else if(sign == LV_SIGNAL_STYLE_CHG || sign == LV_SIGNAL_CORD_CHG) {\n        lv_btnm_set_map(btnm, ext->map_p);\n    } else if(sign == LV_SIGNAL_PRESSED) {\n        lv_indev_t * indev = lv_indev_get_act();\n        if(lv_indev_get_type(indev) == LV_INDEV_TYPE_POINTER || lv_indev_get_type(indev) == LV_INDEV_TYPE_BUTTON) {\n            uint16_t btn_pr;\n            /*Search the pressed area*/\n            lv_indev_get_point(param, &p);\n            btn_pr = get_button_from_point(btnm, &p);\n\n            invalidate_button_area(btnm, ext->btn_id_pr) /*Invalidate the old area*/;\n            ext->btn_id_pr  = btn_pr;\n            ext->btn_id_act = btn_pr;\n            invalidate_button_area(btnm, ext->btn_id_pr); /*Invalidate the new area*/\n        }\n        if(ext->btn_id_act != LV_BTNM_BTN_NONE) {\n            if(button_is_click_trig(ext->ctrl_bits[ext->btn_id_act]) == false &&\n               button_is_inactive(ext->ctrl_bits[ext->btn_id_act]) == false &&\n               button_is_hidden(ext->ctrl_bits[ext->btn_id_act]) == false) {\n                uint32_t b = ext->btn_id_act;\n                res        = lv_event_send(btnm, LV_EVENT_VALUE_CHANGED, &b);\n            }\n        }\n    } else if(sign == LV_SIGNAL_PRESSING) {\n        uint16_t btn_pr;\n        /*Search the pressed area*/\n        lv_indev_get_point(param, &p);\n        btn_pr = get_button_from_point(btnm, &p);\n        /*Invalidate to old and the new areas*/;\n        if(btn_pr != ext->btn_id_pr) {\n            lv_indev_reset_long_press(param); /*Start the log press time again on the new button*/\n            if(ext->btn_id_pr != LV_BTNM_BTN_NONE) {\n                invalidate_button_area(btnm, ext->btn_id_pr);\n            }\n            if(btn_pr != LV_BTNM_BTN_NONE) {\n                uint32_t b = ext->btn_id_act;\n                res        = lv_event_send(btnm, LV_EVENT_VALUE_CHANGED, &b);\n                if(res == LV_RES_OK) {\n                    invalidate_button_area(btnm, btn_pr);\n                }\n            }\n        }\n\n        ext->btn_id_pr  = btn_pr;\n        ext->btn_id_act = btn_pr;\n    } else if(sign == LV_SIGNAL_RELEASED) {\n        if(ext->btn_id_pr != LV_BTNM_BTN_NONE) {\n            /*Toggle the button if enabled*/\n            if(button_is_tgl_enabled(ext->ctrl_bits[ext->btn_id_pr])) {\n                if(button_get_tgl_state(ext->ctrl_bits[ext->btn_id_pr])) {\n                    ext->ctrl_bits[ext->btn_id_pr] &= (~LV_BTNM_CTRL_TGL_STATE);\n                } else {\n                    ext->ctrl_bits[ext->btn_id_pr] |= LV_BTNM_CTRL_TGL_STATE;\n                }\n                if(ext->one_toggle) make_one_button_toggled(btnm, ext->btn_id_pr);\n            }\n\n            /*Invalidate to old pressed area*/;\n            invalidate_button_area(btnm, ext->btn_id_pr);\n\n#if LV_USE_GROUP\n            /*Leave the clicked button when releases if this not the focused object in a group*/\n            lv_group_t * g = lv_obj_get_group(btnm);\n            if(lv_group_get_focused(g) != btnm) {\n                ext->btn_id_pr = LV_BTNM_BTN_NONE;\n            }\n#else\n            ext->btn_id_pr = LV_BTNM_BTN_NONE;\n#endif\n\n            if(button_is_click_trig(ext->ctrl_bits[ext->btn_id_act]) == true &&\n               button_is_inactive(ext->ctrl_bits[ext->btn_id_act]) == false &&\n               button_is_hidden(ext->ctrl_bits[ext->btn_id_act]) == false) {\n                uint32_t b = ext->btn_id_act;\n                res        = lv_event_send(btnm, LV_EVENT_VALUE_CHANGED, &b);\n            }\n        }\n    } else if(sign == LV_SIGNAL_LONG_PRESS_REP) {\n        if(ext->btn_id_act != LV_BTNM_BTN_NONE) {\n            if(button_is_repeat_disabled(ext->ctrl_bits[ext->btn_id_act]) == false &&\n               button_is_inactive(ext->ctrl_bits[ext->btn_id_act]) == false &&\n               button_is_hidden(ext->ctrl_bits[ext->btn_id_act]) == false) {\n                uint32_t b = ext->btn_id_act;\n                res        = lv_event_send(btnm, LV_EVENT_VALUE_CHANGED, &b);\n            }\n        }\n    } else if(sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_DEFOCUS) {\n        ext->btn_id_pr  = LV_BTNM_BTN_NONE;\n        ext->btn_id_act = LV_BTNM_BTN_NONE;\n        lv_obj_invalidate(btnm);\n    } else if(sign == LV_SIGNAL_FOCUS) {\n#if LV_USE_GROUP\n        lv_indev_t * indev         = lv_indev_get_act();\n        lv_indev_type_t indev_type = lv_indev_get_type(indev);\n        if(indev_type == LV_INDEV_TYPE_POINTER) {\n            /*Select the clicked button*/\n            lv_point_t p1;\n            lv_indev_get_point(indev, &p1);\n            uint16_t btn_i = get_button_from_point(btnm, &p1);\n            ext->btn_id_pr = btn_i;\n\n        } else if(indev_type == LV_INDEV_TYPE_ENCODER) {\n            /*In navigation mode don't select any button but in edit mode select the fist*/\n            if(lv_group_get_editing(lv_obj_get_group(btnm)))\n                ext->btn_id_pr = 0;\n            else\n                ext->btn_id_pr = LV_BTNM_BTN_NONE;\n        } else {\n            ext->btn_id_pr = 0;\n        }\n#else\n        ext->btn_id_pr = 0;\n#endif\n\n        ext->btn_id_act = ext->btn_id_pr;\n        lv_obj_invalidate(btnm);\n    } else if(sign == LV_SIGNAL_CONTROL) {\n        char c = *((char *)param);\n        if(c == LV_KEY_RIGHT) {\n            if(ext->btn_id_pr == LV_BTNM_BTN_NONE)\n                ext->btn_id_pr = 0;\n            else\n                ext->btn_id_pr++;\n            if(ext->btn_id_pr >= ext->btn_cnt - 1) ext->btn_id_pr = ext->btn_cnt - 1;\n            ext->btn_id_act = ext->btn_id_pr;\n            lv_obj_invalidate(btnm);\n        } else if(c == LV_KEY_LEFT) {\n            if(ext->btn_id_pr == LV_BTNM_BTN_NONE) ext->btn_id_pr = 0;\n            if(ext->btn_id_pr > 0) ext->btn_id_pr--;\n            ext->btn_id_act = ext->btn_id_pr;\n            lv_obj_invalidate(btnm);\n        } else if(c == LV_KEY_DOWN) {\n            const lv_style_t * style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BG);\n            /*Find the area below the the current*/\n            if(ext->btn_id_pr == LV_BTNM_BTN_NONE) {\n                ext->btn_id_pr = 0;\n            } else {\n                uint16_t area_below;\n                lv_coord_t pr_center =\n                    ext->button_areas[ext->btn_id_pr].x1 + (lv_area_get_width(&ext->button_areas[ext->btn_id_pr]) >> 1);\n\n                for(area_below = ext->btn_id_pr; area_below < ext->btn_cnt; area_below++) {\n                    if(ext->button_areas[area_below].y1 > ext->button_areas[ext->btn_id_pr].y1 &&\n                       pr_center >= ext->button_areas[area_below].x1 &&\n                       pr_center <= ext->button_areas[area_below].x2 + style->body.padding.left) {\n                        break;\n                    }\n                }\n\n                if(area_below < ext->btn_cnt) ext->btn_id_pr = area_below;\n            }\n            ext->btn_id_act = ext->btn_id_pr;\n            lv_obj_invalidate(btnm);\n        } else if(c == LV_KEY_UP) {\n            const lv_style_t * style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BG);\n            /*Find the area below the the current*/\n            if(ext->btn_id_pr == LV_BTNM_BTN_NONE) {\n                ext->btn_id_pr = 0;\n            } else {\n                int16_t area_above;\n                lv_coord_t pr_center =\n                    ext->button_areas[ext->btn_id_pr].x1 + (lv_area_get_width(&ext->button_areas[ext->btn_id_pr]) >> 1);\n\n                for(area_above = ext->btn_id_pr; area_above >= 0; area_above--) {\n                    if(ext->button_areas[area_above].y1 < ext->button_areas[ext->btn_id_pr].y1 &&\n                       pr_center >= ext->button_areas[area_above].x1 - style->body.padding.left &&\n                       pr_center <= ext->button_areas[area_above].x2) {\n                        break;\n                    }\n                }\n                if(area_above >= 0) ext->btn_id_pr = area_above;\n            }\n            ext->btn_id_act = ext->btn_id_pr;\n            lv_obj_invalidate(btnm);\n        }\n    } else if(sign == LV_SIGNAL_GET_EDITABLE) {\n        bool * editable = (bool *)param;\n        *editable       = true;\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_btnm\";\n    }\n\n    return res;\n}\n\n/**\n * Create the required number of buttons and control bytes according to a map\n * @param btnm pointer to button matrix object\n * @param map_p pointer to a string array\n */\nstatic void allocate_btn_areas_and_controls(const lv_obj_t * btnm, const char ** map)\n{\n    /*Count the buttons in the map*/\n    uint16_t btn_cnt = 0;\n    uint16_t i       = 0;\n    while(strlen(map[i]) != 0) {\n        if(strcmp(map[i], \"\\n\") != 0) { /*Do not count line breaks*/\n            btn_cnt++;\n        }\n        i++;\n    }\n\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n\n    if(ext->button_areas != NULL) {\n        lv_mem_free(ext->button_areas);\n        ext->button_areas = NULL;\n    }\n    if(ext->ctrl_bits != NULL) {\n        lv_mem_free(ext->ctrl_bits);\n        ext->ctrl_bits = NULL;\n    }\n\n    ext->button_areas = lv_mem_alloc(sizeof(lv_area_t) * btn_cnt);\n    lv_mem_assert(ext->button_areas);\n    ext->ctrl_bits = lv_mem_alloc(sizeof(lv_btnm_ctrl_t) * btn_cnt);\n    lv_mem_assert(ext->ctrl_bits);\n    if(ext->button_areas == NULL || ext->ctrl_bits == NULL) btn_cnt = 0;\n\n    memset(ext->ctrl_bits, 0, sizeof(lv_btnm_ctrl_t) * btn_cnt);\n\n    ext->btn_cnt = btn_cnt;\n}\n\n/**\n * Get the width of a button in units (default is 1).\n * @param ctrl_bits least significant 3 bits used (1..7 valid values)\n * @return the width of the button in units\n */\nstatic uint8_t get_button_width(lv_btnm_ctrl_t ctrl_bits)\n{\n    uint8_t w = ctrl_bits & LV_BTNM_WIDTH_MASK;\n    return w != 0 ? w : 1;\n}\n\nstatic bool button_is_hidden(lv_btnm_ctrl_t ctrl_bits)\n{\n    return ctrl_bits & LV_BTNM_CTRL_HIDDEN ? true : false;\n}\n\nstatic bool button_is_repeat_disabled(lv_btnm_ctrl_t ctrl_bits)\n{\n    return ctrl_bits & LV_BTNM_CTRL_NO_REPEAT ? true : false;\n}\n\nstatic bool button_is_inactive(lv_btnm_ctrl_t ctrl_bits)\n{\n    return ctrl_bits & LV_BTNM_CTRL_INACTIVE ? true : false;\n}\n\nstatic bool button_is_click_trig(lv_btnm_ctrl_t ctrl_bits)\n{\n    return ctrl_bits & LV_BTNM_CTRL_CLICK_TRIG ? true : false;\n}\n\nstatic bool button_is_tgl_enabled(lv_btnm_ctrl_t ctrl_bits)\n{\n    return ctrl_bits & LV_BTNM_CTRL_TGL_ENABLE ? true : false;\n}\n\nstatic bool button_get_tgl_state(lv_btnm_ctrl_t ctrl_bits)\n{\n    return ctrl_bits & LV_BTNM_CTRL_TGL_STATE ? true : false;\n}\n\n/**\n * Gives the button id of a button under a given point\n * @param btnm pointer to a button matrix object\n * @param p a point with absolute coordinates\n * @return the id of the button or LV_BTNM_BTN_NONE.\n */\nstatic uint16_t get_button_from_point(lv_obj_t * btnm, lv_point_t * p)\n{\n    lv_area_t btnm_cords;\n    lv_area_t btn_area;\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n    uint16_t i;\n    lv_obj_get_coords(btnm, &btnm_cords);\n\n    for(i = 0; i < ext->btn_cnt; i++) {\n        lv_area_copy(&btn_area, &ext->button_areas[i]);\n        btn_area.x1 += btnm_cords.x1;\n        btn_area.y1 += btnm_cords.y1;\n        btn_area.x2 += btnm_cords.x1;\n        btn_area.y2 += btnm_cords.y1;\n        if(lv_area_is_point_on(&btn_area, p) != false) {\n            break;\n        }\n    }\n\n    if(i == ext->btn_cnt) i = LV_BTNM_BTN_NONE;\n\n    return i;\n}\n\nstatic void invalidate_button_area(const lv_obj_t * btnm, uint16_t btn_idx)\n{\n    if(btn_idx == LV_BTNM_BTN_NONE) return;\n\n    lv_area_t btn_area;\n    lv_area_t btnm_area;\n\n    lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);\n    lv_area_copy(&btn_area, &ext->button_areas[btn_idx]);\n    lv_obj_get_coords(btnm, &btnm_area);\n\n    /* Convert relative coordinates to absolute */\n    btn_area.x1 += btnm_area.x1;\n    btn_area.y1 += btnm_area.y1;\n    btn_area.x2 += btnm_area.x1;\n    btn_area.y2 += btnm_area.y1;\n\n    lv_inv_area(lv_obj_get_disp(btnm), &btn_area);\n}\n\n/**\n * Compares two button matrix maps for equality\n * @param map1 map to compare\n * @param map2 map to compare\n * @return true if maps are identical in length and content\n */\nstatic bool maps_are_identical(const char ** map1, const char ** map2)\n{\n    if(map1 == map2) return true;\n    if(map1 == NULL || map2 == NULL) return map1 == map2;\n\n    uint16_t i = 0;\n    while(map1[i][0] != '\\0' && map2[i][0] != '\\0') {\n        if(strcmp(map1[i], map2[i]) != 0) return false;\n        i++;\n    }\n    return map1[i][0] == '\\0' && map2[i][0] == '\\0';\n}\n\n/**\n * Enforces a single button being toggled on the button matrix.\n * It simply clears the toggle flag on other buttons.\n * @param btnm Button matrix object\n * @param btn_idx Button that should remain toggled\n */\nstatic void make_one_button_toggled(lv_obj_t * btnm, uint16_t btn_idx)\n{\n    /*Save whether the button was toggled*/\n    bool was_toggled = lv_btnm_get_btn_ctrl(btnm, btn_idx, LV_BTNM_CTRL_TGL_STATE);\n\n    lv_btnm_clear_btn_ctrl_all(btnm, LV_BTNM_CTRL_TGL_STATE);\n\n    if(was_toggled) lv_btnm_set_btn_ctrl(btnm, btn_idx, LV_BTNM_CTRL_TGL_STATE);\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_calendar.c",
    "content": "/**\n * @file lv_calendar.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_calendar.h\"\n#if LV_USE_CALENDAR != 0\n\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_hal/lv_hal_indev.h\"\n#include \"libs/lvgl/lv_misc/lv_utils.h\"\n#include \"libs/lvgl/lv_core/lv_indev.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include <string.h>\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\nenum {\n    DAY_DRAW_PREV_MONTH,\n    DAY_DRAW_ACT_MONTH,\n    DAY_DRAW_NEXT_MONTH,\n};\ntypedef uint8_t day_draw_state_t;\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_calendar_design(lv_obj_t * calendar, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_calendar_signal(lv_obj_t * calendar, lv_signal_t sign, void * param);\nstatic bool calculate_touched_day(lv_obj_t * calendar, const lv_point_t * touched_point);\nstatic lv_coord_t get_header_height(lv_obj_t * calendar);\nstatic lv_coord_t get_day_names_height(lv_obj_t * calendar);\nstatic void draw_header(lv_obj_t * calendar, const lv_area_t * mask);\nstatic void draw_day_names(lv_obj_t * calendar, const lv_area_t * mask);\nstatic void draw_days(lv_obj_t * calendar, const lv_area_t * mask);\nstatic uint8_t get_day_of_week(uint32_t year, uint32_t month, uint32_t day);\nstatic bool is_highlighted(lv_obj_t * calendar, int32_t year, int32_t month, int32_t day);\nstatic const char * get_day_name(lv_obj_t * calendar, uint8_t day);\nstatic const char * get_month_name(lv_obj_t * calendar, int32_t month);\nstatic uint8_t get_month_length(int32_t year, int32_t month);\nstatic uint8_t is_leap_year(uint32_t year);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\nstatic lv_design_cb_t ancestor_design;\nstatic const char * day_name[7]    = {\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"};\nstatic const char * month_name[12] = {\"January\", \"February\", \"March\",     \"April\",   \"May\",      \"June\",\n                                      \"July\",    \"August\",   \"September\", \"October\", \"November\", \"December\"};\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a calendar object\n * @param par pointer to an object, it will be the parent of the new calendar\n * @param copy pointer to a calendar object, if not NULL then the new object will be copied from it\n * @return pointer to the created calendar\n */\nlv_obj_t * lv_calendar_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"calendar create started\");\n\n    /*Create the ancestor of calendar*/\n    lv_obj_t * new_calendar = lv_obj_create(par, copy);\n    lv_mem_assert(new_calendar);\n    if(new_calendar == NULL) return NULL;\n\n    /*Allocate the calendar type specific extended data*/\n    lv_calendar_ext_t * ext = lv_obj_allocate_ext_attr(new_calendar, sizeof(lv_calendar_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_calendar);\n    if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_calendar);\n\n    /*Initialize the allocated 'ext' */\n    ext->today.year  = 2018;\n    ext->today.month = 1;\n    ext->today.day   = 1;\n\n    ext->showed_date.year  = 2018;\n    ext->showed_date.month = 1;\n    ext->showed_date.day   = 1;\n\n    ext->pressed_date.year  = 0;\n    ext->pressed_date.month = 0;\n    ext->pressed_date.day   = 0;\n\n    ext->highlighted_dates      = NULL;\n    ext->highlighted_dates_num  = 0;\n    ext->day_names              = NULL;\n    ext->month_names            = NULL;\n    ext->style_header           = &lv_style_plain_color;\n    ext->style_header_pr        = &lv_style_pretty_color;\n    ext->style_highlighted_days = &lv_style_plain_color;\n    ext->style_inactive_days    = &lv_style_btn_ina;\n    ext->style_week_box         = &lv_style_plain_color;\n    ext->style_today_box        = &lv_style_pretty_color;\n    ext->style_day_names        = &lv_style_pretty;\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_cb(new_calendar, lv_calendar_signal);\n    lv_obj_set_design_cb(new_calendar, lv_calendar_design);\n\n    /*Init the new calendar calendar*/\n    if(copy == NULL) {\n        lv_obj_set_size(new_calendar, LV_DPI * 2, LV_DPI * 2);\n        lv_obj_set_style(new_calendar, &lv_style_pretty);\n\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_BG, th->style.calendar.bg);\n            lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_HEADER, th->style.calendar.header);\n            lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_HEADER_PR, th->style.calendar.header_pr);\n            lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_DAY_NAMES, th->style.calendar.day_names);\n            lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_WEEK_BOX, th->style.calendar.week_box);\n            lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_TODAY_BOX, th->style.calendar.today_box);\n            lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_HIGHLIGHTED_DAYS,\n                                  th->style.calendar.highlighted_days);\n            lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_INACTIVE_DAYS, th->style.calendar.inactive_days);\n        } else {\n            lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_BG, &lv_style_pretty);\n            lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_HEADER, ext->style_header);\n            lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_HEADER_PR, ext->style_header_pr);\n            lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_DAY_NAMES, ext->style_day_names);\n            lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_WEEK_BOX, ext->style_week_box);\n            lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_TODAY_BOX, ext->style_today_box);\n            lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_HIGHLIGHTED_DAYS, ext->style_highlighted_days);\n            lv_calendar_set_style(new_calendar, LV_CALENDAR_STYLE_INACTIVE_DAYS, ext->style_inactive_days);\n        }\n    }\n    /*Copy an existing calendar*/\n    else {\n        lv_calendar_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->today.year              = copy_ext->today.year;\n        ext->today.month             = copy_ext->today.month;\n        ext->today.day               = copy_ext->today.day;\n\n        ext->showed_date.year  = copy_ext->showed_date.year;\n        ext->showed_date.month = copy_ext->showed_date.month;\n        ext->showed_date.day   = copy_ext->showed_date.day;\n\n        ext->highlighted_dates     = copy_ext->highlighted_dates;\n        ext->highlighted_dates_num = copy_ext->highlighted_dates_num;\n        ext->day_names             = copy_ext->day_names;\n\n        ext->month_names            = copy_ext->month_names;\n        ext->style_header           = copy_ext->style_header;\n        ext->style_header_pr        = copy_ext->style_header_pr;\n        ext->style_highlighted_days = copy_ext->style_highlighted_days;\n        ext->style_inactive_days    = copy_ext->style_inactive_days;\n        ext->style_week_box         = copy_ext->style_week_box;\n        ext->style_today_box        = copy_ext->style_today_box;\n        ext->style_day_names        = copy_ext->style_day_names;\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_calendar);\n    }\n\n    LV_LOG_INFO(\"calendar created\");\n\n    return new_calendar;\n}\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/*\n * New object specific \"add\" or \"remove\" functions come here\n */\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the today's date\n * @param calendar pointer to a calendar object\n * @param today pointer to an `lv_calendar_date_t` variable containing the date of today. The value\n * will be saved it can be local variable too.\n */\nvoid lv_calendar_set_today_date(lv_obj_t * calendar, lv_calendar_date_t * today)\n{\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n    ext->today.year         = today->year;\n    ext->today.month        = today->month;\n    ext->today.day          = today->day;\n\n    lv_obj_invalidate(calendar);\n}\n\n/**\n * Set the currently showed\n * @param calendar pointer to a calendar object\n * @param showed pointer to an `lv_calendar_date_t` variable containing the date to show. The value\n * will be saved it can be local variable too.\n */\nvoid lv_calendar_set_showed_date(lv_obj_t * calendar, lv_calendar_date_t * showed)\n{\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n    ext->showed_date.year   = showed->year;\n    ext->showed_date.month  = showed->month;\n    ext->showed_date.day    = showed->day;\n\n    lv_obj_invalidate(calendar);\n}\n\n/**\n * Set the the highlighted dates\n * @param calendar pointer to a calendar object\n * @param highlighted pointer to an `lv_calendar_date_t` array containing the dates. ONLY A POINTER\n * WILL BE SAVED! CAN'T BE LOCAL ARRAY.\n * @param date_num number of dates in the array\n */\nvoid lv_calendar_set_highlighted_dates(lv_obj_t * calendar, lv_calendar_date_t * highlighted, uint16_t date_num)\n{\n    lv_calendar_ext_t * ext    = lv_obj_get_ext_attr(calendar);\n    ext->highlighted_dates     = highlighted;\n    ext->highlighted_dates_num = date_num;\n\n    lv_obj_invalidate(calendar);\n}\n\n/**\n * Set the name of the days\n * @param calendar pointer to a calendar object\n * @param day_names pointer to an array with the names. E.g. `const char * days[7] = {\"Sun\", \"Mon\",\n * ...}` Only the pointer will be saved so this variable can't be local which will be destroyed\n * later.\n */\nvoid lv_calendar_set_day_names(lv_obj_t * calendar, const char ** day_names)\n{\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n    ext->day_names          = day_names;\n    lv_obj_invalidate(calendar);\n}\n\n/**\n * Set the name of the month\n * @param calendar pointer to a calendar object\n * @param day_names pointer to an array with the names. E.g. `const char * days[12] = {\"Jan\", \"Feb\",\n * ...}` Only the pointer will be saved so this variable can't be local which will be destroyed\n * later.\n */\nvoid lv_calendar_set_month_names(lv_obj_t * calendar, const char ** day_names)\n{\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n    ext->month_names        = day_names;\n    lv_obj_invalidate(calendar);\n}\n\n/**\n * Set a style of a calendar.\n * @param calendar pointer to calendar object\n * @param type which style should be set\n * @param style pointer to a style\n *  */\nvoid lv_calendar_set_style(lv_obj_t * calendar, lv_calendar_style_t type, const lv_style_t * style)\n{\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n\n    switch(type) {\n        case LV_CALENDAR_STYLE_BG: lv_obj_set_style(calendar, style); break;\n        case LV_CALENDAR_STYLE_DAY_NAMES: ext->style_day_names = style; break;\n        case LV_CALENDAR_STYLE_HEADER: ext->style_header = style; break;\n        case LV_CALENDAR_STYLE_HEADER_PR: ext->style_header_pr = style; break;\n        case LV_CALENDAR_STYLE_HIGHLIGHTED_DAYS: ext->style_highlighted_days = style; break;\n        case LV_CALENDAR_STYLE_INACTIVE_DAYS: ext->style_inactive_days = style; break;\n        case LV_CALENDAR_STYLE_TODAY_BOX: ext->style_today_box = style; break;\n        case LV_CALENDAR_STYLE_WEEK_BOX: ext->style_week_box = style; break;\n    }\n\n    lv_obj_invalidate(calendar);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the today's date\n * @param calendar pointer to a calendar object\n * @return return pointer to an `lv_calendar_date_t` variable containing the date of today.\n */\nlv_calendar_date_t * lv_calendar_get_today_date(const lv_obj_t * calendar)\n{\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n    return &ext->today;\n}\n\n/**\n * Get the currently showed\n * @param calendar pointer to a calendar object\n * @return pointer to an `lv_calendar_date_t` variable containing the date is being shown.\n */\nlv_calendar_date_t * lv_calendar_get_showed_date(const lv_obj_t * calendar)\n{\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n    return &ext->showed_date;\n}\n\n/**\n * Get the the pressed date.\n * @param calendar pointer to a calendar object\n * @return pointer to an `lv_calendar_date_t` variable containing the pressed date.\n * `NULL` if not date pressed (e.g. the header)\n */\nlv_calendar_date_t * lv_calendar_get_pressed_date(const lv_obj_t * calendar)\n{\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n    return ext->pressed_date.year != 0 ? &ext->pressed_date : NULL;\n}\n\n/**\n * Get the the highlighted dates\n * @param calendar pointer to a calendar object\n * @return pointer to an `lv_calendar_date_t` array containing the dates.\n */\nlv_calendar_date_t * lv_calendar_get_highlighted_dates(const lv_obj_t * calendar)\n{\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n    return ext->highlighted_dates;\n}\n\n/**\n * Get the number of the highlighted dates\n * @param calendar pointer to a calendar object\n * @return number of highlighted days\n */\nuint16_t lv_calendar_get_highlighted_dates_num(const lv_obj_t * calendar)\n{\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n    return ext->highlighted_dates_num;\n}\n\n/**\n * Get the name of the days\n * @param calendar pointer to a calendar object\n * @return pointer to the array of day names\n */\nconst char ** lv_calendar_get_day_names(const lv_obj_t * calendar)\n{\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n    return ext->day_names;\n}\n\n/**\n * Get the name of the month\n * @param calendar pointer to a calendar object\n * @return pointer to the array of month names\n */\nconst char ** lv_calendar_get_month_names(const lv_obj_t * calendar)\n{\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n    return ext->month_names;\n}\n\n/**\n * Get style of a calendar.\n * @param calendar pointer to calendar object\n * @param type which style should be get\n * @return style pointer to the style\n *  */\nconst lv_style_t * lv_calendar_get_style(const lv_obj_t * calendar, lv_calendar_style_t type)\n{\n    const lv_style_t * style = NULL;\n    lv_calendar_ext_t * ext  = lv_obj_get_ext_attr(calendar);\n\n    switch(type) {\n        case LV_CALENDAR_STYLE_BG: style = lv_obj_get_style(calendar); break;\n        case LV_CALENDAR_STYLE_HEADER: style = ext->style_header; break;\n        case LV_CALENDAR_STYLE_HEADER_PR: style = ext->style_header_pr; break;\n        case LV_CALENDAR_STYLE_DAY_NAMES: style = ext->style_day_names; break;\n        case LV_CALENDAR_STYLE_HIGHLIGHTED_DAYS: style = ext->style_highlighted_days; break;\n        case LV_CALENDAR_STYLE_INACTIVE_DAYS: style = ext->style_inactive_days; break;\n        case LV_CALENDAR_STYLE_WEEK_BOX: style = ext->style_week_box; break;\n        case LV_CALENDAR_STYLE_TODAY_BOX: style = ext->style_today_box; break;\n        default: style = NULL; break;\n    }\n\n    return style;\n}\n\n/*=====================\n * Other functions\n *====================*/\n\n/*\n * New object specific \"other\" functions come here\n */\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the calendars\n * @param calendar pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_calendar_design(lv_obj_t * calendar, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    /*Return false if the object is not covers the mask_p area*/\n    if(mode == LV_DESIGN_COVER_CHK) {\n        return ancestor_design(calendar, mask, mode);\n    }\n    /*Draw the object*/\n    else if(mode == LV_DESIGN_DRAW_MAIN) {\n        lv_opa_t opa_scale = lv_obj_get_opa_scale(calendar);\n        lv_draw_rect(&calendar->coords, mask, lv_calendar_get_style(calendar, LV_CALENDAR_STYLE_BG), opa_scale);\n\n        draw_header(calendar, mask);\n        draw_day_names(calendar, mask);\n        draw_days(calendar, mask);\n\n    }\n    /*Post draw when the children are drawn*/\n    else if(mode == LV_DESIGN_DRAW_POST) {\n    }\n\n    return true;\n}\n\n/**\n * Signal function of the calendar\n * @param calendar pointer to a calendar object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_calendar_signal(lv_obj_t * calendar, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(calendar, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    if(sign == LV_SIGNAL_CLEANUP) {\n        /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/\n    } else if(sign == LV_SIGNAL_PRESSING) {\n        lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n        lv_area_t header_area;\n        lv_area_copy(&header_area, &calendar->coords);\n        header_area.y2 = header_area.y1 + get_header_height(calendar);\n\n        lv_indev_t * indev = lv_indev_get_act();\n        lv_point_t p;\n        lv_indev_get_point(indev, &p);\n\n        /*If the header is pressed mark an arrow as pressed*/\n        if(lv_area_is_point_on(&header_area, &p)) {\n            if(p.x < header_area.x1 + lv_area_get_width(&header_area) / 2) {\n                if(ext->btn_pressing != -1) lv_obj_invalidate(calendar);\n                ext->btn_pressing = -1;\n            } else {\n                if(ext->btn_pressing != 1) lv_obj_invalidate(calendar);\n                ext->btn_pressing = 1;\n            }\n\n            ext->pressed_date.year  = 0;\n            ext->pressed_date.month = 0;\n            ext->pressed_date.day   = 0;\n        }\n        /*If a day is pressed save it*/\n        else if(calculate_touched_day(calendar, &p)) {\n            if(ext->btn_pressing != 0) lv_obj_invalidate(calendar);\n            ext->btn_pressing = 0;\n        }\n        /*ELse set a deafault state*/\n        else {\n            if(ext->btn_pressing != 0) lv_obj_invalidate(calendar);\n            ext->btn_pressing       = 0;\n            ext->pressed_date.year  = 0;\n            ext->pressed_date.month = 0;\n            ext->pressed_date.day   = 0;\n        }\n    } else if(sign == LV_SIGNAL_PRESS_LOST) {\n        lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n        ext->btn_pressing       = 0;\n        lv_obj_invalidate(calendar);\n\n    } else if(sign == LV_SIGNAL_RELEASED) {\n        lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n        if(ext->btn_pressing < 0) {\n            if(ext->showed_date.month <= 1) {\n                ext->showed_date.month = 12;\n                ext->showed_date.year--;\n            } else {\n                ext->showed_date.month--;\n            }\n        } else if(ext->btn_pressing > 0) {\n            if(ext->showed_date.month >= 12) {\n                ext->showed_date.month = 1;\n                ext->showed_date.year++;\n            } else {\n                ext->showed_date.month++;\n            }\n        } else if(ext->pressed_date.year != 0) {\n            res = lv_event_send(calendar, LV_EVENT_VALUE_CHANGED, NULL);\n            if(res != LV_RES_OK) return res;\n        }\n\n        ext->btn_pressing = 0;\n        lv_obj_invalidate(calendar);\n    } else if(sign == LV_SIGNAL_CONTROL) {\n        uint8_t c               = *((uint8_t *)param);\n        lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n        if(c == LV_KEY_RIGHT || c == LV_KEY_UP) {\n            if(ext->showed_date.month >= 12) {\n                ext->showed_date.month = 1;\n                ext->showed_date.year++;\n            } else {\n                ext->showed_date.month++;\n            }\n            lv_obj_invalidate(calendar);\n        } else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) {\n            if(ext->showed_date.month <= 1) {\n                ext->showed_date.month = 12;\n                ext->showed_date.year--;\n            } else {\n                ext->showed_date.month--;\n            }\n            lv_obj_invalidate(calendar);\n        }\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set date*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_calendar\";\n    }\n\n    return res;\n}\n\n/**\n * It will check if the days part of calendar is touched\n * and if it is, it will calculate the day and put it in pressed_date of calendar object.\n * @param calendar pointer to a calendar object\n * @param pointer to a point\n * @return true: days part of calendar is touched and its related date is put in pressed date\n * false: the point is out of days part area.\n */\nstatic bool calculate_touched_day(lv_obj_t * calendar, const lv_point_t * touched_point)\n{\n    lv_area_t days_area;\n    lv_area_copy(&days_area, &calendar->coords);\n    const lv_style_t * style_bg = lv_calendar_get_style(calendar, LV_CALENDAR_STYLE_BG);\n    days_area.x1 += style_bg->body.padding.left;\n    days_area.x2 -= style_bg->body.padding.right;\n    days_area.y1 =\n        calendar->coords.y1 + get_header_height(calendar) + get_day_names_height(calendar) - style_bg->body.padding.top;\n\n    if(lv_area_is_point_on(&days_area, touched_point)) {\n        lv_coord_t w  = (days_area.x2 - days_area.x1 + 1) / 7;\n        lv_coord_t h  = (days_area.y2 - days_area.y1 + 1) / 6;\n        uint8_t x_pos = 0;\n        x_pos         = (touched_point->x - days_area.x1) / w;\n        if(x_pos > 6) x_pos = 6;\n        uint8_t y_pos = 0;\n        y_pos         = (touched_point->y - days_area.y1) / h;\n        if(y_pos > 5) y_pos = 5;\n\n        uint8_t i_pos           = 0;\n        i_pos                   = (y_pos * 7) + x_pos;\n        lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n        if(i_pos < get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1)) {\n            ext->pressed_date.year  = ext->showed_date.year - (ext->showed_date.month == 1 ? 1 : 0);\n            ext->pressed_date.month = ext->showed_date.month == 1 ? 12 : (ext->showed_date.month - 1);\n            ext->pressed_date.day   = get_month_length(ext->pressed_date.year, ext->pressed_date.month) -\n                                    get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) + 1 + i_pos;\n        } else if(i_pos < (get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) +\n                           get_month_length(ext->showed_date.year, ext->showed_date.month))) {\n            ext->pressed_date.year  = ext->showed_date.year;\n            ext->pressed_date.month = ext->showed_date.month;\n            ext->pressed_date.day   = i_pos + 1 - get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1);\n        } else if(i_pos < 42) {\n            ext->pressed_date.year  = ext->showed_date.year + (ext->showed_date.month == 12 ? 1 : 0);\n            ext->pressed_date.month = ext->showed_date.month == 12 ? 1 : (ext->showed_date.month + 1);\n            ext->pressed_date.day   = i_pos + 1 - get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1) -\n                                    get_month_length(ext->showed_date.year, ext->showed_date.month);\n        }\n        return true;\n    } else {\n        return false;\n    }\n}\n\n/**\n * Get the height of a calendar's header based on it's style\n * @param calendar point to a calendar\n * @return the header's height\n */\nstatic lv_coord_t get_header_height(lv_obj_t * calendar)\n{\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n\n    return lv_font_get_line_height(ext->style_header->text.font) + ext->style_header->body.padding.top +\n           ext->style_header->body.padding.bottom;\n}\n\n/**\n * Get the height of a calendar's day_names based on it's style\n * @param calendar point to a calendar\n * @return the day_names's height\n */\nstatic lv_coord_t get_day_names_height(lv_obj_t * calendar)\n{\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n\n    return lv_font_get_line_height(ext->style_day_names->text.font) + ext->style_day_names->body.padding.top +\n           ext->style_day_names->body.padding.bottom;\n}\n\n/**\n * Draw the calendar header with month name and arrows\n * @param calendar point to a calendar\n * @param mask a mask for drawing\n */\nstatic void draw_header(lv_obj_t * calendar, const lv_area_t * mask)\n{\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n    lv_opa_t opa_scale      = lv_obj_get_opa_scale(calendar);\n\n    lv_area_t header_area;\n    header_area.x1 = calendar->coords.x1;\n    header_area.x2 = calendar->coords.x2;\n    header_area.y1 = calendar->coords.y1;\n    header_area.y2 = calendar->coords.y1 + get_header_height(calendar);\n\n    lv_draw_rect(&header_area, mask, ext->style_header, opa_scale);\n\n    /*Add the year + month name*/\n    char txt_buf[64];\n    lv_utils_num_to_str(ext->showed_date.year, txt_buf);\n    txt_buf[4] = ' ';\n    txt_buf[5] = '\\0';\n    strcpy(&txt_buf[5], get_month_name(calendar, ext->showed_date.month));\n    header_area.y1 += ext->style_header->body.padding.top;\n    lv_draw_label(&header_area, mask, ext->style_header, opa_scale, txt_buf, LV_TXT_FLAG_CENTER, NULL, -1, -1, NULL);\n\n    /*Add the left arrow*/\n    const lv_style_t * arrow_style = ext->btn_pressing < 0 ? ext->style_header_pr : ext->style_header;\n    header_area.x1 += ext->style_header->body.padding.left;\n    lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_LEFT, LV_TXT_FLAG_NONE, NULL, -1, -1, NULL);\n\n    /*Add the right arrow*/\n    arrow_style    = ext->btn_pressing > 0 ? ext->style_header_pr : ext->style_header;\n    header_area.x1 = header_area.x2 - ext->style_header->body.padding.right -\n                     lv_txt_get_width(LV_SYMBOL_RIGHT, strlen(LV_SYMBOL_RIGHT), arrow_style->text.font,\n                                      arrow_style->text.line_space, LV_TXT_FLAG_NONE);\n    lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_RIGHT, LV_TXT_FLAG_NONE, NULL, -1, -1, NULL);\n}\n\n/**\n * Draw the day's name below the header\n * @param calendar point to a calendar\n * @param mask a mask for drawing\n */\nstatic void draw_day_names(lv_obj_t * calendar, const lv_area_t * mask)\n{\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n    lv_opa_t opa_scale      = lv_obj_get_opa_scale(calendar);\n\n    lv_coord_t l_pad = ext->style_day_names->body.padding.left;\n    lv_coord_t w =\n        lv_obj_get_width(calendar) - ext->style_day_names->body.padding.left - ext->style_day_names->body.padding.right;\n    lv_coord_t box_w = w / 7;\n    lv_area_t label_area;\n    label_area.y1 = calendar->coords.y1 + get_header_height(calendar) + ext->style_day_names->body.padding.top;\n    label_area.y2 = label_area.y1 + lv_font_get_line_height(ext->style_day_names->text.font);\n    uint32_t i;\n    for(i = 0; i < 7; i++) {\n        label_area.x1 = calendar->coords.x1 + (w * i) / 7 + l_pad;\n        label_area.x2 = label_area.x1 + box_w - 1;\n        lv_draw_label(&label_area, mask, ext->style_day_names, opa_scale, get_day_name(calendar, i), LV_TXT_FLAG_CENTER,\n                      NULL, -1, -1, NULL);\n    }\n}\n\n/**\n * Draw the date numbers in a matrix\n * @param calendar point to a calendar\n * @param mask a mask for drawing\n */\nstatic void draw_days(lv_obj_t * calendar, const lv_area_t * mask)\n{\n    lv_calendar_ext_t * ext     = lv_obj_get_ext_attr(calendar);\n    const lv_style_t * style_bg = lv_calendar_get_style(calendar, LV_CALENDAR_STYLE_BG);\n    lv_area_t label_area;\n    lv_opa_t opa_scale = lv_obj_get_opa_scale(calendar);\n    label_area.y1      = calendar->coords.y1 + get_header_height(calendar) + ext->style_day_names->body.padding.top +\n                    lv_font_get_line_height(ext->style_day_names->text.font) +\n                    ext->style_day_names->body.padding.bottom;\n    label_area.y2 = label_area.y1 + lv_font_get_line_height(style_bg->text.font);\n\n    lv_coord_t w          = lv_obj_get_width(calendar) - style_bg->body.padding.left - style_bg->body.padding.right;\n    lv_coord_t h          = calendar->coords.y2 - label_area.y1 - style_bg->body.padding.bottom;\n    lv_coord_t box_w      = w / 7;\n    lv_coord_t vert_space = (h - (6 * lv_font_get_line_height(style_bg->text.font))) / 5;\n\n    uint32_t week;\n    uint8_t day_cnt;\n    uint8_t month_start_day = get_day_of_week(ext->showed_date.year, ext->showed_date.month, 1);\n    day_draw_state_t draw_state; /*true: Not the prev. or next month is drawn*/\n    const lv_style_t * act_style;\n\n    /*If starting with the first day of the week then the previous month is not visible*/\n    if(month_start_day == 0) {\n        day_cnt    = 1;\n        draw_state = DAY_DRAW_ACT_MONTH;\n        act_style  = style_bg;\n    } else {\n        draw_state = DAY_DRAW_PREV_MONTH;\n        day_cnt = get_month_length(ext->showed_date.year, ext->showed_date.month - 1); /*Length of the previous month*/\n        day_cnt -= month_start_day - 1; /*First visible number of the previous month*/\n        act_style = ext->style_inactive_days;\n    }\n\n    bool month_of_today_shown = false;\n    if(ext->showed_date.year == ext->today.year && ext->showed_date.month == ext->today.month) {\n        month_of_today_shown = true;\n    }\n\n    char buf[3];\n    bool in_week_box = false;\n\n    /*Draw 6 weeks*/\n    for(week = 0; week < 6; week++) {\n\n        /*Draw the \"week box\"*/\n        if(month_of_today_shown &&\n           ((draw_state == DAY_DRAW_ACT_MONTH && ext->today.day >= day_cnt && ext->today.day < day_cnt + 7) ||\n            (draw_state == DAY_DRAW_PREV_MONTH && ext->today.day <= 7 - month_start_day && week == 0))) {\n            lv_area_t week_box_area;\n            lv_area_copy(&week_box_area, &label_area); /*'label_area' is already set for this row*/\n            week_box_area.x1 =\n                calendar->coords.x1 + style_bg->body.padding.left - ext->style_week_box->body.padding.left;\n            week_box_area.x2 =\n                calendar->coords.x2 - style_bg->body.padding.right + ext->style_week_box->body.padding.right;\n\n            week_box_area.y1 -= ext->style_week_box->body.padding.top;\n            week_box_area.y2 += ext->style_week_box->body.padding.bottom;\n            lv_draw_rect(&week_box_area, mask, ext->style_week_box, opa_scale);\n\n            in_week_box = true;\n        } else {\n            in_week_box = false;\n        }\n\n        /*Draw the 7 days of a week*/\n        uint32_t day;\n        for(day = 0; day < 7; day++) {\n            /*The previous month is over*/\n            if(draw_state == DAY_DRAW_PREV_MONTH && day == month_start_day) {\n                draw_state = DAY_DRAW_ACT_MONTH;\n                day_cnt    = 1;\n                act_style  = style_bg;\n            }\n            /*The current month is over*/\n            if(draw_state == DAY_DRAW_ACT_MONTH &&\n               day_cnt > get_month_length(ext->showed_date.year, ext->showed_date.month)) {\n                draw_state = DAY_DRAW_NEXT_MONTH;\n                day_cnt    = 1;\n                act_style  = ext->style_inactive_days;\n            }\n\n            label_area.x1 =\n                calendar->coords.x1 + (w * day) / 7 + style_bg->body.padding.left;\n            label_area.x2 = label_area.x1 + box_w - 1;\n\n            /*Draw the \"today box\"*/\n            if(draw_state == DAY_DRAW_ACT_MONTH && month_of_today_shown && ext->today.day == day_cnt) {\n                lv_area_t today_box_area;\n                lv_area_copy(&today_box_area, &label_area);\n                today_box_area.x1 = label_area.x1;\n                today_box_area.x2 = label_area.x2;\n\n                today_box_area.y1 = label_area.y1 - ext->style_today_box->body.padding.top;\n                today_box_area.y2 = label_area.y2 + ext->style_today_box->body.padding.bottom;\n                lv_draw_rect(&today_box_area, mask, ext->style_today_box, opa_scale);\n            }\n\n            /*Get the final style : highlighted/week box/today box/normal*/\n            const lv_style_t * final_style;\n            if(draw_state == DAY_DRAW_PREV_MONTH &&\n               is_highlighted(calendar, ext->showed_date.year - (ext->showed_date.month == 1 ? 1 : 0),\n                              ext->showed_date.month == 1 ? 12 : ext->showed_date.month - 1, day_cnt)) {\n                final_style = ext->style_highlighted_days;\n            } else if(draw_state == DAY_DRAW_ACT_MONTH &&\n                      is_highlighted(calendar, ext->showed_date.year, ext->showed_date.month, day_cnt)) {\n                final_style = ext->style_highlighted_days;\n            } else if(draw_state == DAY_DRAW_NEXT_MONTH &&\n                      is_highlighted(calendar, ext->showed_date.year + (ext->showed_date.month == 12 ? 1 : 0),\n                                     ext->showed_date.month == 12 ? 1 : ext->showed_date.month + 1, day_cnt)) {\n                final_style = ext->style_highlighted_days;\n            } else if(month_of_today_shown && day_cnt == ext->today.day && draw_state == DAY_DRAW_ACT_MONTH)\n                final_style = ext->style_today_box;\n            else if(in_week_box && draw_state == DAY_DRAW_ACT_MONTH)\n                final_style = ext->style_week_box;\n            else\n                final_style = act_style;\n\n            /*Write the day's number*/\n            lv_utils_num_to_str(day_cnt, buf);\n            lv_draw_label(&label_area, mask, final_style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, -1, -1, NULL);\n\n            /*Go to the next day*/\n            day_cnt++;\n        }\n\n        /*Got to the next weeks row*/\n        label_area.y1 += vert_space + lv_font_get_line_height(style_bg->text.font);\n        label_area.y2 += vert_space + lv_font_get_line_height(style_bg->text.font);\n    }\n}\n\n/**\n * Check weather a date is highlighted or not\n * @param calendar pointer to a calendar object\n * @param year a year\n * @param month a  month [1..12]\n * @param day a day [1..31]\n * @return true: highlighted\n */\nstatic bool is_highlighted(lv_obj_t * calendar, int32_t year, int32_t month, int32_t day)\n{\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n\n    if(ext->highlighted_dates == NULL || ext->highlighted_dates_num == 0) return false;\n\n    uint32_t i;\n    for(i = 0; i < ext->highlighted_dates_num; i++) {\n        if(ext->highlighted_dates[i].year == year && ext->highlighted_dates[i].month == month &&\n           ext->highlighted_dates[i].day == day) {\n            return true;\n        }\n    }\n\n    return false;\n}\n\n/**\n * Get the day name\n * @param calendar pointer to a calendar object\n * @param day a day in [0..6]\n * @return\n */\nstatic const char * get_day_name(lv_obj_t * calendar, uint8_t day)\n{\n\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n    if(ext->day_names)\n        return ext->day_names[day];\n    else\n        return day_name[day];\n}\n\n/**\n * Get the month name\n * @param calendar pointer to a calendar object\n * @param month a month. The range is basically [1..12] but [-11..1] is also supported to handle\n * previous year\n * @return\n */\nstatic const char * get_month_name(lv_obj_t * calendar, int32_t month)\n{\n    month--; /*Range of months id [1..12] but range of indexes is [0..11]*/\n    if(month < 0) month = 12 + month;\n\n    lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);\n    if(ext->month_names)\n        return ext->month_names[month];\n    else\n        return month_name[month];\n}\n\n/**\n * Get the number of days in a month\n * @param year a year\n * @param month a month. The range is basically [1..12] but [-11..1] is also supported to handle\n * previous year\n * @return [28..31]\n */\nstatic uint8_t get_month_length(int32_t year, int32_t month)\n{\n    month--; /*Range of months id [1..12] but range of indexes is [0..11]*/\n    if(month < 0) {\n        year--;             /*Already in the previous year (won't be less then -12 to skip a whole year)*/\n        month = 12 + month; /*`month` is negative, the result will be < 12*/\n    }\n    if(month >= 12) {\n        year++;\n        month -= 12;\n    }\n\n    /*month == 1 is february*/\n    return (month == 1) ? (28 + is_leap_year(year)) : 31 - month % 7 % 2;\n}\n\n/**\n * Tells whether a year is leap year or not\n * @param year a year\n * @return 0: not leap year; 1: leap year\n */\nstatic uint8_t is_leap_year(uint32_t year)\n{\n    return (year % 4) || ((year % 100 == 0) && (year % 400)) ? 0 : 1;\n}\n\n/**\n * Get the day of the week\n * @param year a year\n * @param month a  month\n * @param day a day\n * @return [0..6] which means [Sun..Sat]\n */\nstatic uint8_t get_day_of_week(uint32_t year, uint32_t month, uint32_t day)\n{\n    uint32_t a = month < 3 ? 1 : 0;\n    uint32_t b = year - a;\n\n    uint32_t day_of_week = (day + (31 * (month - 2 + 12 * a) / 12) + b + (b / 4) - (b / 100) + (b / 400)) % 7;\n\n    return day_of_week;\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_canvas.c",
    "content": "/**\n * @file lv_canvas.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include <stdlib.h>\n#include \"libs/lvgl/lv_objx/lv_canvas.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_core/lv_refr.h\"\n\n#if LV_USE_CANVAS != 0\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic lv_res_t lv_canvas_signal(lv_obj_t * canvas, lv_signal_t sign, void * param);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\nstatic lv_design_cb_t ancestor_design;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a canvas object\n * @param par pointer to an object, it will be the parent of the new canvas\n * @param copy pointer to a canvas object, if not NULL then the new object will be copied from it\n * @return pointer to the created canvas\n */\nlv_obj_t * lv_canvas_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"canvas create started\");\n\n    /*Create the ancestor of canvas*/\n    lv_obj_t * new_canvas = lv_img_create(par, copy);\n    lv_mem_assert(new_canvas);\n    if(new_canvas == NULL) return NULL;\n\n    /*Allocate the canvas type specific extended data*/\n    lv_canvas_ext_t * ext = lv_obj_allocate_ext_attr(new_canvas, sizeof(lv_canvas_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_canvas);\n    if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_canvas);\n\n    /*Initialize the allocated 'ext' */\n    ext->dsc.header.always_zero = 0;\n    ext->dsc.header.cf          = LV_IMG_CF_TRUE_COLOR;\n    ext->dsc.header.h           = 0;\n    ext->dsc.header.w           = 0;\n    ext->dsc.data_size          = 0;\n    ext->dsc.data               = NULL;\n\n    lv_img_set_src(new_canvas, &ext->dsc);\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_cb(new_canvas, lv_canvas_signal);\n\n    /*Init the new canvas canvas*/\n    if(copy == NULL) {\n\n    }\n    /*Copy an existing canvas*/\n    else {\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_canvas);\n    }\n\n    LV_LOG_INFO(\"canvas created\");\n\n    return new_canvas;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a buffer for the canvas.\n * @param buf a buffer where the content of the canvas will be.\n * The required size is (lv_img_color_format_get_px_size(cf) * w * h) / 8)\n * It can be allocated with `lv_mem_alloc()` or\n * it can be statically allocated array (e.g. static lv_color_t buf[100*50]) or\n * it can be an address in RAM or external SRAM\n * @param canvas pointer to a canvas object\n * @param w width of the canvas\n * @param h height of the canvas\n * @param cf color format. The following formats are supported:\n *      LV_IMG_CF_TRUE_COLOR, LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED, LV_IMG_CF_INDEXES_1/2/4/8BIT\n *\n */\nvoid lv_canvas_set_buffer(lv_obj_t * canvas, void * buf, lv_coord_t w, lv_coord_t h, lv_img_cf_t cf)\n{\n    lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas);\n\n    ext->dsc.header.cf = cf;\n    ext->dsc.header.w  = w;\n    ext->dsc.header.h  = h;\n    ext->dsc.data      = buf;\n    ext->dsc.data_size = (lv_img_color_format_get_px_size(cf) * w * h) / 8;\n\n    lv_img_set_src(canvas, &ext->dsc);\n}\n\n/**\n * Set the color of a pixel on the canvas\n * @param canvas pointer to canvas object\n * @param x x coordinate of the point to set\n * @param y x coordinate of the point to set\n * @param c color of the point\n */\nvoid lv_canvas_set_px(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_color_t c)\n{\n    lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas);\n\n    lv_img_buf_set_px_color(&ext->dsc, x, y, c);\n    lv_obj_invalidate(canvas);\n}\n\n/**\n * Set the palette color of a canvas with index format. Valid only for `LV_IMG_CF_INDEXED1/2/4/8`\n * @param canvas pointer to canvas object\n * @param id the palette color to set:\n *   - for `LV_IMG_CF_INDEXED1`: 0..1\n *   - for `LV_IMG_CF_INDEXED2`: 0..3\n *   - for `LV_IMG_CF_INDEXED4`: 0..15\n *   - for `LV_IMG_CF_INDEXED8`: 0..255\n * @param c the color to set\n */\nvoid lv_canvas_set_palette(lv_obj_t * canvas, uint8_t id, lv_color_t c)\n{\n    lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas);\n\n    lv_img_buf_set_palette(&ext->dsc, id, c);\n    lv_obj_invalidate(canvas);\n}\n\n/**\n * Set a style of a canvas.\n * @param canvas pointer to canvas object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_canvas_set_style(lv_obj_t * canvas, lv_canvas_style_t type, const lv_style_t * style)\n{\n    switch(type) {\n        case LV_CANVAS_STYLE_MAIN: lv_img_set_style(canvas, LV_IMG_STYLE_MAIN, style); break;\n    }\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the color of a pixel on the canvas\n * @param canvas\n * @param x x coordinate of the point to set\n * @param y x coordinate of the point to set\n * @return color of the point\n */\nlv_color_t lv_canvas_get_px(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y)\n{\n    lv_canvas_ext_t * ext    = lv_obj_get_ext_attr(canvas);\n    const lv_style_t * style = lv_canvas_get_style(canvas, LV_CANVAS_STYLE_MAIN);\n\n    return lv_img_buf_get_px_color(&ext->dsc, x, y, style);\n}\n\n/**\n * Get the image of the canvas as a pointer to an `lv_img_dsc_t` variable.\n * @param canvas pointer to a canvas object\n * @return pointer to the image descriptor.\n */\nlv_img_dsc_t * lv_canvas_get_img(lv_obj_t * canvas)\n{\n    lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas);\n\n    return &ext->dsc;\n}\n\n/**\n * Get style of a canvas.\n * @param canvas pointer to canvas object\n * @param type which style should be get\n * @return style pointer to the style\n */\nconst lv_style_t * lv_canvas_get_style(const lv_obj_t * canvas, lv_canvas_style_t type)\n{\n    const lv_style_t * style = NULL;\n\n    switch(type) {\n        case LV_CANVAS_STYLE_MAIN: style = lv_img_get_style(canvas, LV_IMG_STYLE_MAIN); break;\n        default: style = NULL;\n    }\n\n    return style;\n}\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Copy a buffer to the canvas\n * @param canvas pointer to a canvas object\n * @param to_copy buffer to copy. The color format has to match with the canvas's buffer color\n * format\n * @param w width of the buffer to copy\n * @param h height of the buffer to copy\n * @param x left side of the destination position\n * @param y top side of the destination position\n */\nvoid lv_canvas_copy_buf(lv_obj_t * canvas, const void * to_copy, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h)\n{\n    lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas);\n    if(x + w >= ext->dsc.header.w || y + h >= ext->dsc.header.h) {\n        LV_LOG_WARN(\"lv_canvas_copy_buf: x or y out of the canvas\");\n        return;\n    }\n\n    uint32_t px_size   = lv_img_color_format_get_px_size(ext->dsc.header.cf) >> 3;\n    uint32_t px        = ext->dsc.header.w * y * px_size + x * px_size;\n    uint8_t * to_copy8 = (uint8_t *)to_copy;\n    lv_coord_t i;\n    for(i = 0; i < h; i++) {\n        memcpy((void *)&ext->dsc.data[px], to_copy8, w * px_size);\n        px += ext->dsc.header.w * px_size;\n        to_copy8 += w * px_size;\n    }\n}\n\n/**\n * Rotate and image and store the result on a canvas.\n * @param canvas pointer to a canvas object\n * @param img pointer to an image descriptor.\n *             Can be the image descriptor of an other canvas too (`lv_canvas_get_img()`).\n * @param angle the angle of rotation (0..360);\n * @param offset_x offset X to tell where to put the result data on destination canvas\n * @param offset_y offset X to tell where to put the result data on destination canvas\n * @param pivot_x pivot X of rotation. Relative to the source canvas\n *                Set to `source width / 2` to rotate around the center\n * @param pivot_y pivot Y of rotation. Relative to the source canvas\n *                Set to `source height / 2` to rotate around the center\n */\nvoid lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle, lv_coord_t offset_x, lv_coord_t offset_y,\n                      int32_t pivot_x, int32_t pivot_y)\n{\n    lv_canvas_ext_t * ext_dst = lv_obj_get_ext_attr(canvas);\n    const lv_style_t * style  = lv_canvas_get_style(canvas, LV_CANVAS_STYLE_MAIN);\n    int32_t sinma             = lv_trigo_sin(-angle);\n    int32_t cosma             = lv_trigo_sin(-angle + 90); /* cos */\n\n    int32_t img_width   = img->header.w;\n    int32_t img_height  = img->header.h;\n    int32_t dest_width  = ext_dst->dsc.header.w;\n    int32_t dest_height = ext_dst->dsc.header.h;\n\n    int32_t x;\n    int32_t y;\n    for(x = -offset_x; x < dest_width - offset_x; x++) {\n        for(y = -offset_y; y < dest_height - offset_y; y++) {\n            /*Get the target point relative coordinates to the pivot*/\n            int32_t xt = x - pivot_x;\n            int32_t yt = y - pivot_y;\n\n            /*Get the source pixel from the upscaled image*/\n            int32_t xs = ((cosma * xt - sinma * yt) >> (LV_TRIGO_SHIFT - 8)) + pivot_x * 256;\n            int32_t ys = ((sinma * xt + cosma * yt) >> (LV_TRIGO_SHIFT - 8)) + pivot_y * 256;\n\n            /*Get the integer part of the source pixel*/\n            int xs_int = xs >> 8;\n            int ys_int = ys >> 8;\n\n            if(xs_int >= img_width)\n                continue;\n            else if(xs_int < 0)\n                continue;\n\n            if(ys_int >= img_height)\n                continue;\n            else if(ys_int < 0)\n                continue;\n\n            /*Get the fractional part of the source pixel*/\n            int xs_fract = xs & 0xff;\n            int ys_fract = ys & 0xff;\n\n            /* If the fractional < 0x70 mix the source pixel with the left/top pixel\n             * If the fractional > 0x90 mix the source pixel with the right/bottom pixel\n             * In the 0x70..0x90 range use the unchanged source pixel */\n\n            int xn;      /*x neightboor*/\n            lv_opa_t xr; /*x mix ratio*/\n            if(xs_fract < 0x70) {\n                xn = xs_int - 1;\n                xr = xs_fract * 2;\n            } else if(xs_fract > 0x90) {\n                xn = xs_int + 1;\n                xr = (0xFF - xs_fract) * 2;\n            } else {\n                xn = xs_int;\n                xr = 0xFF;\n            }\n\n            /*Handle under/overflow*/\n            if(xn >= img_width)\n                continue;\n            else if(xn < 0)\n                continue;\n\n            int yn;      /*y neightboor*/\n            lv_opa_t yr; /*y mix ratio*/\n            if(ys_fract < 0x70) {\n                yn = ys_int - 1;\n                yr = ys_fract * 2;\n            } else if(ys_fract > 0x90) {\n                yn = ys_int + 1;\n                yr = (0xFF - ys_fract) * 2;\n            } else {\n                yn = ys_int;\n                yr = 0xFF;\n            }\n\n            /*Handle under/overflow*/\n            if(yn >= img_height)\n                continue;\n            else if(yn < 0)\n                continue;\n\n            /*Get the mixture of the original source and the neightboor pixels in both directions*/\n            lv_color_t c_dest_int = lv_img_buf_get_px_color(img, xs_int, ys_int, style);\n\n            if(lv_img_color_format_is_chroma_keyed(img->header.cf)) {\n                lv_color_t ct = LV_COLOR_TRANSP;\n                if(c_dest_int.full == ct.full) continue;\n            }\n\n            lv_color_t c_dest_xn = lv_img_buf_get_px_color(img, xn, ys_int, style);\n            lv_color_t c_dest_yn = lv_img_buf_get_px_color(img, xs_int, yn, style);\n            lv_color_t x_dest    = lv_color_mix(c_dest_int, c_dest_xn, xr);\n            lv_color_t y_dest    = lv_color_mix(c_dest_int, c_dest_yn, yr);\n            lv_color_t color_res = lv_color_mix(x_dest, y_dest, LV_OPA_50);\n\n            if(x + offset_x >= 0 && x + offset_x < dest_width && y + offset_y >= 0 && y + offset_y < dest_height) {\n                /*If the image has no alpha channel just simple set the result color on the canvas*/\n                if(lv_img_color_format_has_alpha(img->header.cf) == false) {\n                    lv_img_buf_set_px_color(&ext_dst->dsc, x + offset_x, y + offset_y, color_res);\n                } else {\n                    /*Get result pixel opacity*/\n                    lv_opa_t opa_int = lv_img_buf_get_px_alpha(img, xs_int, ys_int);\n                    lv_opa_t opa_xn  = lv_img_buf_get_px_alpha(img, xn, ys_int);\n                    lv_opa_t opa_yn  = lv_img_buf_get_px_alpha(img, xs_int, yn);\n                    lv_opa_t opa_x   = (opa_int * xr + (opa_xn * (255 - xr))) >> 8;\n                    lv_opa_t opa_y   = (opa_int * yr + (opa_yn * (255 - yr))) >> 8;\n                    lv_opa_t opa_res = (opa_x + opa_y) / 2;\n                    if(opa_res <= LV_OPA_MIN) continue;\n\n                    lv_color_t bg_color = lv_img_buf_get_px_color(&ext_dst->dsc, x + offset_x, y + offset_y, style);\n\n                    /*If the canvas has no alpha but the image has mix the image's color with\n                     * canvas*/\n                    if(lv_img_color_format_has_alpha(ext_dst->dsc.header.cf) == false) {\n                        if(opa_res < LV_OPA_MAX) color_res = lv_color_mix(color_res, bg_color, opa_res);\n                        lv_img_buf_set_px_color(&ext_dst->dsc, x + offset_x, y + offset_y, color_res);\n                    }\n                    /*Both the image and canvas has alpha channel. Some extra calculation is\n                       required*/\n                    else {\n                        lv_opa_t bg_opa = lv_img_buf_get_px_alpha(&ext_dst->dsc, x + offset_x, y + offset_y);\n                        /* Pick the foreground if it's fully opaque or the Background is fully\n                         * transparent*/\n                        if(opa_res >= LV_OPA_MAX || bg_opa <= LV_OPA_MIN) {\n                            lv_img_buf_set_px_color(&ext_dst->dsc, x + offset_x, y + offset_y, color_res);\n                            lv_img_buf_set_px_alpha(&ext_dst->dsc, x + offset_x, y + offset_y, opa_res);\n                        }\n                        /*Opaque background: use simple mix*/\n                        else if(bg_opa >= LV_OPA_MAX) {\n                            lv_img_buf_set_px_color(&ext_dst->dsc, x + offset_x, y + offset_y,\n                                                    lv_color_mix(color_res, bg_color, opa_res));\n                        }\n                        /*Both colors have alpha. Expensive calculation need to be applied*/\n                        else {\n\n                            /*Info:\n                             * https://en.wikipedia.org/wiki/Alpha_compositing#Analytical_derivation_of_the_over_operator*/\n                            lv_opa_t opa_res_2 = 255 - ((uint16_t)((uint16_t)(255 - opa_res) * (255 - bg_opa)) >> 8);\n                            if(opa_res_2 == 0) {\n                                opa_res_2 = 1; /*never happens, just to be sure*/\n                            }\n                            lv_opa_t ratio = (uint16_t)((uint16_t)opa_res * 255) / opa_res_2;\n\n                            lv_img_buf_set_px_color(&ext_dst->dsc, x + offset_x, y + offset_y,\n                                                    lv_color_mix(color_res, bg_color, ratio));\n                            lv_img_buf_set_px_alpha(&ext_dst->dsc, x + offset_x, y + offset_y, opa_res_2);\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    lv_obj_invalidate(canvas);\n}\n\n/**\n * Fill the canvas with color\n * @param canvas pointer to a canvas\n * @param color the background color\n */\nvoid lv_canvas_fill_bg(lv_obj_t * canvas, lv_color_t color)\n{\n    lv_img_dsc_t * dsc = lv_canvas_get_img(canvas);\n\n    uint32_t x = dsc->header.w * dsc->header.h;\n    uint32_t y;\n    for(y = 0; y < dsc->header.h; y++) {\n        for(x = 0; x < dsc->header.w; x++) {\n            lv_img_buf_set_px_color(dsc, x, y, color);\n        }\n    }\n}\n\n/**\n * Draw a rectangle on the canvas\n * @param canvas pointer to a canvas object\n * @param x left coordinate of the rectangle\n * @param y top coordinate of the rectangle\n * @param w width of the rectangle\n * @param h height of the rectangle\n * @param style style of the rectangle (`body` properties are used except `padding`)\n */\nvoid lv_canvas_draw_rect(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h,\n                         const lv_style_t * style)\n{\n    lv_img_dsc_t * dsc = lv_canvas_get_img(canvas);\n\n    /* Create a dummy display to fool the lv_draw function.\n     * It will think it draws to real screen. */\n    lv_area_t mask;\n    mask.x1 = 0;\n    mask.x2 = dsc->header.w - 1;\n    mask.y1 = 0;\n    mask.y2 = dsc->header.h - 1;\n\n    lv_area_t coords;\n    coords.x1 = x;\n    coords.y1 = y;\n    coords.x2 = x + w - 1;\n    coords.y2 = y + h - 1;\n\n    lv_disp_t disp;\n    memset(&disp, 0, sizeof(lv_disp_t));\n\n    lv_disp_buf_t disp_buf;\n    lv_disp_buf_init(&disp_buf, (void *)dsc->data, NULL, dsc->header.w * dsc->header.h);\n    lv_area_copy(&disp_buf.area, &mask);\n\n    lv_disp_drv_init(&disp.driver);\n\n    disp.driver.buffer  = &disp_buf;\n    disp.driver.hor_res = dsc->header.w;\n    disp.driver.ver_res = dsc->header.h;\n\n    /*Disable anti-aliasing if drawing with transparent color to chroma keyed canvas*/\n    lv_color_t ctransp = LV_COLOR_TRANSP;\n    if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED &&\n        style->body.main_color.full == ctransp.full &&\n        style->body.grad_color.full == ctransp.full)\n    {\n        disp.driver.antialiasing = 0;\n    }\n\n    lv_disp_t * refr_ori = lv_refr_get_disp_refreshing();\n    lv_refr_set_disp_refreshing(&disp);\n\n    lv_draw_rect(&coords, &mask, style, LV_OPA_COVER);\n\n    lv_refr_set_disp_refreshing(refr_ori);\n}\n\n/**\n * Draw a text on the canvas.\n * @param canvas pointer to a canvas object\n * @param x left coordinate of the text\n * @param y top coordinate of the text\n * @param max_w max width of the text. The text will be wrapped to fit into this size\n * @param style style of the text (`text` properties are used)\n * @param txt text to display\n * @param align align of the text (`LV_LABEL_ALIGN_LEFT/RIGHT/CENTER`)\n */\nvoid lv_canvas_draw_text(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t max_w, const lv_style_t * style,\n                         const char * txt, lv_label_align_t align)\n{\n    lv_img_dsc_t * dsc = lv_canvas_get_img(canvas);\n\n    /* Create a dummy display to fool the lv_draw function.\n     * It will think it draws to real screen. */\n    lv_area_t mask;\n    mask.x1 = 0;\n    mask.x2 = dsc->header.w - 1;\n    mask.y1 = 0;\n    mask.y2 = dsc->header.h - 1;\n\n    lv_area_t coords;\n    coords.x1 = x;\n    coords.y1 = y;\n    coords.x2 = x + max_w - 1;\n    coords.y2 = dsc->header.h - 1;\n\n    lv_disp_t disp;\n    memset(&disp, 0, sizeof(lv_disp_t));\n\n    lv_disp_buf_t disp_buf;\n    lv_disp_buf_init(&disp_buf, (void *)dsc->data, NULL, dsc->header.w * dsc->header.h);\n    lv_area_copy(&disp_buf.area, &mask);\n\n    lv_disp_drv_init(&disp.driver);\n\n    disp.driver.buffer  = &disp_buf;\n    disp.driver.hor_res = dsc->header.w;\n    disp.driver.ver_res = dsc->header.h;\n\n    lv_disp_t * refr_ori = lv_refr_get_disp_refreshing();\n    lv_refr_set_disp_refreshing(&disp);\n\n    lv_txt_flag_t flag;\n    switch(align) {\n        case LV_LABEL_ALIGN_LEFT: flag = LV_TXT_FLAG_NONE; break;\n        case LV_LABEL_ALIGN_RIGHT: flag = LV_TXT_FLAG_RIGHT; break;\n        case LV_LABEL_ALIGN_CENTER: flag = LV_TXT_FLAG_CENTER; break;\n        default: flag = LV_TXT_FLAG_NONE; break;\n    }\n\n    lv_draw_label(&coords, &mask, style, LV_OPA_COVER, txt, flag, NULL, LV_LABEL_TEXT_SEL_OFF, LV_LABEL_TEXT_SEL_OFF,\n                  NULL);\n\n    lv_refr_set_disp_refreshing(refr_ori);\n}\n\n/**\n * Draw an image on the canvas\n * @param canvas pointer to a canvas object\n * @param src image source. Can be a pointer an `lv_img_dsc_t` variable or a path an image.\n * @param style style of the image (`image` properties are used)\n */\nvoid lv_canvas_draw_img(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, const void * src, const lv_style_t * style)\n{\n    lv_img_dsc_t * dsc = lv_canvas_get_img(canvas);\n\n    /* Create a dummy display to fool the lv_draw function.\n     * It will think it draws to real screen. */\n    lv_area_t mask;\n    mask.x1 = 0;\n    mask.x2 = dsc->header.w - 1;\n    mask.y1 = 0;\n    mask.y2 = dsc->header.h - 1;\n\n    lv_img_header_t header;\n    lv_res_t res = lv_img_decoder_get_info(src, &header);\n    if(res != LV_RES_OK) {\n        LV_LOG_WARN(\"lv_canvas_draw_img: Couldn't get the image data.\");\n        return;\n    }\n\n    lv_area_t coords;\n    coords.x1 = x;\n    coords.y1 = y;\n    coords.x2 = x + header.w - 1;\n    coords.y2 = y + header.h - 1;\n\n    lv_disp_t disp;\n    memset(&disp, 0, sizeof(lv_disp_t));\n\n    lv_disp_buf_t disp_buf;\n    lv_disp_buf_init(&disp_buf, (void *)dsc->data, NULL, dsc->header.w * dsc->header.h);\n    lv_area_copy(&disp_buf.area, &mask);\n\n    lv_disp_drv_init(&disp.driver);\n\n    disp.driver.buffer  = &disp_buf;\n    disp.driver.hor_res = dsc->header.w;\n    disp.driver.ver_res = dsc->header.h;\n\n    lv_disp_t * refr_ori = lv_refr_get_disp_refreshing();\n    lv_refr_set_disp_refreshing(&disp);\n\n    lv_draw_img(&coords, &mask, src, style, LV_OPA_COVER);\n\n    lv_refr_set_disp_refreshing(refr_ori);\n}\n\n/**\n * Draw a line on the canvas\n * @param canvas pointer to a canvas object\n * @param points point of the line\n * @param point_cnt number of points\n * @param style style of the line (`line` properties are used)\n */\nvoid lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t * points, uint32_t point_cnt, const lv_style_t * style)\n{\n    lv_img_dsc_t * dsc = lv_canvas_get_img(canvas);\n\n    /* Create a dummy display to fool the lv_draw function.\n     * It will think it draws to real screen. */\n    lv_area_t mask;\n    mask.x1 = 0;\n    mask.x2 = dsc->header.w - 1;\n    mask.y1 = 0;\n    mask.y2 = dsc->header.h - 1;\n\n    lv_disp_t disp;\n    memset(&disp, 0, sizeof(lv_disp_t));\n\n    lv_disp_buf_t disp_buf;\n    lv_disp_buf_init(&disp_buf, (void *)dsc->data, NULL, dsc->header.w * dsc->header.h);\n    lv_area_copy(&disp_buf.area, &mask);\n\n    lv_disp_drv_init(&disp.driver);\n\n    disp.driver.buffer  = &disp_buf;\n    disp.driver.hor_res = dsc->header.w;\n    disp.driver.ver_res = dsc->header.h;\n\n    /*Disable anti-aliasing if drawing with transparent color to chroma keyed canvas*/\n    lv_color_t ctransp = LV_COLOR_TRANSP;\n    if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED &&\n        style->body.main_color.full == ctransp.full &&\n        style->body.grad_color.full == ctransp.full)\n    {\n        disp.driver.antialiasing = 0;\n    }\n\n    lv_disp_t * refr_ori = lv_refr_get_disp_refreshing();\n    lv_refr_set_disp_refreshing(&disp);\n\n    uint32_t i;\n    for(i = 0; i < point_cnt - 1; i++) {\n        lv_draw_line(&points[i], &points[i + 1], &mask, style, LV_OPA_COVER);\n    }\n\n    lv_refr_set_disp_refreshing(refr_ori);\n}\n\n/**\n * Draw a polygon on the canvas\n * @param canvas pointer to a canvas object\n * @param points point of the polygon\n * @param point_cnt number of points\n * @param style style of the polygon (`body.main_color` and `body.opa` is used)\n */\nvoid lv_canvas_draw_polygon(lv_obj_t * canvas, const lv_point_t * points, uint32_t point_cnt, const lv_style_t * style)\n{\n    lv_img_dsc_t * dsc = lv_canvas_get_img(canvas);\n\n    /* Create a dummy display to fool the lv_draw function.\n     * It will think it draws to real screen. */\n    lv_area_t mask;\n    mask.x1 = 0;\n    mask.x2 = dsc->header.w - 1;\n    mask.y1 = 0;\n    mask.y2 = dsc->header.h - 1;\n\n    lv_disp_t disp;\n    memset(&disp, 0, sizeof(lv_disp_t));\n\n    lv_disp_buf_t disp_buf;\n    lv_disp_buf_init(&disp_buf, (void *)dsc->data, NULL, dsc->header.w * dsc->header.h);\n    lv_area_copy(&disp_buf.area, &mask);\n\n    lv_disp_drv_init(&disp.driver);\n\n    disp.driver.buffer  = &disp_buf;\n    disp.driver.hor_res = dsc->header.w;\n    disp.driver.ver_res = dsc->header.h;\n\n    /*Disable anti-aliasing if drawing with transparent color to chroma keyed canvas*/\n    lv_color_t ctransp = LV_COLOR_TRANSP;\n    if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED &&\n        style->body.main_color.full == ctransp.full &&\n        style->body.grad_color.full == ctransp.full)\n    {\n        disp.driver.antialiasing = 0;\n    }\n\n    lv_disp_t * refr_ori = lv_refr_get_disp_refreshing();\n    lv_refr_set_disp_refreshing(&disp);\n\n    lv_draw_polygon(points, point_cnt, &mask, style, LV_OPA_COVER);\n\n    lv_refr_set_disp_refreshing(refr_ori);\n}\n\n/**\n * Draw an arc on the canvas\n * @param canvas pointer to a canvas object\n * @param x origo x  of the arc\n * @param y origo y of the arc\n * @param r radius of the arc\n * @param start_angle start angle in degrees\n * @param end_angle end angle in degrees\n * @param style style of the polygon (`body.main_color` and `body.opa` is used)\n */\nvoid lv_canvas_draw_arc(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t r, int32_t start_angle,\n                        int32_t end_angle, const lv_style_t * style)\n{\n    lv_img_dsc_t * dsc = lv_canvas_get_img(canvas);\n\n    /* Create a dummy display to fool the lv_draw function.\n     * It will think it draws to real screen. */\n    lv_area_t mask;\n    mask.x1 = 0;\n    mask.x2 = dsc->header.w - 1;\n    mask.y1 = 0;\n    mask.y2 = dsc->header.h - 1;\n\n    lv_disp_t disp;\n    memset(&disp, 0, sizeof(lv_disp_t));\n\n    lv_disp_buf_t disp_buf;\n    lv_disp_buf_init(&disp_buf, (void *)dsc->data, NULL, dsc->header.w * dsc->header.h);\n    lv_area_copy(&disp_buf.area, &mask);\n\n    lv_disp_drv_init(&disp.driver);\n\n    disp.driver.buffer  = &disp_buf;\n    disp.driver.hor_res = dsc->header.w;\n    disp.driver.ver_res = dsc->header.h;\n\n    /*Disable anti-aliasing if drawing with transparent color to chroma keyed canvas*/\n    lv_color_t ctransp = LV_COLOR_TRANSP;\n    if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED &&\n        style->body.main_color.full == ctransp.full &&\n        style->body.grad_color.full == ctransp.full)\n    {\n        disp.driver.antialiasing = 0;\n    }\n\n    lv_disp_t * refr_ori = lv_refr_get_disp_refreshing();\n    lv_refr_set_disp_refreshing(&disp);\n\n    lv_draw_arc(x, y, r, &mask, start_angle, end_angle, style, LV_OPA_COVER);\n\n    lv_refr_set_disp_refreshing(refr_ori);\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Signal function of the canvas\n * @param canvas pointer to a canvas object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_canvas_signal(lv_obj_t * canvas, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(canvas, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    if(sign == LV_SIGNAL_CLEANUP) {\n        /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_canvas\";\n    }\n\n    return res;\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_cb.c",
    "content": "/**\n * @file lv_cb.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_cb.h\"\n#if LV_USE_CB != 0\n\n#include \"libs/lvgl/lv_core/lv_group.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_cb_design(lv_obj_t * cb, const lv_area_t * mask, lv_design_mode_t mode);\nstatic bool lv_bullet_design(lv_obj_t * bullet, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_cb_signal(lv_obj_t * cb, lv_signal_t sign, void * param);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_design_cb_t ancestor_bg_design;\nstatic lv_design_cb_t ancestor_bullet_design;\nstatic lv_signal_cb_t ancestor_signal;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a check box objects\n * @param par pointer to an object, it will be the parent of the new check box\n * @param copy pointer to a check box object, if not NULL then the new object will be copied from it\n * @return pointer to the created check box\n */\nlv_obj_t * lv_cb_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n\n    LV_LOG_TRACE(\"check box create started\");\n\n    /*Create the ancestor basic object*/\n    lv_obj_t * new_cb = lv_btn_create(par, copy);\n    lv_mem_assert(new_cb);\n    if(new_cb == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_cb);\n    if(ancestor_bg_design == NULL) ancestor_bg_design = lv_obj_get_design_cb(new_cb);\n\n    lv_cb_ext_t * ext = lv_obj_allocate_ext_attr(new_cb, sizeof(lv_cb_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    ext->bullet = NULL;\n    ext->label  = NULL;\n\n    lv_obj_set_signal_cb(new_cb, lv_cb_signal);\n    lv_obj_set_design_cb(new_cb, lv_cb_design);\n\n    /*Init the new checkbox object*/\n    if(copy == NULL) {\n        ext->bullet = lv_btn_create(new_cb, NULL);\n        if(ancestor_bullet_design == NULL) ancestor_bullet_design = lv_obj_get_design_cb(ext->bullet);\n        lv_obj_set_click(ext->bullet, false);\n\n        ext->label = lv_label_create(new_cb, NULL);\n\n        lv_cb_set_text(new_cb, \"Check box\");\n        lv_btn_set_layout(new_cb, LV_LAYOUT_ROW_M);\n        lv_btn_set_fit(new_cb, LV_FIT_TIGHT);\n        lv_btn_set_toggle(new_cb, true);\n        lv_obj_set_protect(new_cb, LV_PROTECT_PRESS_LOST);\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_cb_set_style(new_cb, LV_CB_STYLE_BG, th->style.cb.bg);\n            lv_cb_set_style(new_cb, LV_CB_STYLE_BOX_REL, th->style.cb.box.rel);\n            lv_cb_set_style(new_cb, LV_CB_STYLE_BOX_PR, th->style.cb.box.pr);\n            lv_cb_set_style(new_cb, LV_CB_STYLE_BOX_TGL_REL, th->style.cb.box.tgl_rel);\n            lv_cb_set_style(new_cb, LV_CB_STYLE_BOX_TGL_PR, th->style.cb.box.tgl_pr);\n            lv_cb_set_style(new_cb, LV_CB_STYLE_BOX_INA, th->style.cb.box.ina);\n        } else {\n            lv_cb_set_style(new_cb, LV_CB_STYLE_BG, &lv_style_transp);\n            lv_cb_set_style(new_cb, LV_CB_STYLE_BOX_REL, &lv_style_pretty);\n        }\n    } else {\n        lv_cb_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->bullet            = lv_btn_create(new_cb, copy_ext->bullet);\n        ext->label             = lv_label_create(new_cb, copy_ext->label);\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_cb);\n    }\n\n    lv_obj_set_design_cb(ext->bullet, lv_bullet_design);\n\n    LV_LOG_INFO(\"check box created\");\n\n    return new_cb;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the text of a check box. `txt` will be copied and may be deallocated\n * after this function returns.\n * @param cb pointer to a check box\n * @param txt the text of the check box. NULL to refresh with the current text.\n */\nvoid lv_cb_set_text(lv_obj_t * cb, const char * txt)\n{\n    lv_cb_ext_t * ext = lv_obj_get_ext_attr(cb);\n    lv_label_set_text(ext->label, txt);\n}\n\n/**\n * Set the text of a check box. `txt` must not be deallocated during the life\n * of this checkbox.\n * @param cb pointer to a check box\n * @param txt the text of the check box. NULL to refresh with the current text.\n */\nvoid lv_cb_set_static_text(lv_obj_t * cb, const char * txt)\n{\n    lv_cb_ext_t * ext = lv_obj_get_ext_attr(cb);\n    lv_label_set_static_text(ext->label, txt);\n}\n\n/**\n * Set a style of a check box\n * @param cb pointer to check box object\n * @param type which style should be set\n * @param style pointer to a style\n *  */\nvoid lv_cb_set_style(lv_obj_t * cb, lv_cb_style_t type, const lv_style_t * style)\n{\n    lv_cb_ext_t * ext = lv_obj_get_ext_attr(cb);\n\n    switch(type) {\n        case LV_CB_STYLE_BG:\n            lv_btn_set_style(cb, LV_BTN_STYLE_REL, style);\n            lv_btn_set_style(cb, LV_BTN_STYLE_PR, style);\n            lv_btn_set_style(cb, LV_BTN_STYLE_TGL_REL, style);\n            lv_btn_set_style(cb, LV_BTN_STYLE_TGL_PR, style);\n            lv_btn_set_style(cb, LV_BTN_STYLE_INA, style);\n            break;\n        case LV_CB_STYLE_BOX_REL: lv_btn_set_style(ext->bullet, LV_BTN_STYLE_REL, style); break;\n        case LV_CB_STYLE_BOX_PR: lv_btn_set_style(ext->bullet, LV_BTN_STYLE_PR, style); break;\n        case LV_CB_STYLE_BOX_TGL_REL: lv_btn_set_style(ext->bullet, LV_BTN_STYLE_TGL_REL, style); break;\n        case LV_CB_STYLE_BOX_TGL_PR: lv_btn_set_style(ext->bullet, LV_BTN_STYLE_TGL_PR, style); break;\n        case LV_CB_STYLE_BOX_INA: lv_btn_set_style(ext->bullet, LV_BTN_STYLE_INA, style); break;\n    }\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the text of a check box\n * @param cb pointer to check box object\n * @return pointer to the text of the check box\n */\nconst char * lv_cb_get_text(const lv_obj_t * cb)\n{\n    lv_cb_ext_t * ext = lv_obj_get_ext_attr(cb);\n    return lv_label_get_text(ext->label);\n}\n\n/**\n * Get a style of a button\n * @param cb pointer to check box object\n * @param type which style should be get\n * @return style pointer to the style\n *  */\nconst lv_style_t * lv_cb_get_style(const lv_obj_t * cb, lv_cb_style_t type)\n{\n    const lv_style_t * style = NULL;\n    lv_cb_ext_t * ext        = lv_obj_get_ext_attr(cb);\n\n    switch(type) {\n        case LV_CB_STYLE_BOX_REL: style = lv_btn_get_style(ext->bullet, LV_BTN_STYLE_REL); break;\n        case LV_CB_STYLE_BOX_PR: style = lv_btn_get_style(ext->bullet, LV_BTN_STYLE_PR); break;\n        case LV_CB_STYLE_BOX_TGL_REL: style = lv_btn_get_style(ext->bullet, LV_BTN_STYLE_TGL_REL); break;\n        case LV_CB_STYLE_BOX_TGL_PR: style = lv_btn_get_style(ext->bullet, LV_BTN_STYLE_TGL_PR); break;\n        case LV_CB_STYLE_BOX_INA: style = lv_btn_get_style(ext->bullet, LV_BTN_STYLE_INA); break;\n        default: style = NULL; break;\n    }\n\n    return style;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the check boxes\n * @param cb pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_cb_design(lv_obj_t * cb, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    bool result = true;\n\n    if(mode == LV_DESIGN_COVER_CHK) {\n        /*Return false if the object is not covers the mask_p area*/\n        result = ancestor_bg_design(cb, mask, mode);\n    } else if(mode == LV_DESIGN_DRAW_MAIN || mode == LV_DESIGN_DRAW_POST) {\n        lv_cb_ext_t * cb_ext      = lv_obj_get_ext_attr(cb);\n        lv_btn_ext_t * bullet_ext = lv_obj_get_ext_attr(cb_ext->bullet);\n\n        /*Be sure the state of the bullet is the same as the parent button*/\n        bullet_ext->state = cb_ext->bg_btn.state;\n\n        result = ancestor_bg_design(cb, mask, mode);\n\n    } else {\n        result = ancestor_bg_design(cb, mask, mode);\n    }\n\n    return result;\n}\n\n/**\n * Handle the drawing related tasks of the check boxes\n * @param bullet pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_bullet_design(lv_obj_t * bullet, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    if(mode == LV_DESIGN_COVER_CHK) {\n        return ancestor_bullet_design(bullet, mask, mode);\n    } else if(mode == LV_DESIGN_DRAW_MAIN) {\n#if LV_USE_GROUP\n        /* If the check box is the active in a group and\n         * the background is not visible (transparent)\n         * then activate the style of the bullet*/\n        const lv_style_t * style_ori  = lv_obj_get_style(bullet);\n        lv_obj_t * bg                 = lv_obj_get_parent(bullet);\n        const lv_style_t * style_page = lv_obj_get_style(bg);\n        lv_group_t * g                = lv_obj_get_group(bg);\n        if(style_page->body.opa == LV_OPA_TRANSP) { /*Is the Background visible?*/\n            if(lv_group_get_focused(g) == bg) {\n                lv_style_t * style_mod;\n                style_mod       = lv_group_mod_style(g, style_ori);\n                bullet->style_p = style_mod; /*Temporally change the style to the activated */\n            }\n        }\n#endif\n        ancestor_bullet_design(bullet, mask, mode);\n\n#if LV_USE_GROUP\n        bullet->style_p = style_ori; /*Revert the style*/\n#endif\n    } else if(mode == LV_DESIGN_DRAW_POST) {\n        ancestor_bullet_design(bullet, mask, mode);\n    }\n\n    return true;\n}\n\n/**\n * Signal function of the check box\n * @param cb pointer to a check box object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_cb_signal(lv_obj_t * cb, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(cb, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_cb_ext_t * ext = lv_obj_get_ext_attr(cb);\n\n    if(sign == LV_SIGNAL_STYLE_CHG) {\n        const lv_style_t * label_style = lv_label_get_style(ext->label, LV_LABEL_STYLE_MAIN);\n        lv_obj_set_size(ext->bullet, lv_font_get_line_height(label_style->text.font),\n                        lv_font_get_line_height(label_style->text.font));\n        lv_btn_set_state(ext->bullet, lv_btn_get_state(cb));\n    } else if(sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) {\n        lv_btn_set_state(ext->bullet, lv_btn_get_state(cb));\n    } else if(sign == LV_SIGNAL_CONTROL) {\n        char c = *((char *)param);\n        if(c == LV_KEY_RIGHT || c == LV_KEY_DOWN || c == LV_KEY_LEFT || c == LV_KEY_UP) {\n            /*Follow the backgrounds state with the bullet*/\n            lv_btn_set_state(ext->bullet, lv_btn_get_state(cb));\n        }\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_cb\";\n    }\n\n    return res;\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_chart.c",
    "content": "/**\n * @file lv_chart.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_chart.h\"\n#if LV_USE_CHART != 0\n\n#include \"libs/lvgl/lv_core/lv_refr.h\"\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_CHART_YMIN_DEF 0\n#define LV_CHART_YMAX_DEF 100\n#define LV_CHART_HDIV_DEF 3\n#define LV_CHART_VDIV_DEF 5\n#define LV_CHART_PNUM_DEF 10\n#define LV_CHART_AXIS_TO_LABEL_DISTANCE 4\n#define LV_CHART_AXIS_MAJOR_TICK_LEN_COE 1 / 15\n#define LV_CHART_AXIS_MINOR_TICK_LEN_COE 2 / 3\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_chart_design(lv_obj_t * chart, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_chart_signal(lv_obj_t * chart, lv_signal_t sign, void * param);\nstatic void lv_chart_draw_div(lv_obj_t * chart, const lv_area_t * mask);\nstatic void lv_chart_draw_lines(lv_obj_t * chart, const lv_area_t * mask);\nstatic void lv_chart_draw_points(lv_obj_t * chart, const lv_area_t * mask);\nstatic void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask);\nstatic void lv_chart_draw_vertical_lines(lv_obj_t * chart, const lv_area_t * mask);\nstatic void lv_chart_draw_areas(lv_obj_t * chart, const lv_area_t * mask);\nstatic void lv_chart_draw_axes(lv_obj_t * chart, const lv_area_t * mask);\nstatic void lv_chart_inv_lines(lv_obj_t * chart, uint16_t i);\nstatic void lv_chart_inv_points(lv_obj_t * chart, uint16_t i);\nstatic void lv_chart_inv_cols(lv_obj_t * chart, uint16_t i);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_design_cb_t ancestor_design_f;\nstatic lv_signal_cb_t ancestor_signal;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a chart background objects\n * @param par pointer to an object, it will be the parent of the new chart background\n * @param copy pointer to a chart background object, if not NULL then the new object will be copied\n * from it\n * @return pointer to the created chart background\n */\nlv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"chart create started\");\n\n    /*Create the ancestor basic object*/\n    lv_obj_t * new_chart = lv_obj_create(par, copy);\n    lv_mem_assert(new_chart);\n    if(new_chart == NULL) return NULL;\n\n    /*Allocate the object type specific extended data*/\n    lv_chart_ext_t * ext = lv_obj_allocate_ext_attr(new_chart, sizeof(lv_chart_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    lv_ll_init(&ext->series_ll, sizeof(lv_chart_series_t));\n\n    ext->series.num            = 0;\n    ext->ymin                  = LV_CHART_YMIN_DEF;\n    ext->ymax                  = LV_CHART_YMAX_DEF;\n    ext->hdiv_cnt              = LV_CHART_HDIV_DEF;\n    ext->vdiv_cnt              = LV_CHART_VDIV_DEF;\n    ext->point_cnt             = LV_CHART_PNUM_DEF;\n    ext->type                  = LV_CHART_TYPE_LINE;\n    ext->update_mode           = LV_CHART_UPDATE_MODE_SHIFT;\n    ext->series.opa            = LV_OPA_COVER;\n    ext->series.dark           = LV_OPA_50;\n    ext->series.width          = 2;\n    ext->margin                = 0;\n    memset(&ext->x_axis, 0, sizeof(ext->x_axis));\n    memset(&ext->y_axis, 0, sizeof(ext->y_axis));\n    ext->x_axis.major_tick_len = LV_CHART_TICK_LENGTH_AUTO;\n    ext->x_axis.minor_tick_len = LV_CHART_TICK_LENGTH_AUTO;\n    ext->y_axis.major_tick_len = LV_CHART_TICK_LENGTH_AUTO;\n    ext->y_axis.minor_tick_len = LV_CHART_TICK_LENGTH_AUTO;\n\n    if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_cb(new_chart);\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_chart);\n\n    lv_obj_set_signal_cb(new_chart, lv_chart_signal);\n    lv_obj_set_design_cb(new_chart, lv_chart_design);\n\n    /*Init the new chart background object*/\n    if(copy == NULL) {\n        lv_obj_set_size(new_chart, LV_DPI * 3, LV_DPI * 2);\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_chart_set_style(new_chart, LV_CHART_STYLE_MAIN, th->style.chart);\n        } else {\n            lv_chart_set_style(new_chart, LV_CHART_STYLE_MAIN, &lv_style_pretty);\n        }\n\n    } else {\n        lv_chart_ext_t * ext_copy = lv_obj_get_ext_attr(copy);\n\n        ext->type       = ext_copy->type;\n        ext->ymin       = ext_copy->ymin;\n        ext->ymax       = ext_copy->ymax;\n        ext->hdiv_cnt   = ext_copy->hdiv_cnt;\n        ext->vdiv_cnt   = ext_copy->vdiv_cnt;\n        ext->point_cnt  = ext_copy->point_cnt;\n        ext->series.opa = ext_copy->series.opa;\n        ext->margin     = ext_copy->margin;\n        memcpy(&ext->x_axis, &ext_copy->x_axis, sizeof(lv_chart_axis_cfg_t));\n        memcpy(&ext->y_axis, &ext_copy->y_axis, sizeof(lv_chart_axis_cfg_t));\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_chart);\n    }\n\n    LV_LOG_INFO(\"chart created\");\n\n    return new_chart;\n}\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/**\n * Allocate and add a data series to the chart\n * @param chart pointer to a chart object\n * @param color color of the data series\n * @return pointer to the allocated data series\n */\nlv_chart_series_t * lv_chart_add_series(lv_obj_t * chart, lv_color_t color)\n{\n    lv_chart_ext_t * ext    = lv_obj_get_ext_attr(chart);\n    lv_chart_series_t * ser = lv_ll_ins_head(&ext->series_ll);\n    lv_mem_assert(ser);\n    if(ser == NULL) return NULL;\n\n    lv_coord_t def = LV_CHART_POINT_DEF;\n\n    if(ser == NULL) return NULL;\n\n    ser->color  = color;\n    ser->points = lv_mem_alloc(sizeof(lv_coord_t) * ext->point_cnt);\n    lv_mem_assert(ser->points);\n    if(ser->points == NULL) {\n        lv_ll_rem(&ext->series_ll, ser);\n        lv_mem_free(ser);\n        return NULL;\n    }\n\n    ser->start_point = 0;\n\n    uint16_t i;\n    lv_coord_t * p_tmp = ser->points;\n    for(i = 0; i < ext->point_cnt; i++) {\n        *p_tmp = def;\n        p_tmp++;\n    }\n\n    ext->series.num++;\n\n    return ser;\n}\n\n/**\n * Clear the point of a serie\n * @param chart pointer to a chart object\n * @param serie pointer to the chart's serie to clear\n */\nvoid lv_chart_clear_serie(lv_obj_t * chart, lv_chart_series_t * serie)\n{\n    if(chart == NULL || serie == NULL) return;\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    if(ext == NULL) return;\n\n    uint32_t i;\n    for(i = 0; i < ext->point_cnt; i++) {\n        serie->points[i] = LV_CHART_POINT_DEF;\n    }\n\n    serie->start_point = 0;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the number of horizontal and vertical division lines\n * @param chart pointer to a graph background object\n * @param hdiv number of horizontal division lines\n * @param vdiv number of vertical division lines\n */\nvoid lv_chart_set_div_line_count(lv_obj_t * chart, uint8_t hdiv, uint8_t vdiv)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    if(ext->hdiv_cnt == hdiv && ext->vdiv_cnt == vdiv) return;\n\n    ext->hdiv_cnt = hdiv;\n    ext->vdiv_cnt = vdiv;\n\n    lv_obj_invalidate(chart);\n}\n\n/**\n * Set the minimal and maximal y values\n * @param chart pointer to a graph background object\n * @param ymin y minimum value\n * @param ymax y maximum value\n */\nvoid lv_chart_set_range(lv_obj_t * chart, lv_coord_t ymin, lv_coord_t ymax)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    if(ext->ymin == ymin && ext->ymax == ymax) return;\n\n    ext->ymin = ymin;\n    ext->ymax = ymax;\n\n    lv_chart_refresh(chart);\n}\n\n/**\n * Set a new type for a chart\n * @param chart pointer to a chart object\n * @param type new type of the chart (from 'lv_chart_type_t' enum)\n */\nvoid lv_chart_set_type(lv_obj_t * chart, lv_chart_type_t type)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    if(ext->type == type) return;\n\n    ext->type = type;\n\n    lv_chart_refresh(chart);\n}\n\n/**\n * Set the number of points on a data line on a chart\n * @param chart pointer r to chart object\n * @param point_cnt new number of points on the data lines\n */\nvoid lv_chart_set_point_count(lv_obj_t * chart, uint16_t point_cnt)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    if(ext->point_cnt == point_cnt) return;\n\n    lv_chart_series_t * ser;\n    uint16_t point_cnt_old = ext->point_cnt;\n    uint16_t i;\n    lv_coord_t def = LV_CHART_POINT_DEF;\n\n    if(point_cnt < 1) point_cnt = 1;\n\n    LV_LL_READ_BACK(ext->series_ll, ser)\n    {\n        if(ser->start_point != 0) {\n            lv_coord_t * new_points = lv_mem_alloc(sizeof(lv_coord_t) * point_cnt);\n            lv_mem_assert(new_points);\n            if(new_points == NULL) return;\n\n            if(point_cnt >= point_cnt_old) {\n                for(i = 0; i < point_cnt_old; i++) {\n                    new_points[i] =\n                        ser->points[(i + ser->start_point) % point_cnt_old]; /*Copy old contents to new array*/\n                }\n                for(i = point_cnt_old; i < point_cnt; i++) {\n                    new_points[i] = def; /*Fill up the rest with default value*/\n                }\n            } else {\n                for(i = 0; i < point_cnt; i++) {\n                    new_points[i] =\n                        ser->points[(i + ser->start_point) % point_cnt_old]; /*Copy old contents to new array*/\n                }\n            }\n\n            /*Switch over pointer from old to new*/\n            lv_mem_free(ser->points);\n            ser->points = new_points;\n        } else {\n            ser->points = lv_mem_realloc(ser->points, sizeof(lv_coord_t) * point_cnt);\n            lv_mem_assert(ser->points);\n            if(ser->points == NULL) return;\n            /*Initialize the new points*/\n            if(point_cnt > point_cnt_old) {\n                for(i = point_cnt_old - 1; i < point_cnt; i++) {\n                    ser->points[i] = def;\n                }\n            }\n        }\n\n        ser->start_point = 0;\n    }\n\n    ext->point_cnt = point_cnt;\n\n    lv_chart_refresh(chart);\n}\n\n/**\n * Set the opacity of the data series\n * @param chart pointer to a chart object\n * @param opa opacity of the data series\n */\nvoid lv_chart_set_series_opa(lv_obj_t * chart, lv_opa_t opa)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    if(ext->series.opa == opa) return;\n\n    ext->series.opa = opa;\n    lv_obj_invalidate(chart);\n}\n\n/**\n * Set the line width or point radius of the data series\n * @param chart pointer to a chart object\n * @param width the new width\n */\nvoid lv_chart_set_series_width(lv_obj_t * chart, lv_coord_t width)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    if(ext->series.width == width) return;\n\n    ext->series.width = width;\n    lv_obj_invalidate(chart);\n}\n/**\n * Set the dark effect on the bottom of the points or columns\n * @param chart pointer to a chart object\n * @param dark_eff dark effect level (LV_OPA_TRANSP to turn off)\n */\nvoid lv_chart_set_series_darking(lv_obj_t * chart, lv_opa_t dark_eff)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    if(ext->series.dark == dark_eff) return;\n\n    ext->series.dark = dark_eff;\n    lv_obj_invalidate(chart);\n}\n\n/**\n * Initialize all data points with a value\n * @param chart pointer to chart object\n * @param ser pointer to a data series on 'chart'\n * @param y the new value  for all points\n */\nvoid lv_chart_init_points(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    uint16_t i;\n    for(i = 0; i < ext->point_cnt; i++) {\n        ser->points[i] = y;\n    }\n    ser->start_point = 0;\n    lv_chart_refresh(chart);\n}\n\n/**\n * Set the value of points from an array\n * @param chart pointer to chart object\n * @param ser pointer to a data series on 'chart'\n * @param y_array array of 'lv_coord_t' points (with 'points count' elements )\n */\nvoid lv_chart_set_points(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y_array[])\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    memcpy(ser->points, y_array, ext->point_cnt * (sizeof(lv_coord_t)));\n    ser->start_point = 0;\n    lv_chart_refresh(chart);\n}\n\n/**\n * Shift all data left and set the rightmost data on a data line\n * @param chart pointer to chart object\n * @param ser pointer to a data series on 'chart'\n * @param y the new value of the rightmost data\n */\nvoid lv_chart_set_next(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    if(ext->update_mode == LV_CHART_UPDATE_MODE_SHIFT) {\n        ser->points[ser->start_point] =\n            y; /*This was the place of the former left most value, after shifting it is the rightmost*/\n        ser->start_point = (ser->start_point + 1) % ext->point_cnt;\n        lv_chart_refresh(chart);\n    } else if(ext->update_mode == LV_CHART_UPDATE_MODE_CIRCULAR) {\n        ser->points[ser->start_point] = y;\n\n        if(ext->type & LV_CHART_TYPE_LINE) lv_chart_inv_lines(chart, ser->start_point);\n        if(ext->type & LV_CHART_TYPE_COLUMN) lv_chart_inv_cols(chart, ser->start_point);\n        if(ext->type & LV_CHART_TYPE_POINT) lv_chart_inv_points(chart, ser->start_point);\n        if(ext->type & LV_CHART_TYPE_VERTICAL_LINE) lv_chart_inv_lines(chart, ser->start_point);\n        if(ext->type & LV_CHART_TYPE_AREA) lv_chart_inv_lines(chart, ser->start_point);\n\n        ser->start_point = (ser->start_point + 1) % ext->point_cnt; /*update the x for next incoming y*/\n    }\n}\n\n/**\n * Set update mode of the chart object.\n * @param chart pointer to a chart object\n * @param update mode\n */\nvoid lv_chart_set_update_mode(lv_obj_t * chart, lv_chart_update_mode_t update_mode)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    if(ext->update_mode == update_mode) return;\n\n    ext->update_mode = update_mode;\n    lv_obj_invalidate(chart);\n}\n\n/**\n * Set the length of the tick marks on the x axis\n * @param chart pointer to the chart\n * @param major_tick_len the length of the major tick or `LV_CHART_TICK_LENGTH_AUTO` to set automatically\n *                       (where labels are added)\n * @param minor_tick_len the length of the minor tick, `LV_CHART_TICK_LENGTH_AUTO` to set automatically\n *                       (where no labels are added)\n */\nvoid lv_chart_set_x_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_t minor_tick_len)\n{\n    lv_chart_ext_t * ext       = lv_obj_get_ext_attr(chart);\n    ext->x_axis.major_tick_len = major_tick_len;\n    ext->x_axis.minor_tick_len = minor_tick_len;\n}\n\n/**\n * Set the length of the tick marks on the y axis\n * @param chart pointer to the chart\n * @param major_tick_len the length of the major tick or `LV_CHART_TICK_LENGTH_AUTO` to set automatically\n *                       (where labels are added)\n * @param minor_tick_len the length of the minor tick, `LV_CHART_TICK_LENGTH_AUTO` to set automatically\n *                       (where no labels are added)\n */\nvoid lv_chart_set_y_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_t minor_tick_len)\n{\n    lv_chart_ext_t * ext       = lv_obj_get_ext_attr(chart);\n    ext->y_axis.major_tick_len = major_tick_len;\n    ext->y_axis.minor_tick_len = minor_tick_len;\n}\n\n/**\n * Set the x-axis tick count and labels of a chart\n * @param chart \t\t\tpointer to a chart object\n * @param list_of_values \tlist of string values, terminated with \\n, except the last\n * @param num_tick_marks \tif list_of_values is NULL: total number of ticks per axis\n * \t\t\t\t\t\t\telse number of ticks between two value labels\n * @param options\t\t\textra options\n */\nvoid lv_chart_set_x_tick_texts(lv_obj_t * chart, const char * list_of_values, uint8_t num_tick_marks,\n                               lv_chart_axis_options_t options)\n{\n    lv_chart_ext_t * ext       = lv_obj_get_ext_attr(chart);\n    ext->x_axis.num_tick_marks = num_tick_marks;\n    ext->x_axis.list_of_values = list_of_values;\n    ext->x_axis.options        = options;\n}\n\n/**\n * Set the y-axis tick count and labels of a chart\n * @param chart             pointer to a chart object\n * @param list_of_values    list of string values, terminated with \\n, except the last\n * @param num_tick_marks    if list_of_values is NULL: total number of ticks per axis\n *                          else number of ticks between two value labels\n * @param options           extra options\n */\nvoid lv_chart_set_y_tick_texts(lv_obj_t * chart, const char * list_of_values, uint8_t num_tick_marks,\n                               lv_chart_axis_options_t options)\n{\n    lv_chart_ext_t * ext       = lv_obj_get_ext_attr(chart);\n    ext->y_axis.num_tick_marks = num_tick_marks;\n    ext->y_axis.list_of_values = list_of_values;\n    ext->y_axis.options        = options;\n}\n\n/**\n * Set the margin around the chart, used for axes value and ticks\n * @param chart     pointer to an chart object\n * @param margin    value of the margin [px]\n */\nvoid lv_chart_set_margin(lv_obj_t * chart, uint16_t margin)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    ext->margin          = margin;\n    lv_obj_refresh_ext_draw_pad(chart);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the type of a chart\n * @param chart pointer to chart object\n * @return type of the chart (from 'lv_chart_t' enum)\n */\nlv_chart_type_t lv_chart_get_type(const lv_obj_t * chart)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    return ext->type;\n}\n\n/**\n * Get the data point number per data line on chart\n * @param chart pointer to chart object\n * @return point number on each data line\n */\nuint16_t lv_chart_get_point_cnt(const lv_obj_t * chart)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    return ext->point_cnt;\n}\n\n/**\n * Get the opacity of the data series\n * @param chart pointer to chart object\n * @return the opacity of the data series\n */\nlv_opa_t lv_chart_get_series_opa(const lv_obj_t * chart)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    return ext->series.opa;\n}\n\n/**\n * Get the data series width\n * @param chart pointer to chart object\n * @return the width the data series (lines or points)\n */\nlv_coord_t lv_chart_get_series_width(const lv_obj_t * chart)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    return ext->series.width;\n}\n\n/**\n * Get the dark effect level on the bottom of the points or columns\n * @param chart pointer to chart object\n * @return dark effect level (LV_OPA_TRANSP to turn off)\n */\nlv_opa_t lv_chart_get_series_darking(const lv_obj_t * chart)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    return ext->series.dark;\n}\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Refresh a chart if its data line has changed\n * @param chart pointer to chart object\n */\nvoid lv_chart_refresh(lv_obj_t * chart)\n{\n    lv_obj_invalidate(chart);\n}\n\n/**\n * Get the margin around the chart, used for axes value and labels\n * @param chart pointer to an chart object\n * @param return value of the margin\n */\nuint16_t lv_chart_get_margin(lv_obj_t * chart)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    return ext->margin;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the chart backgrounds\n * @param chart pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_chart_design(lv_obj_t * chart, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    if(mode == LV_DESIGN_COVER_CHK) {\n        /*Return false if the object is not covers the mask_p area*/\n        return ancestor_design_f(chart, mask, mode);\n    } else if(mode == LV_DESIGN_DRAW_MAIN) {\n        /*Draw the background*/\n        lv_draw_rect(&chart->coords, mask, lv_obj_get_style(chart), lv_obj_get_opa_scale(chart));\n\n        lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n\n        lv_chart_draw_div(chart, mask);\n\n        /* Adjust the mask to remove the margin (clips chart contents to be within background) */\n\n        lv_area_t mask_tmp, adjusted_mask;\n        lv_obj_get_coords(chart, &mask_tmp);\n\n        bool union_ok = lv_area_intersect(&adjusted_mask, mask, &mask_tmp);\n\n        if(union_ok) {\n                if(ext->type & LV_CHART_TYPE_LINE) lv_chart_draw_lines(chart, &adjusted_mask);\n                if(ext->type & LV_CHART_TYPE_COLUMN) lv_chart_draw_cols(chart, &adjusted_mask);\n                if(ext->type & LV_CHART_TYPE_POINT) lv_chart_draw_points(chart, &adjusted_mask);\n                if(ext->type & LV_CHART_TYPE_VERTICAL_LINE) lv_chart_draw_vertical_lines(chart, &adjusted_mask);\n                if(ext->type & LV_CHART_TYPE_AREA) lv_chart_draw_areas(chart, &adjusted_mask);\n        }\n\n        lv_chart_draw_axes(chart, mask);\n    }\n    return true;\n}\n\n/**\n * Signal function of the chart background\n * @param chart pointer to a chart background object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n */\nstatic lv_res_t lv_chart_signal(lv_obj_t * chart, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(chart, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    if(sign == LV_SIGNAL_CLEANUP) {\n        lv_coord_t ** datal;\n        LV_LL_READ(ext->series_ll, datal)\n        {\n            lv_mem_free(*datal);\n        }\n        lv_ll_clear(&ext->series_ll);\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_chart\";\n    } else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {\n        /*Provide extra px draw area around the chart*/\n        chart->ext_draw_pad = ext->margin;\n    }\n\n    return res;\n}\n\n/**\n * Draw the division lines on chart background\n * @param chart pointer to chart object\n * @param mask mask, inherited from the design function\n */\nstatic void lv_chart_draw_div(lv_obj_t * chart, const lv_area_t * mask)\n{\n    lv_chart_ext_t * ext     = lv_obj_get_ext_attr(chart);\n    const lv_style_t * style = lv_obj_get_style(chart);\n    lv_opa_t opa_scale       = lv_obj_get_opa_scale(chart);\n\n    uint8_t div_i;\n    uint8_t div_i_end;\n    uint8_t div_i_start;\n    lv_point_t p1;\n    lv_point_t p2;\n    lv_coord_t w     = lv_obj_get_width(chart);\n    lv_coord_t h     = lv_obj_get_height(chart);\n    lv_coord_t x_ofs = chart->coords.x1;\n    lv_coord_t y_ofs = chart->coords.y1;\n\n    if(ext->hdiv_cnt != 0) {\n        /*Draw side lines if no border*/\n        if(style->body.border.width != 0) {\n            div_i_start = 1;\n            div_i_end   = ext->hdiv_cnt;\n        } else {\n            div_i_start = 0;\n            div_i_end   = ext->hdiv_cnt + 1;\n        }\n\n        p1.x = 0 + x_ofs;\n        p2.x = w + x_ofs;\n        for(div_i = div_i_start; div_i <= div_i_end; div_i++) {\n            p1.y = (int32_t)((int32_t)(h - style->line.width) * div_i) / (ext->hdiv_cnt + 1);\n            p1.y += y_ofs;\n            p2.y = p1.y;\n            lv_draw_line(&p1, &p2, mask, style, opa_scale);\n        }\n    }\n\n    if(ext->vdiv_cnt != 0) {\n        /*Draw side lines if no border*/\n        if(style->body.border.width != 0) {\n            div_i_start = 1;\n            div_i_end   = ext->vdiv_cnt;\n        } else {\n            div_i_start = 0;\n            div_i_end   = ext->vdiv_cnt + 1;\n        }\n\n        p1.y = 0 + y_ofs;\n        p2.y = h + y_ofs;\n        for(div_i = div_i_start; div_i <= div_i_end; div_i++) {\n            p1.x = (int32_t)((int32_t)(w - style->line.width) * div_i) / (ext->vdiv_cnt + 1);\n            p1.x += x_ofs;\n            p2.x = p1.x;\n            lv_draw_line(&p1, &p2, mask, style, opa_scale);\n        }\n    }\n}\n\n/**\n * Draw the data lines as lines on a chart\n * @param obj pointer to chart object\n */\nstatic void lv_chart_draw_lines(lv_obj_t * chart, const lv_area_t * mask)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n\n    uint16_t i;\n    lv_point_t p1;\n    lv_point_t p2;\n    lv_coord_t w     = lv_obj_get_width(chart);\n    lv_coord_t h     = lv_obj_get_height(chart);\n    lv_coord_t x_ofs = chart->coords.x1;\n    lv_coord_t y_ofs = chart->coords.y1;\n    int32_t y_tmp;\n    lv_coord_t p_prev;\n    lv_coord_t p_act;\n    lv_chart_series_t * ser;\n    lv_opa_t opa_scale = lv_obj_get_opa_scale(chart);\n    lv_style_t style;\n    lv_style_copy(&style, &lv_style_plain);\n    style.line.opa   = ext->series.opa;\n    style.line.width = ext->series.width;\n\n    /*Go through all data lines*/\n    LV_LL_READ_BACK(ext->series_ll, ser)\n    {\n        style.line.color = ser->color;\n\n        lv_coord_t start_point = ext->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0;\n\n        p1.x = 0 + x_ofs;\n        p2.x = 0 + x_ofs;\n\n        p_prev = start_point;\n        y_tmp  = (int32_t)((int32_t)ser->points[p_prev] - ext->ymin) * h;\n        y_tmp  = y_tmp / (ext->ymax - ext->ymin);\n        p2.y   = h - y_tmp + y_ofs;\n\n        for(i = 1; i < ext->point_cnt; i++) {\n            p1.x = p2.x;\n            p1.y = p2.y;\n\n            p2.x = ((w * i) / (ext->point_cnt - 1)) + x_ofs;\n\n            p_act = (start_point + i) % ext->point_cnt;\n\n            y_tmp = (int32_t)((int32_t)ser->points[p_act] - ext->ymin) * h;\n            y_tmp = y_tmp / (ext->ymax - ext->ymin);\n            p2.y  = h - y_tmp + y_ofs;\n\n            if(ser->points[p_prev] != LV_CHART_POINT_DEF && ser->points[p_act] != LV_CHART_POINT_DEF)\n                lv_draw_line(&p1, &p2, mask, &style, opa_scale);\n\n            p_prev = p_act;\n        }\n    }\n}\n\n/**\n * Draw the data lines as points on a chart\n * @param chart pointer to chart object\n * @param mask mask, inherited from the design function\n */\nstatic void lv_chart_draw_points(lv_obj_t * chart, const lv_area_t * mask)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n\n    uint16_t i;\n    lv_area_t cir_a;\n    lv_coord_t w     = lv_obj_get_width(chart);\n    lv_coord_t h     = lv_obj_get_height(chart);\n    lv_coord_t x_ofs = chart->coords.x1;\n    lv_coord_t y_ofs = chart->coords.y1;\n    int32_t y_tmp;\n    lv_coord_t p_act;\n    lv_chart_series_t * ser;\n    uint8_t series_cnt = 0;\n    lv_style_t style_point;\n    lv_style_copy(&style_point, &lv_style_plain);\n\n    style_point.body.border.width = 0;\n    style_point.body.radius       = LV_RADIUS_CIRCLE;\n    style_point.body.opa          = ext->series.opa;\n    style_point.body.radius       = ext->series.width;\n\n    /*Go through all data lines*/\n\n    LV_LL_READ_BACK(ext->series_ll, ser)\n    {\n        lv_coord_t start_point = ext->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0;\n\n        style_point.body.main_color = ser->color;\n        style_point.body.grad_color = lv_color_mix(LV_COLOR_BLACK, ser->color, ext->series.dark);\n\n        for(i = 0; i < ext->point_cnt; i++) {\n            cir_a.x1 = ((w * i) / (ext->point_cnt - 1)) + x_ofs;\n            cir_a.x2 = cir_a.x1 + style_point.body.radius;\n            cir_a.x1 -= style_point.body.radius;\n\n            p_act = (start_point + i) % ext->point_cnt;\n            y_tmp = (int32_t)((int32_t)ser->points[p_act] - ext->ymin) * h;\n            y_tmp = y_tmp / (ext->ymax - ext->ymin);\n\n            cir_a.y1 = h - y_tmp + y_ofs;\n            cir_a.y2 = cir_a.y1 + style_point.body.radius;\n            cir_a.y1 -= style_point.body.radius;\n\n            if(ser->points[p_act] != LV_CHART_POINT_DEF)\n                lv_draw_rect(&cir_a, mask, &style_point, lv_obj_get_opa_scale(chart));\n        }\n        series_cnt++;\n    }\n}\n\n/**\n * Draw the data lines as columns on a chart\n * @param chart pointer to chart object\n * @param mask mask, inherited from the design function\n */\nstatic void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n\n    uint16_t i;\n    lv_area_t col_a;\n    lv_area_t col_mask;\n    bool mask_ret;\n    lv_coord_t w = lv_obj_get_width(chart);\n    lv_coord_t h = lv_obj_get_height(chart);\n    int32_t y_tmp;\n    lv_chart_series_t * ser;\n    lv_style_t rects;\n    lv_coord_t col_w = w / ((ext->series.num + 1) * ext->point_cnt); /* Suppose + 1 series as separator*/\n    lv_coord_t x_ofs = col_w / 2;                                    /*Shift with a half col.*/\n\n    lv_style_copy(&rects, &lv_style_plain);\n    rects.body.border.width = 0;\n    rects.body.radius       = 0;\n    rects.body.opa          = ext->series.opa;\n\n    col_a.y2 = chart->coords.y2;\n\n    lv_coord_t x_act;\n\n    /*Go through all points*/\n    for(i = 0; i < ext->point_cnt; i++) {\n        x_act = (int32_t)((int32_t)w * i) / ext->point_cnt;\n        x_act += chart->coords.x1 + x_ofs;\n\n        /*Draw the current point of all data line*/\n        LV_LL_READ_BACK(ext->series_ll, ser)\n        {\n            lv_coord_t start_point = ext->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0;\n\n            col_a.x1 = x_act;\n            col_a.x2 = col_a.x1 + col_w;\n            x_act += col_w;\n\n            if(col_a.x2 < mask->x1) continue;\n            if(col_a.x1 > mask->x2) break;\n\n            rects.body.main_color = ser->color;\n            rects.body.grad_color = lv_color_mix(LV_COLOR_BLACK, ser->color, ext->series.dark);\n\n            lv_coord_t p_act = (start_point + i) % ext->point_cnt;\n            y_tmp            = (int32_t)((int32_t)ser->points[p_act] - ext->ymin) * h;\n            y_tmp            = y_tmp / (ext->ymax - ext->ymin);\n            col_a.y1         = h - y_tmp + chart->coords.y1;\n\n            mask_ret = lv_area_intersect(&col_mask, mask, &col_a);\n            if(mask_ret != false && ser->points[p_act] != LV_CHART_POINT_DEF) {\n                lv_draw_rect(&chart->coords, &col_mask, &rects, lv_obj_get_opa_scale(chart));\n            }\n        }\n    }\n}\n\n/**\n * Draw the data lines as vertical lines on a chart if there is only 1px between point\n * @param obj pointer to chart object\n */\nstatic void lv_chart_draw_vertical_lines(lv_obj_t * chart, const lv_area_t * mask)\n{\n\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n    lv_coord_t w         = lv_obj_get_width(chart);\n    /*Vertical lines works only if the width == point count. Else use the normal line type*/\n    if(ext->point_cnt != w) {\n        lv_chart_draw_lines(chart, mask);\n        return;\n    }\n\n    uint16_t i;\n    lv_point_t p1;\n    lv_point_t p2;\n    lv_coord_t p_act;\n    lv_coord_t h     = lv_obj_get_height(chart);\n    lv_coord_t x_ofs = chart->coords.x1;\n    lv_coord_t y_ofs = chart->coords.y1;\n    int32_t y_tmp;\n    lv_chart_series_t * ser;\n    lv_opa_t opa_scale = lv_obj_get_opa_scale(chart);\n    lv_style_t style;\n    lv_style_copy(&style, &lv_style_plain);\n    style.line.opa   = ext->series.opa;\n    style.line.width = ext->series.width;\n\n    /*Go through all data lines*/\n    LV_LL_READ_BACK(ext->series_ll, ser)\n    {\n        lv_coord_t start_point = ext->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0;\n        style.line.color       = ser->color;\n\n        p1.x  = 0 + x_ofs;\n        p2.x  = 0 + x_ofs;\n        y_tmp = (int32_t)((int32_t)ser->points[0] - ext->ymin) * h;\n        y_tmp = y_tmp / (ext->ymax - ext->ymin);\n        p2.y  = h - y_tmp + y_ofs;\n        p1.y  = p2.y;\n\n        for(i = 0; i < ext->point_cnt; i++) {\n            p_act = (start_point + i) % ext->point_cnt;\n\n            y_tmp = (int32_t)((int32_t)ser->points[p_act] - ext->ymin) * h;\n            y_tmp = y_tmp / (ext->ymax - ext->ymin);\n            p2.y  = h - y_tmp + y_ofs;\n\n            if(p1.y == p2.y) {\n                p2.x++;\n            }\n\n            if(ser->points[p_act] != LV_CHART_POINT_DEF) {\n                lv_draw_line(&p1, &p2, mask, &style, opa_scale);\n            }\n\n            p2.x = ((w * p_act) / (ext->point_cnt - 1)) + x_ofs;\n            p1.x = p2.x;\n            p1.y = p2.y;\n        }\n    }\n}\n\n/**\n * Draw the data lines as areas on a chart\n * @param obj pointer to chart object\n */\nstatic void lv_chart_draw_areas(lv_obj_t * chart, const lv_area_t * mask)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n\n    uint16_t i;\n    lv_point_t p1;\n    lv_point_t p2;\n    lv_coord_t w     = lv_obj_get_width(chart);\n    lv_coord_t h     = lv_obj_get_height(chart);\n    lv_coord_t x_ofs = chart->coords.x1;\n    lv_coord_t y_ofs = chart->coords.y1;\n    int32_t y_tmp;\n    lv_coord_t p_prev;\n    lv_coord_t p_act;\n    lv_chart_series_t * ser;\n    lv_opa_t opa_scale = lv_obj_get_opa_scale(chart);\n    lv_style_t style;\n    lv_style_copy(&style, &lv_style_plain);\n\n    /*Go through all data lines*/\n    LV_LL_READ_BACK(ext->series_ll, ser)\n    {\n        lv_coord_t start_point = ext->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0;\n        style.body.main_color  = ser->color;\n        style.body.opa         = ext->series.opa;\n\n        p2.x = 0 + x_ofs;\n\n        p_prev = start_point;\n        y_tmp  = (int32_t)((int32_t)ser->points[p_prev] - ext->ymin) * h;\n        y_tmp  = y_tmp / (ext->ymax - ext->ymin);\n        p2.y   = h - y_tmp + y_ofs;\n\n        for(i = 1; i < ext->point_cnt; i++) {\n            p1.x = p2.x;\n            p1.y = p2.y;\n\n            p_act = (start_point + i) % ext->point_cnt;\n            p2.x  = ((w * i) / (ext->point_cnt - 1)) + x_ofs;\n\n            y_tmp = (int32_t)((int32_t)ser->points[p_act] - ext->ymin) * h;\n            y_tmp = y_tmp / (ext->ymax - ext->ymin);\n            p2.y  = h - y_tmp + y_ofs;\n\n            if(ser->points[p_prev] != LV_CHART_POINT_DEF && ser->points[p_act] != LV_CHART_POINT_DEF) {\n                lv_point_t triangle_points[3];\n                triangle_points[0]   = p1;\n                triangle_points[1]   = p2;\n                triangle_points[2].x = p1.x;\n                triangle_points[2].y = chart->coords.y2;\n                lv_draw_triangle(triangle_points, mask, &style, opa_scale);\n                triangle_points[2].x = p2.x;\n                triangle_points[0].y = chart->coords.y2;\n                lv_draw_triangle(triangle_points, mask, &style, opa_scale);\n            }\n            p_prev = p_act;\n        }\n    }\n}\n\nstatic void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n\n    if(ext->y_axis.list_of_values != NULL || ext->y_axis.num_tick_marks != 0) {\n\n        const lv_style_t * style = lv_obj_get_style(chart);\n        lv_opa_t opa_scale       = lv_obj_get_opa_scale(chart);\n\n        uint8_t i, j;\n        uint8_t list_index;\n        uint8_t num_of_labels;\n        uint8_t num_scale_ticks;\n        uint8_t major_tick_len, minor_tick_len;\n        lv_point_t p1;\n        lv_point_t p2;\n        lv_coord_t x_ofs = chart->coords.x1;\n        lv_coord_t y_ofs = chart->coords.y1;\n        lv_coord_t h     = lv_obj_get_height(chart);\n        lv_coord_t w     = lv_obj_get_width(chart);\n        char buf[LV_CHART_AXIS_TICK_LABEL_MAX_LEN + 1]; /* up to N symbols per label + null terminator */\n\n        /* calculate the size of tick marks */\n        if(ext->y_axis.major_tick_len == LV_CHART_TICK_LENGTH_AUTO)\n            major_tick_len = (int32_t)w * LV_CHART_AXIS_MAJOR_TICK_LEN_COE;\n        else\n            major_tick_len = ext->y_axis.major_tick_len;\n\n        if(ext->y_axis.minor_tick_len == LV_CHART_TICK_LENGTH_AUTO)\n            minor_tick_len = major_tick_len * LV_CHART_AXIS_MINOR_TICK_LEN_COE;\n        else\n            minor_tick_len = ext->y_axis.minor_tick_len;\n\n        /* count the '\\n'-s to determine the number of options */\n        list_index    = 0;\n        num_of_labels = 0;\n        if(ext->y_axis.list_of_values != NULL) {\n            for(j = 0; ext->y_axis.list_of_values[j] != '\\0'; j++) {\n                if(ext->y_axis.list_of_values[j] == '\\n') num_of_labels++;\n            }\n\n            num_of_labels++; /* last option in the at row*/\n        }\n\n        /* we can't have string labels without ticks step, set to 1 if not specified */\n        if(ext->y_axis.num_tick_marks == 0) ext->y_axis.num_tick_marks = 1;\n\n        /* calculate total number of ticks */\n        if(num_of_labels < 2)\n            num_scale_ticks = ext->y_axis.num_tick_marks;\n        else\n            num_scale_ticks = (ext->y_axis.num_tick_marks * (num_of_labels - 1));\n\n        for(i = 0; i < (num_scale_ticks + 1); i++) { /* one extra loop - it may not exist in the list, empty label */\n                                                     /* first point of the tick */\n            p1.x = x_ofs - 1;\n\n            /* second point of the tick */\n            if((num_of_labels != 0) && (i == 0 || i % ext->y_axis.num_tick_marks == 0))\n                p2.x = p1.x - major_tick_len; /* major tick */\n            else\n                p2.x = p1.x - minor_tick_len; /* minor tick */\n\n            /* draw a line at moving y position */\n            p2.y = p1.y =\n                y_ofs + (int32_t)((int32_t)(h - style->line.width) * i) / num_scale_ticks;\n\n            if(i != num_scale_ticks)\n                lv_draw_line(&p1, &p2, mask, style, opa_scale);\n            else if((ext->y_axis.options & LV_CHART_AXIS_DRAW_LAST_TICK) != 0)\n                lv_draw_line(&p1, &p2, mask, style, opa_scale);\n\n            /* draw values if available */\n            if(num_of_labels != 0) {\n                /* add text only to major tick */\n                if(i == 0 || i % ext->y_axis.num_tick_marks == 0) {\n                    /* search for tick string */\n                    j = 0;\n                    while(ext->y_axis.list_of_values[list_index] != '\\n' &&\n                          ext->y_axis.list_of_values[list_index] != '\\0') {\n                        /* do not overflow the buffer, but move to the end of the current label */\n                        if(j < LV_CHART_AXIS_TICK_LABEL_MAX_LEN)\n                            buf[j++] = ext->y_axis.list_of_values[list_index++];\n                        else\n                            list_index++;\n                    }\n\n                    /* this was a string, but not end of the list, so jump to the next string */\n                    if(ext->y_axis.list_of_values[list_index] == '\\n') list_index++;\n\n                    /* terminate the string */\n                    buf[j] = '\\0';\n\n                    /* reserve appropriate area */\n                    lv_point_t size;\n                    lv_txt_get_size(&size, buf, style->text.font, style->text.letter_space, style->text.line_space,\n                                    LV_COORD_MAX, LV_TXT_FLAG_CENTER);\n\n                    /* set the area at some distance of the major tick len left of the tick */\n                    lv_area_t a = {(p2.x - size.x - LV_CHART_AXIS_TO_LABEL_DISTANCE), (p2.y - size.y / 2),\n                                   (p2.x - LV_CHART_AXIS_TO_LABEL_DISTANCE), (p2.y + size.y / 2)};\n                    lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, -1, -1, NULL);\n                }\n            }\n\n        }\n    }\n}\n\nstatic void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n\n    if(ext->x_axis.list_of_values != NULL || ext->x_axis.num_tick_marks != 0) {\n\n        const lv_style_t * style = lv_obj_get_style(chart);\n        lv_opa_t opa_scale       = lv_obj_get_opa_scale(chart);\n\n        uint8_t i, j;\n        uint8_t list_index;\n        uint8_t num_of_labels;\n        uint8_t num_scale_ticks;\n        uint8_t major_tick_len, minor_tick_len;\n        lv_point_t p1;\n        lv_point_t p2;\n        lv_coord_t x_ofs = chart->coords.x1;\n        lv_coord_t y_ofs = chart->coords.y1;\n        lv_coord_t h     = lv_obj_get_height(chart);\n        lv_coord_t w     = lv_obj_get_width(chart);\n        char buf[LV_CHART_AXIS_TICK_LABEL_MAX_LEN + 1]; /* up to N symbols per label + null terminator */\n\n        /* calculate the size of tick marks */\n        if(ext->x_axis.major_tick_len == LV_CHART_TICK_LENGTH_AUTO)\n            major_tick_len = (int32_t)w * LV_CHART_AXIS_MAJOR_TICK_LEN_COE;\n        else\n            major_tick_len = ext->x_axis.major_tick_len;\n\n        if(ext->x_axis.minor_tick_len == LV_CHART_TICK_LENGTH_AUTO)\n            minor_tick_len = major_tick_len * LV_CHART_AXIS_MINOR_TICK_LEN_COE;\n        else\n            minor_tick_len = ext->x_axis.minor_tick_len;\n\n        /* count the '\\n'-s to determine the number of options */\n        list_index    = 0;\n        num_of_labels = 0;\n        if(ext->x_axis.list_of_values != NULL) {\n            for(j = 0; ext->x_axis.list_of_values[j] != '\\0'; j++) {\n                if(ext->x_axis.list_of_values[j] == '\\n') num_of_labels++;\n            }\n\n            num_of_labels++; /* last option in the at row*/\n        }\n\n        /* we can't have string labels without ticks step, set to 1 if not specified */\n        if(ext->x_axis.num_tick_marks == 0) ext->x_axis.num_tick_marks = 1;\n\n        /* calculate total number of marks */\n        if(num_of_labels < 2)\n            num_scale_ticks = ext->x_axis.num_tick_marks;\n        else\n            num_scale_ticks = (ext->x_axis.num_tick_marks * (num_of_labels - 1));\n\n        for(i = 0; i < (num_scale_ticks + 1); i++) { /* one extra loop - it may not exist in the list, empty label */\n                                                     /* first point of the tick */\n            p1.y = h + y_ofs;\n\n            /* second point of the tick */\n            if((num_of_labels != 0) && (i == 0 || i % ext->x_axis.num_tick_marks == 0))\n                p2.y = p1.y + major_tick_len; /* major tick */\n            else\n                p2.y = p1.y + minor_tick_len; /* minor tick */\n\n            /* draw a line at moving x position */\n            p2.x = p1.x = x_ofs + (int32_t)((int32_t)(w - style->line.width) * i) / num_scale_ticks;\n\n            if(i != num_scale_ticks)\n                lv_draw_line(&p1, &p2, mask, style, opa_scale);\n            else if((ext->x_axis.options & LV_CHART_AXIS_DRAW_LAST_TICK) != 0)\n                lv_draw_line(&p1, &p2, mask, style, opa_scale);\n\n            /* draw values if available */\n            if(num_of_labels != 0) {\n                /* add text only to major tick */\n                if(i == 0 || i % ext->x_axis.num_tick_marks == 0) {\n                    /* search for tick string */\n                    j = 0;\n                    while(ext->x_axis.list_of_values[list_index] != '\\n' &&\n                          ext->x_axis.list_of_values[list_index] != '\\0') {\n                        /* do not overflow the buffer, but move to the end of the current label */\n                        if(j < LV_CHART_AXIS_TICK_LABEL_MAX_LEN)\n                            buf[j++] = ext->x_axis.list_of_values[list_index++];\n                        else\n                            list_index++;\n                    }\n\n                    /* this was a string, but not end of the list, so jump to the next string */\n                    if(ext->x_axis.list_of_values[list_index] == '\\n') list_index++;\n\n                    /* terminate the string */\n                    buf[j] = '\\0';\n\n                    /* reserve appropriate area */\n                    lv_point_t size;\n                    lv_txt_get_size(&size, buf, style->text.font, style->text.letter_space, style->text.line_space,\n                                    LV_COORD_MAX, LV_TXT_FLAG_CENTER);\n\n                    /* set the area at some distance of the major tick len under of the tick */\n                    lv_area_t a = {(p2.x - size.x / 2), (p2.y + LV_CHART_AXIS_TO_LABEL_DISTANCE), (p2.x + size.x / 2),\n                                   (p2.y + size.y + LV_CHART_AXIS_TO_LABEL_DISTANCE)};\n                    lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, -1, -1, NULL);\n                }\n            }\n        }\n    }\n}\n\nstatic void lv_chart_draw_axes(lv_obj_t * chart, const lv_area_t * mask)\n{\n    lv_chart_draw_y_ticks(chart, mask);\n    lv_chart_draw_x_ticks(chart, mask);\n}\n\n/**\n * invalid area of the new line data lines on a chart\n * @param obj pointer to chart object\n */\nstatic void lv_chart_inv_lines(lv_obj_t * chart, uint16_t i)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n\n    lv_coord_t w     = lv_obj_get_width(chart);\n    lv_coord_t x_ofs = chart->coords.x1;\n\n    if(i < ext->point_cnt) {\n        lv_area_t coords;\n        lv_obj_get_coords(chart, &coords);\n        if(i < ext->point_cnt - 1) {\n            coords.x1 = ((w * i) / (ext->point_cnt - 1)) + x_ofs - ext->series.width;\n            coords.x2 = ((w * (i + 1)) / (ext->point_cnt - 1)) + x_ofs + ext->series.width;\n            lv_inv_area(lv_obj_get_disp(chart), &coords);\n        }\n\n        if(i > 0) {\n            coords.x1 = ((w * (i - 1)) / (ext->point_cnt - 1)) + x_ofs - ext->series.width;\n            coords.x2 = ((w * i) / (ext->point_cnt - 1)) + x_ofs + ext->series.width;\n            lv_inv_area(lv_obj_get_disp(chart), &coords);\n        }\n    }\n}\n\n/**\n * invalid area of the new point data lines on a chart\n * @param chart pointer to chart object\n * @param mask mask, inherited from the design function\n */\nstatic void lv_chart_inv_points(lv_obj_t * chart, uint16_t i)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n\n    lv_area_t cir_a;\n    lv_coord_t w     = lv_obj_get_width(chart);\n    lv_coord_t x_ofs = chart->coords.x1;\n\n    lv_obj_get_coords(chart, &cir_a);\n    cir_a.x1 = ((w * i) / (ext->point_cnt - 1)) + x_ofs;\n    cir_a.x2 = cir_a.x1 + ext->series.width;\n    cir_a.x1 -= ext->series.width;\n\n    lv_inv_area(lv_obj_get_disp(chart), &cir_a);\n}\n\n/**\n * invalid area of the new column data lines on a chart\n * @param chart pointer to chart object\n * @param mask mask, inherited from the design function\n */\nstatic void lv_chart_inv_cols(lv_obj_t * chart, uint16_t i)\n{\n    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);\n\n    lv_area_t col_a;\n    lv_coord_t w     = lv_obj_get_width(chart);\n    lv_coord_t col_w = w / ((ext->series.num + 1) * ext->point_cnt); /* Suppose + 1 series as separator*/\n    lv_coord_t x_ofs = col_w / 2;                                    /*Shift with a half col.*/\n\n    lv_coord_t x_act;\n\n    x_act = (int32_t)((int32_t)w * i) / ext->point_cnt;\n    x_act += chart->coords.x1 + x_ofs;\n\n    lv_obj_get_coords(chart, &col_a);\n    col_a.x1 = x_act;\n    col_a.x2 = col_a.x1 + col_w;\n\n    lv_inv_area(lv_obj_get_disp(chart), &col_a);\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_cont.c",
    "content": "/**\n * @file lv_cont.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n\n#include \"libs/lvgl/lv_objx/lv_cont.h\"\n#if LV_USE_CONT != 0\n\n#include \"utils/types.h\"\n#include <stdint.h>\n#include <string.h>\n\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_draw/lv_draw_basic.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_misc/lv_area.h\"\n#include \"libs/lvgl/lv_misc/lv_color.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic lv_res_t lv_cont_signal(lv_obj_t * cont, lv_signal_t sign, void * param);\nstatic void lv_cont_refr_layout(lv_obj_t * cont);\nstatic void lv_cont_layout_col(lv_obj_t * cont);\nstatic void lv_cont_layout_row(lv_obj_t * cont);\nstatic void lv_cont_layout_center(lv_obj_t * cont);\nstatic void lv_cont_layout_pretty(lv_obj_t * cont);\nstatic void lv_cont_layout_grid(lv_obj_t * cont);\nstatic void lv_cont_refr_autofit(lv_obj_t * cont);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a container objects\n * @param par pointer to an object, it will be the parent of the new container\n * @param copy pointer to a container object, if not NULL then the new object will be copied from it\n * @return pointer to the created container\n */\nlv_obj_t * lv_cont_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n\n    LV_LOG_TRACE(\"container create started\");\n\n    /*Create a basic object*/\n    lv_obj_t * new_cont = lv_obj_create(par, copy);\n    lv_mem_assert(new_cont);\n    if(new_cont == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_cont);\n\n    lv_obj_allocate_ext_attr(new_cont, sizeof(lv_cont_ext_t));\n    lv_cont_ext_t * ext = lv_obj_get_ext_attr(new_cont);\n    if(ext == NULL) return NULL;\n\n    lv_mem_assert(ext);\n    ext->fit_left   = LV_FIT_NONE;\n    ext->fit_right  = LV_FIT_NONE;\n    ext->fit_top    = LV_FIT_NONE;\n    ext->fit_bottom = LV_FIT_NONE;\n    ext->layout     = LV_LAYOUT_OFF;\n\n    lv_obj_set_signal_cb(new_cont, lv_cont_signal);\n\n    /*Init the new container*/\n    if(copy == NULL) {\n        /*Set the default styles if it's not screen*/\n        if(par != NULL) {\n            lv_theme_t * th = lv_theme_get_current();\n            if(th) {\n                lv_cont_set_style(new_cont, LV_CONT_STYLE_MAIN, th->style.cont);\n            } else {\n                lv_cont_set_style(new_cont, LV_CONT_STYLE_MAIN, &lv_style_pretty);\n            }\n        }\n    }\n    /*Copy an existing object*/\n    else {\n        lv_cont_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->fit_left            = copy_ext->fit_left;\n        ext->fit_right           = copy_ext->fit_right;\n        ext->fit_top             = copy_ext->fit_top;\n        ext->fit_bottom          = copy_ext->fit_bottom;\n        ext->layout              = copy_ext->layout;\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_cont);\n    }\n\n    LV_LOG_INFO(\"container created\");\n\n    return new_cont;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a layout on a container\n * @param cont pointer to a container object\n * @param layout a layout from 'lv_cont_layout_t'\n */\nvoid lv_cont_set_layout(lv_obj_t * cont, lv_layout_t layout)\n{\n    lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);\n    if(ext->layout == layout) return;\n\n    ext->layout = layout;\n\n    /*Send a signal to refresh the layout*/\n    cont->signal_cb(cont, LV_SIGNAL_CHILD_CHG, NULL);\n}\n\n/**\n * Set the fit policy in all 4 directions separately.\n * It tell how to change the container's size automatically.\n * @param cont pointer to a container object\n * @param left left fit policy from `lv_fit_t`\n * @param right right fit policy from `lv_fit_t`\n * @param top bottom fit policy from `lv_fit_t`\n * @param bottom bottom fit policy from `lv_fit_t`\n */\nvoid lv_cont_set_fit4(lv_obj_t * cont, lv_fit_t left, lv_fit_t right, lv_fit_t top, lv_fit_t bottom)\n{\n    lv_obj_invalidate(cont);\n    lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);\n    if(ext->fit_left == left && ext->fit_right == right && ext->fit_top == top && ext->fit_bottom == bottom) {\n        return;\n    }\n\n    ext->fit_left   = left;\n    ext->fit_right  = right;\n    ext->fit_top    = top;\n    ext->fit_bottom = bottom;\n\n    /*Send a signal to refresh the layout*/\n    cont->signal_cb(cont, LV_SIGNAL_CHILD_CHG, NULL);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the layout of a container\n * @param cont pointer to container object\n * @return the layout from 'lv_cont_layout_t'\n */\nlv_layout_t lv_cont_get_layout(const lv_obj_t * cont)\n{\n    lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);\n    return ext->layout;\n}\n\n/**\n * Get left fit mode of a container\n * @param cont pointer to a container object\n * @return an element of `lv_fit_t`\n */\nlv_fit_t lv_cont_get_fit_left(const lv_obj_t * cont)\n{\n    lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);\n    return ext->fit_left;\n}\n\n/**\n * Get right fit mode of a container\n * @param cont pointer to a container object\n * @return an element of `lv_fit_t`\n */\nlv_fit_t lv_cont_get_fit_right(const lv_obj_t * cont)\n{\n    lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);\n    return ext->fit_right;\n}\n\n/**\n * Get top fit mode of a container\n * @param cont pointer to a container object\n * @return an element of `lv_fit_t`\n */\nlv_fit_t lv_cont_get_fit_top(const lv_obj_t * cont)\n{\n    lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);\n    return ext->fit_top;\n}\n\n/**\n * Get bottom fit mode of a container\n * @param cont pointer to a container object\n * @return an element of `lv_fit_t`\n */\nlv_fit_t lv_cont_get_fit_bottom(const lv_obj_t * cont)\n{\n    lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);\n    return ext->fit_bottom;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Signal function of the container\n * @param cont pointer to a container object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_cont_signal(lv_obj_t * cont, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(cont, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    if(sign == LV_SIGNAL_STYLE_CHG) { /*Recalculate the padding if the style changed*/\n        lv_cont_refr_layout(cont);\n        lv_cont_refr_autofit(cont);\n    } else if(sign == LV_SIGNAL_CHILD_CHG) {\n        lv_cont_refr_layout(cont);\n        lv_cont_refr_autofit(cont);\n    } else if(sign == LV_SIGNAL_CORD_CHG) {\n        if(lv_obj_get_width(cont) != lv_area_get_width(param) || lv_obj_get_height(cont) != lv_area_get_height(param)) {\n            lv_cont_refr_layout(cont);\n            lv_cont_refr_autofit(cont);\n        }\n    } else if(sign == LV_SIGNAL_PARENT_SIZE_CHG) {\n        /*FLOOD and FILL fit needs to be refreshed if the parent size has changed*/\n        lv_cont_refr_autofit(cont);\n\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_cont\";\n    }\n\n    return res;\n}\n\n/**\n * Refresh the layout of a container\n * @param cont pointer to an object which layout should be refreshed\n */\nstatic void lv_cont_refr_layout(lv_obj_t * cont)\n{\n    lv_layout_t type = lv_cont_get_layout(cont);\n\n    /*'cont' has to be at least 1 child*/\n    if(lv_obj_get_child(cont, NULL) == NULL) return;\n\n    if(type == LV_LAYOUT_OFF) return;\n\n    if(type == LV_LAYOUT_CENTER) {\n        lv_cont_layout_center(cont);\n    } else if(type == LV_LAYOUT_COL_L || type == LV_LAYOUT_COL_M || type == LV_LAYOUT_COL_R) {\n        lv_cont_layout_col(cont);\n    } else if(type == LV_LAYOUT_ROW_T || type == LV_LAYOUT_ROW_M || type == LV_LAYOUT_ROW_B) {\n        lv_cont_layout_row(cont);\n    } else if(type == LV_LAYOUT_PRETTY) {\n        lv_cont_layout_pretty(cont);\n    } else if(type == LV_LAYOUT_GRID) {\n        lv_cont_layout_grid(cont);\n    }\n}\n\n/**\n * Handle column type layouts\n * @param cont pointer to an object which layout should be handled\n */\nstatic void lv_cont_layout_col(lv_obj_t * cont)\n{\n    lv_layout_t type = lv_cont_get_layout(cont);\n    lv_obj_t * child;\n\n    /*Adjust margin and get the alignment type*/\n    lv_align_t align;\n    const lv_style_t * style = lv_obj_get_style(cont);\n    lv_coord_t hpad_corr;\n\n    switch(type) {\n        case LV_LAYOUT_COL_L:\n            hpad_corr = style->body.padding.left;\n            align     = LV_ALIGN_IN_TOP_LEFT;\n            break;\n        case LV_LAYOUT_COL_M:\n            hpad_corr = 0;\n            align     = LV_ALIGN_IN_TOP_MID;\n            break;\n        case LV_LAYOUT_COL_R:\n            hpad_corr = -style->body.padding.right;\n            align     = LV_ALIGN_IN_TOP_RIGHT;\n            break;\n        default:\n            hpad_corr = 0;\n            align     = LV_ALIGN_IN_TOP_LEFT;\n            break;\n    }\n\n    /* Disable child change action because the children will be moved a lot\n     * an unnecessary child change signals could be sent*/\n    lv_obj_set_protect(cont, LV_PROTECT_CHILD_CHG);\n    /* Align the children */\n    lv_coord_t last_cord = style->body.padding.top;\n    LV_LL_READ_BACK(cont->child_ll, child)\n    {\n        if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;\n\n        lv_obj_align(child, cont, align, hpad_corr, last_cord);\n        last_cord += lv_obj_get_height(child) + style->body.padding.inner;\n    }\n\n    lv_obj_clear_protect(cont, LV_PROTECT_CHILD_CHG);\n}\n\n/**\n * Handle row type layouts\n * @param cont pointer to an object which layout should be handled\n */\nstatic void lv_cont_layout_row(lv_obj_t * cont)\n{\n    lv_layout_t type = lv_cont_get_layout(cont);\n    lv_obj_t * child;\n\n    /*Adjust margin and get the alignment type*/\n    lv_align_t align;\n    const lv_style_t * style = lv_obj_get_style(cont);\n    lv_coord_t vpad_corr;\n\n    switch(type) {\n        case LV_LAYOUT_ROW_T:\n            vpad_corr = style->body.padding.top;\n            align     = LV_ALIGN_IN_TOP_LEFT;\n            break;\n        case LV_LAYOUT_ROW_M:\n            vpad_corr = 0;\n            align     = LV_ALIGN_IN_LEFT_MID;\n            break;\n        case LV_LAYOUT_ROW_B:\n            vpad_corr = -style->body.padding.bottom;\n            align     = LV_ALIGN_IN_BOTTOM_LEFT;\n            break;\n        default:\n            vpad_corr = 0;\n            align     = LV_ALIGN_IN_TOP_LEFT;\n            break;\n    }\n\n    /* Disable child change action because the children will be moved a lot\n     * an unnecessary child change signals could be sent*/\n    lv_obj_set_protect(cont, LV_PROTECT_CHILD_CHG);\n\n    /* Align the children */\n    lv_coord_t last_cord = style->body.padding.left;\n    LV_LL_READ_BACK(cont->child_ll, child)\n    {\n        if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;\n\n        lv_obj_align(child, cont, align, last_cord, vpad_corr);\n        last_cord += lv_obj_get_width(child) + style->body.padding.inner;\n    }\n\n    lv_obj_clear_protect(cont, LV_PROTECT_CHILD_CHG);\n}\n\n/**\n * Handle the center layout\n * @param cont pointer to an object which layout should be handled\n */\nstatic void lv_cont_layout_center(lv_obj_t * cont)\n{\n    lv_obj_t * child;\n    const lv_style_t * style = lv_obj_get_style(cont);\n    uint32_t obj_num         = 0;\n    lv_coord_t h_tot         = 0;\n\n    LV_LL_READ(cont->child_ll, child)\n    {\n        if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;\n        h_tot += lv_obj_get_height(child) + style->body.padding.inner;\n        obj_num++;\n    }\n\n    if(obj_num == 0) return;\n\n    h_tot -= style->body.padding.inner;\n\n    /* Disable child change action because the children will be moved a lot\n     * an unnecessary child change signals could be sent*/\n    lv_obj_set_protect(cont, LV_PROTECT_CHILD_CHG);\n\n    /* Align the children */\n    lv_coord_t last_cord = -(h_tot / 2);\n    LV_LL_READ_BACK(cont->child_ll, child)\n    {\n        if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;\n\n        lv_obj_align(child, cont, LV_ALIGN_CENTER, 0, last_cord + lv_obj_get_height(child) / 2);\n        last_cord += lv_obj_get_height(child) + style->body.padding.inner;\n    }\n\n    lv_obj_clear_protect(cont, LV_PROTECT_CHILD_CHG);\n}\n\n/**\n * Handle the pretty layout. Put as many object as possible in row\n * then begin a new row\n * @param cont pointer to an object which layout should be handled\n */\nstatic void lv_cont_layout_pretty(lv_obj_t * cont)\n{\n    lv_obj_t * child_rs;  /* Row starter child */\n    lv_obj_t * child_rc;  /* Row closer child */\n    lv_obj_t * child_tmp; /* Temporary child */\n    const lv_style_t * style = lv_obj_get_style(cont);\n    lv_coord_t w_obj         = lv_obj_get_width(cont);\n    lv_coord_t act_y         = style->body.padding.top;\n    /* Disable child change action because the children will be moved a lot\n     * an unnecessary child change signals could be sent*/\n\n    child_rs = lv_ll_get_tail(&cont->child_ll); /*Set the row starter child*/\n    if(child_rs == NULL) return;                /*Return if no child*/\n\n    lv_obj_set_protect(cont, LV_PROTECT_CHILD_CHG);\n\n    child_rc = child_rs; /*Initially the the row starter and closer is the same*/\n    while(child_rs != NULL) {\n        lv_coord_t h_row = 0;\n        lv_coord_t w_row =\n            style->body.padding.left + style->body.padding.right; /*The width is at least the left+right hpad*/\n        uint32_t obj_num = 0;\n\n        /*Find the row closer object and collect some data*/\n        do {\n            if(lv_obj_get_hidden(child_rc) == false && lv_obj_is_protected(child_rc, LV_PROTECT_POS) == false) {\n                /*If this object is already not fit then break*/\n                if(w_row + lv_obj_get_width(child_rc) > w_obj) {\n                    /*Step back one child because the last already not fit, so the previous is the\n                     * closer*/\n                    if(child_rc != NULL && obj_num != 0) {\n                        child_rc = lv_ll_get_next(&cont->child_ll, child_rc);\n                    }\n                    break;\n                }\n                w_row += lv_obj_get_width(child_rc) + style->body.padding.inner; /*Add the object width + opad*/\n                h_row = LV_MATH_MAX(h_row, lv_obj_get_height(child_rc));         /*Search the highest object*/\n                obj_num++;\n                if(lv_obj_is_protected(child_rc, LV_PROTECT_FOLLOW))\n                    break; /*If can not be followed by an other object then break here*/\n            }\n            child_rc = lv_ll_get_prev(&cont->child_ll, child_rc); /*Load the next object*/\n            if(obj_num == 0)\n                child_rs = child_rc; /*If the first object was hidden (or too long) then set the\n                                        next as first */\n        } while(child_rc != NULL);\n\n        /*If the object is too long  then align it to the middle*/\n        if(obj_num == 0) {\n            if(child_rc != NULL) {\n                lv_obj_align(child_rc, cont, LV_ALIGN_IN_TOP_MID, 0, act_y);\n                h_row = lv_obj_get_height(child_rc); /*Not set previously because of the early break*/\n            }\n        }\n        /*If there is only one object in the row then align it to the middle*/\n        else if(obj_num == 1) {\n            lv_obj_align(child_rs, cont, LV_ALIGN_IN_TOP_MID, 0, act_y);\n        }\n        /*If there are two object in the row then align them proportionally*/\n        else if(obj_num == 2) {\n            lv_obj_t * obj1 = child_rs;\n            lv_obj_t * obj2 = lv_ll_get_prev(&cont->child_ll, child_rs);\n            w_row           = lv_obj_get_width(obj1) + lv_obj_get_width(obj2);\n            lv_coord_t pad  = (w_obj - w_row) / 3;\n            lv_obj_align(obj1, cont, LV_ALIGN_IN_TOP_LEFT, pad, act_y + (h_row - lv_obj_get_height(obj1)) / 2);\n            lv_obj_align(obj2, cont, LV_ALIGN_IN_TOP_RIGHT, -pad, act_y + (h_row - lv_obj_get_height(obj2)) / 2);\n        }\n        /* Align the children (from child_rs to child_rc)*/\n        else {\n            w_row -= style->body.padding.inner * obj_num;\n            lv_coord_t new_opad = (w_obj - w_row) / (obj_num - 1);\n            lv_coord_t act_x    = style->body.padding.left; /*x init*/\n            child_tmp           = child_rs;\n            while(child_tmp != NULL) {\n                if(lv_obj_get_hidden(child_tmp) == false && lv_obj_is_protected(child_tmp, LV_PROTECT_POS) == false) {\n                    lv_obj_align(child_tmp, cont, LV_ALIGN_IN_TOP_LEFT, act_x,\n                                 act_y + (h_row - lv_obj_get_height(child_tmp)) / 2);\n                    act_x += lv_obj_get_width(child_tmp) + new_opad;\n                }\n                if(child_tmp == child_rc) break;\n                child_tmp = lv_ll_get_prev(&cont->child_ll, child_tmp);\n            }\n        }\n\n        if(child_rc == NULL) break;\n        act_y += style->body.padding.inner + h_row;           /*y increment*/\n        child_rs = lv_ll_get_prev(&cont->child_ll, child_rc); /*Go to the next object*/\n        child_rc = child_rs;\n    }\n    lv_obj_clear_protect(cont, LV_PROTECT_CHILD_CHG);\n}\n\n/**\n * Handle the grid layout. Align same-sized objects in a grid\n * @param cont pointer to an object which layout should be handled\n */\nstatic void lv_cont_layout_grid(lv_obj_t * cont)\n{\n    lv_obj_t * child;\n    const lv_style_t * style = lv_obj_get_style(cont);\n    lv_coord_t w_tot         = lv_obj_get_width(cont);\n    lv_coord_t w_obj         = lv_obj_get_width(lv_obj_get_child(cont, NULL));\n    lv_coord_t w_fit         =  lv_obj_get_width_fit(cont);\n    lv_coord_t h_obj         = lv_obj_get_height(lv_obj_get_child(cont, NULL));\n    uint16_t obj_row         = (w_fit) / (w_obj + style->body.padding.inner); /*Obj. num. in a row*/\n    lv_coord_t x_ofs;\n    if(obj_row > 1) {\n        x_ofs = w_obj + (w_fit - (obj_row * w_obj)) / (obj_row - 1);\n    } else {\n        x_ofs = w_tot / 2 - w_obj / 2;\n    }\n    lv_coord_t y_ofs = h_obj + style->body.padding.inner;\n\n    /* Disable child change action because the children will be moved a lot\n     * an unnecessary child change signals could be sent*/\n    lv_obj_set_protect(cont, LV_PROTECT_CHILD_CHG);\n\n    /* Align the children */\n    lv_coord_t act_x = style->body.padding.left;\n    lv_coord_t act_y = style->body.padding.top;\n    uint16_t obj_cnt = 0;\n    LV_LL_READ_BACK(cont->child_ll, child)\n    {\n        if(lv_obj_get_hidden(child) != false || lv_obj_is_protected(child, LV_PROTECT_POS) != false) continue;\n\n        if(obj_row > 1) {\n            lv_obj_set_pos(child, act_x, act_y);\n            act_x += x_ofs;\n        } else {\n            lv_obj_set_pos(child, x_ofs, act_y);\n        }\n        obj_cnt++;\n\n        if(obj_cnt >= obj_row) {\n            obj_cnt = 0;\n            act_x   = style->body.padding.left;\n            act_y += y_ofs;\n        }\n    }\n\n    lv_obj_clear_protect(cont, LV_PROTECT_CHILD_CHG);\n}\n\n/**\n * Handle auto fit. Set the size of the object to involve all children.\n * @param cont pointer to an object which size will be modified\n */\nstatic void lv_cont_refr_autofit(lv_obj_t * cont)\n{\n    lv_cont_ext_t * ext = lv_obj_get_ext_attr(cont);\n\n    if(ext->fit_left == LV_FIT_NONE && ext->fit_right == LV_FIT_NONE && ext->fit_top == LV_FIT_NONE &&\n       ext->fit_bottom == LV_FIT_NONE) {\n        return;\n    }\n\n    lv_area_t tight_area;\n    lv_area_t ori;\n    const lv_style_t * style = lv_obj_get_style(cont);\n    lv_obj_t * child_i;\n\n    lv_obj_t * par               = lv_obj_get_parent(cont);\n    const lv_style_t * par_style = lv_obj_get_style(par);\n    lv_area_t flood_area;\n    lv_area_copy(&flood_area, &par->coords);\n    flood_area.x1 += par_style->body.padding.left;\n    flood_area.x2 -= par_style->body.padding.right;\n    flood_area.y1 += par_style->body.padding.top;\n    flood_area.y2 -= par_style->body.padding.bottom;\n\n    /*Search the side coordinates of the children*/\n    lv_obj_get_coords(cont, &ori);\n    lv_obj_get_coords(cont, &tight_area);\n\n    bool has_children = lv_ll_is_empty(&cont->child_ll) ? false : true;\n\n    if(has_children) {\n        tight_area.x1 = LV_COORD_MAX;\n        tight_area.y1 = LV_COORD_MAX;\n        tight_area.x2 = LV_COORD_MIN;\n        tight_area.y2 = LV_COORD_MIN;\n\n        LV_LL_READ(cont->child_ll, child_i)\n        {\n            if(lv_obj_get_hidden(child_i) != false) continue;\n            tight_area.x1 = LV_MATH_MIN(tight_area.x1, child_i->coords.x1);\n            tight_area.y1 = LV_MATH_MIN(tight_area.y1, child_i->coords.y1);\n            tight_area.x2 = LV_MATH_MAX(tight_area.x2, child_i->coords.x2);\n            tight_area.y2 = LV_MATH_MAX(tight_area.y2, child_i->coords.y2);\n        }\n\n        tight_area.x1 -= style->body.padding.left;\n        tight_area.x2 += style->body.padding.right;\n        tight_area.y1 -= style->body.padding.top;\n        tight_area.y2 += style->body.padding.bottom;\n    }\n\n    lv_area_t new_area;\n    lv_area_copy(&new_area, &ori);\n\n    switch(ext->fit_left) {\n        case LV_FIT_TIGHT: new_area.x1 = tight_area.x1; break;\n        case LV_FIT_FLOOD: new_area.x1 = flood_area.x1; break;\n        case LV_FIT_FILL: new_area.x1 = has_children ? LV_MATH_MIN(tight_area.x1, flood_area.x1) : flood_area.x1; break;\n        default: break;\n    }\n\n    switch(ext->fit_right) {\n        case LV_FIT_TIGHT: new_area.x2 = tight_area.x2; break;\n        case LV_FIT_FLOOD: new_area.x2 = flood_area.x2; break;\n        case LV_FIT_FILL: new_area.x2 = has_children ? LV_MATH_MAX(tight_area.x2, flood_area.x2) : flood_area.x2; break;\n        default: break;\n    }\n\n    switch(ext->fit_top) {\n        case LV_FIT_TIGHT: new_area.y1 = tight_area.y1; break;\n        case LV_FIT_FLOOD: new_area.y1 = flood_area.y1; break;\n        case LV_FIT_FILL: new_area.y1 = has_children ? LV_MATH_MIN(tight_area.y1, flood_area.y1) : flood_area.y1; break;\n        default: break;\n    }\n\n    switch(ext->fit_bottom) {\n        case LV_FIT_TIGHT: new_area.y2 = tight_area.y2; break;\n        case LV_FIT_FLOOD: new_area.y2 = flood_area.y2; break;\n        case LV_FIT_FILL: new_area.y2 = has_children ? LV_MATH_MAX(tight_area.y2, flood_area.y2) : flood_area.y2; break;\n        default: break;\n    }\n\n    /*Do nothing if the coordinates are not changed*/\n    if(cont->coords.x1 != new_area.x1 || cont->coords.y1 != new_area.y1 || cont->coords.x2 != new_area.x2 ||\n       cont->coords.y2 != new_area.y2) {\n\n        lv_obj_invalidate(cont);\n        lv_area_copy(&cont->coords, &new_area);\n        lv_obj_invalidate(cont);\n\n        /*Notify the object about its new coordinates*/\n        cont->signal_cb(cont, LV_SIGNAL_CORD_CHG, &ori);\n\n        /*Inform the parent about the new coordinates*/\n        par->signal_cb(par, LV_SIGNAL_CHILD_CHG, cont);\n\n        if(lv_obj_get_auto_realign(cont)) {\n            lv_obj_realign(cont);\n        }\n\n        /*Tell the children the parent's size has changed*/\n        LV_LL_READ(cont->child_ll, child_i)\n        {\n            child_i->signal_cb(child_i, LV_SIGNAL_PARENT_SIZE_CHG, NULL);\n        }\n    }\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_ddlist.c",
    "content": "/**\n * @file lv_ddlist.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_ddlist.h\"\n#if LV_USE_DDLIST != 0\n\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_core/lv_group.h\"\n#include \"libs/lvgl/lv_core/lv_indev.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_font/lv_symbol_def.h\"\n#include \"libs/lvgl/lv_misc/lv_anim.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n#include <string.h>\n\n/*********************\n *      DEFINES\n *********************/\n#if LV_USE_ANIMATION == 0\n#undef LV_DDLIST_DEF_ANIM_TIME\n#define LV_DDLIST_DEF_ANIM_TIME 0 /*No animation*/\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * param);\nstatic lv_res_t lv_ddlist_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param);\nstatic lv_res_t release_handler(lv_obj_t * ddlist);\nstatic void lv_ddlist_refr_size(lv_obj_t * ddlist, lv_anim_enable_t anim);\nstatic void lv_ddlist_pos_current_option(lv_obj_t * ddlist);\nstatic void lv_ddlist_refr_width(lv_obj_t * ddlist);\n#if LV_USE_ANIMATION\nstatic void lv_ddlist_anim_ready_cb(lv_anim_t * a);\nstatic void lv_ddlist_anim_finish(lv_obj_t * ddlist);\nstatic void lv_ddlist_adjust_height(lv_obj_t * ddlist, lv_anim_value_t height);\n#endif\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\nstatic lv_signal_cb_t ancestor_scrl_signal;\nstatic lv_design_cb_t ancestor_design;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a drop down list objects\n * @param par pointer to an object, it will be the parent of the new drop down list\n * @param copy pointer to a drop down list object, if not NULL then the new object will be copied\n * from it\n * @return pointer to the created drop down list\n */\nlv_obj_t * lv_ddlist_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"drop down list create started\");\n\n    /*Create the ancestor drop down list*/\n    lv_obj_t * new_ddlist = lv_page_create(par, copy);\n    lv_mem_assert(new_ddlist);\n    if(new_ddlist == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_ddlist);\n    if(ancestor_scrl_signal == NULL) ancestor_scrl_signal = lv_obj_get_signal_cb(lv_page_get_scrl(new_ddlist));\n    if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_ddlist);\n\n    /*Allocate the drop down list type specific extended data*/\n    lv_ddlist_ext_t * ext = lv_obj_allocate_ext_attr(new_ddlist, sizeof(lv_ddlist_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    /*Initialize the allocated 'ext' */\n    ext->label          = NULL;\n    ext->opened         = 0;\n    ext->fix_height     = 0;\n    ext->sel_opt_id     = 0;\n    ext->sel_opt_id_ori = 0;\n    ext->option_cnt     = 0;\n    ext->sel_style      = &lv_style_plain_color;\n    ext->draw_arrow     = 0; /*Do not draw arrow by default*/\n    ext->stay_open      = 0;\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_cb(new_ddlist, lv_ddlist_signal);\n    lv_obj_set_signal_cb(lv_page_get_scrl(new_ddlist), lv_ddlist_scrl_signal);\n    lv_obj_set_design_cb(new_ddlist, lv_ddlist_design);\n\n    /*Init the new drop down list drop down list*/\n    if(copy == NULL) {\n        lv_page_set_anim_time(new_ddlist, LV_DDLIST_DEF_ANIM_TIME);\n\n        lv_obj_t * scrl = lv_page_get_scrl(new_ddlist);\n        lv_obj_set_drag(scrl, false);\n        lv_page_set_scrl_fit2(new_ddlist, LV_FIT_FILL, LV_FIT_TIGHT);\n\n        ext->label = lv_label_create(new_ddlist, NULL);\n        lv_cont_set_fit2(new_ddlist, LV_FIT_TIGHT, LV_FIT_NONE);\n        lv_page_set_sb_mode(new_ddlist, LV_SB_MODE_HIDE);\n        lv_page_set_style(new_ddlist, LV_PAGE_STYLE_SCRL, &lv_style_transp_tight);\n\n        lv_ddlist_set_options(new_ddlist, \"Option 1\\nOption 2\\nOption 3\");\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_ddlist_set_style(new_ddlist, LV_DDLIST_STYLE_BG, th->style.ddlist.bg);\n            lv_ddlist_set_style(new_ddlist, LV_DDLIST_STYLE_SEL, th->style.ddlist.sel);\n            lv_ddlist_set_style(new_ddlist, LV_DDLIST_STYLE_SB, th->style.ddlist.sb);\n        } else {\n            lv_ddlist_set_style(new_ddlist, LV_DDLIST_STYLE_BG, &lv_style_pretty);\n            lv_ddlist_set_style(new_ddlist, LV_DDLIST_STYLE_SEL, &lv_style_plain_color);\n            lv_ddlist_set_style(new_ddlist, LV_DDLIST_STYLE_SB, &lv_style_pretty_color);\n        }\n    }\n    /*Copy an existing drop down list*/\n    else {\n        lv_ddlist_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->label                 = lv_label_create(new_ddlist, copy_ext->label);\n        lv_label_set_text(ext->label, lv_label_get_text(copy_ext->label));\n        ext->sel_opt_id     = copy_ext->sel_opt_id;\n        ext->sel_opt_id_ori = copy_ext->sel_opt_id;\n        ext->fix_height     = copy_ext->fix_height;\n        ext->option_cnt     = copy_ext->option_cnt;\n        ext->sel_style      = copy_ext->sel_style;\n        ext->draw_arrow     = copy_ext->draw_arrow;\n        ext->stay_open      = copy_ext->stay_open;\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_ddlist);\n    }\n\n    LV_LOG_INFO(\"drop down list created\");\n\n    return new_ddlist;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the options in a drop down list from a string\n * @param ddlist pointer to drop down list object\n * @param options a string with '\\n' separated options. E.g. \"One\\nTwo\\nThree\"\n */\nvoid lv_ddlist_set_options(lv_obj_t * ddlist, const char * options)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n\n    /*Count the '\\n'-s to determine the number of options*/\n    ext->option_cnt = 0;\n    uint16_t i;\n    for(i = 0; options[i] != '\\0'; i++) {\n        if(options[i] == '\\n') ext->option_cnt++;\n    }\n    ext->option_cnt++; /*Last option has no `\\n`*/\n    ext->sel_opt_id     = 0;\n    ext->sel_opt_id_ori = 0;\n\n    lv_label_set_text(ext->label, options);\n\n    lv_ddlist_refr_width(ddlist);\n\n    switch(lv_label_get_align(ext->label)) {\n        case LV_LABEL_ALIGN_LEFT: lv_obj_align(ext->label, NULL, LV_ALIGN_IN_LEFT_MID, 0, 0); break;\n        case LV_LABEL_ALIGN_CENTER: lv_obj_align(ext->label, NULL, LV_ALIGN_CENTER, 0, 0); break;\n        case LV_LABEL_ALIGN_RIGHT: lv_obj_align(ext->label, NULL, LV_ALIGN_IN_RIGHT_MID, 0, 0); break;\n    }\n\n    lv_ddlist_refr_size(ddlist, false);\n}\n\n/**\n * Set the selected option\n * @param ddlist pointer to drop down list object\n * @param sel_opt id of the selected option (0 ... number of option - 1);\n */\nvoid lv_ddlist_set_selected(lv_obj_t * ddlist, uint16_t sel_opt)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n    if(ext->sel_opt_id == sel_opt) return;\n\n    ext->sel_opt_id     = sel_opt < ext->option_cnt ? sel_opt : ext->option_cnt - 1;\n    ext->sel_opt_id_ori = ext->sel_opt_id;\n    /*Move the list to show the current option*/\n    if(ext->opened == 0) {\n        lv_ddlist_pos_current_option(ddlist);\n    } else {\n        lv_obj_invalidate(ddlist);\n    }\n}\n\n/**\n * Set a fix height for the drop down list\n * If 0 then the opened ddlist will be auto. sized else the set height will be applied.\n * @param ddlist pointer to a drop down list\n * @param h the height when the list is opened (0: auto size)\n */\nvoid lv_ddlist_set_fix_height(lv_obj_t * ddlist, lv_coord_t h)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n    if(ext->fix_height == h) return;\n\n    ext->fix_height = h;\n\n    lv_ddlist_refr_size(ddlist, false);\n}\n\n/**\n * Set a fix width for the drop down list\n * @param ddlist pointer to a drop down list\n * @param w the width when the list is opened (0: auto size)\n */\nvoid lv_ddlist_set_fix_width(lv_obj_t * ddlist, lv_coord_t w)\n{\n    if(w == 0) {\n        lv_cont_set_fit2(ddlist, LV_FIT_TIGHT, lv_cont_get_fit_bottom(ddlist));\n    } else {\n        lv_cont_set_fit2(ddlist, LV_FIT_NONE, lv_cont_get_fit_bottom(ddlist));\n        lv_obj_set_width(ddlist, w);\n    }\n\n    lv_ddlist_refr_size(ddlist, false);\n}\n\n/**\n * Set arrow draw in a drop down list\n * @param ddlist pointer to drop down list object\n * @param en enable/disable a arrow draw. E.g. \"true\" for draw.\n */\nvoid lv_ddlist_set_draw_arrow(lv_obj_t * ddlist, bool en)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n\n    /*Set the flag*/\n    ext->draw_arrow = en ? 1 : 0;\n}\n\n/**\n * Leave the list opened when a new value is selected\n * @param ddlist pointer to drop down list object\n * @param en enable/disable \"stay open\" feature\n */\nvoid lv_ddlist_set_stay_open(lv_obj_t * ddlist, bool en)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n\n    /*Set the flag*/\n    ext->stay_open = en ? 1 : 0;\n}\n\n/**\n * Set a style of a drop down list\n * @param ddlist pointer to a drop down list object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_ddlist_set_style(lv_obj_t * ddlist, lv_ddlist_style_t type, const lv_style_t * style)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n\n    switch(type) {\n        case LV_DDLIST_STYLE_BG:\n            lv_page_set_style(ddlist, LV_PAGE_STYLE_BG, style);\n            lv_ddlist_refr_width(ddlist);\n            break;\n        case LV_DDLIST_STYLE_SB: lv_page_set_style(ddlist, LV_PAGE_STYLE_SB, style); break;\n        case LV_DDLIST_STYLE_SEL:\n            ext->sel_style  = style;\n            lv_obj_t * scrl = lv_page_get_scrl(ddlist);\n            lv_obj_refresh_ext_draw_pad(scrl); /*Because of the wider selected rectangle*/\n            break;\n    }\n}\n\nvoid lv_ddlist_set_align(lv_obj_t * ddlist, lv_label_align_t align)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n\n    lv_label_set_align(ext->label, align);\n    switch(align) {\n        case LV_LABEL_ALIGN_LEFT: lv_obj_align(ext->label, NULL, LV_ALIGN_IN_LEFT_MID, 0, 0); break;\n        case LV_LABEL_ALIGN_CENTER: lv_obj_align(ext->label, NULL, LV_ALIGN_CENTER, 0, 0); break;\n        case LV_LABEL_ALIGN_RIGHT: lv_obj_align(ext->label, NULL, LV_ALIGN_IN_RIGHT_MID, 0, 0); break;\n    }\n}\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the options of a drop down list\n * @param ddlist pointer to drop down list object\n * @return the options separated by '\\n'-s (E.g. \"Option1\\nOption2\\nOption3\")\n */\nconst char * lv_ddlist_get_options(const lv_obj_t * ddlist)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n    return lv_label_get_text(ext->label);\n}\n\n/**\n * Get the selected option\n * @param ddlist pointer to drop down list object\n * @return id of the selected option (0 ... number of option - 1);\n */\nuint16_t lv_ddlist_get_selected(const lv_obj_t * ddlist)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n\n    return ext->sel_opt_id;\n}\n\n/**\n * Get the current selected option as a string\n * @param ddlist pointer to ddlist object\n * @param buf pointer to an array to store the string\n * @param buf_size size of `buf` in bytes. 0: to ignore it.\n */\nvoid lv_ddlist_get_selected_str(const lv_obj_t * ddlist, char * buf, uint16_t buf_size)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n\n    uint16_t i;\n    uint16_t line        = 0;\n    const char * opt_txt = lv_label_get_text(ext->label);\n    uint16_t txt_len     = strlen(opt_txt);\n\n    for(i = 0; i < txt_len && line != ext->sel_opt_id; i++) {\n        if(opt_txt[i] == '\\n') line++;\n    }\n\n    uint16_t c;\n    for(c = 0; opt_txt[i] != '\\n' && i < txt_len; c++, i++) {\n        if(buf_size && c >= buf_size - 1) {\n            LV_LOG_WARN(\"lv_ddlist_get_selected_str: the buffer was too small\")\n            break;\n        }\n        buf[c] = opt_txt[i];\n    }\n\n    buf[c] = '\\0';\n}\n\n/**\n * Get the fix height value.\n * @param ddlist pointer to a drop down list object\n * @return the height if the ddlist is opened (0: auto size)\n */\nlv_coord_t lv_ddlist_get_fix_height(const lv_obj_t * ddlist)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n    return ext->fix_height;\n}\n\n/**\n * Get arrow draw in a drop down list\n * @param ddlist pointer to drop down list object\n */\nbool lv_ddlist_get_draw_arrow(lv_obj_t * ddlist)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n\n    return ext->draw_arrow ? true : false;\n}\n\n/**\n * Get whether the drop down list stay open after selecting a  value or not\n * @param ddlist pointer to drop down list object\n */\nbool lv_ddlist_get_stay_open(lv_obj_t * ddlist)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n\n    return ext->stay_open ? true : false;\n}\n\n/**\n * Get a style of a drop down list\n * @param ddlist pointer to a drop down list object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_ddlist_get_style(const lv_obj_t * ddlist, lv_ddlist_style_t type)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n\n    switch(type) {\n        case LV_DDLIST_STYLE_BG: return lv_page_get_style(ddlist, LV_PAGE_STYLE_BG);\n        case LV_DDLIST_STYLE_SB: return lv_page_get_style(ddlist, LV_PAGE_STYLE_SB);\n        case LV_DDLIST_STYLE_SEL: return ext->sel_style;\n        default: return NULL;\n    }\n\n    /*To avoid warning*/\n    return NULL;\n}\n\nlv_label_align_t lv_ddlist_get_align(const lv_obj_t * ddlist)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n\n    return lv_label_get_align(ext->label);\n}\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Open the drop down list with or without animation\n * @param ddlist pointer to drop down list object\n * @param anim_en LV_ANIM_EN: use animation; LV_ANIM_OFF: not use animations\n */\nvoid lv_ddlist_open(lv_obj_t * ddlist, lv_anim_enable_t anim)\n{\n#if LV_USE_ANIMATION == 0\n    anim = false;\n#endif\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n    ext->opened           = 1;\n    lv_obj_set_drag(lv_page_get_scrl(ddlist), true);\n    lv_ddlist_refr_size(ddlist, anim);\n}\n\n/**\n * Close (Collapse) the drop down list\n * @param ddlist pointer to drop down list object\n * @param anim_en LV_ANIM_ON: use animation; LV_ANIM_OFF: not use animations\n */\nvoid lv_ddlist_close(lv_obj_t * ddlist, lv_anim_enable_t anim)\n{\n#if LV_USE_ANIMATION == 0\n    anim = false;\n#endif\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n    ext->opened           = 0;\n    lv_obj_set_drag(lv_page_get_scrl(ddlist), false);\n    lv_ddlist_refr_size(ddlist, anim);\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Get the text alignment flag for a drop down list.\n * @param ddlist drop down list\n * @return text alignment flag\n */\nstatic lv_txt_flag_t lv_ddlist_get_txt_flag(const lv_obj_t * ddlist)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n\n    /*The label might be already deleted so just return with some value*/\n    if(!ext->label) return LV_TXT_FLAG_CENTER;\n\n    lv_label_align_t align = lv_label_get_align(ext->label);\n\n    switch(align) {\n        default:\n        case LV_LABEL_ALIGN_LEFT: return LV_TXT_FLAG_NONE;\n        case LV_LABEL_ALIGN_CENTER: return LV_TXT_FLAG_CENTER;\n        case LV_LABEL_ALIGN_RIGHT: return LV_TXT_FLAG_RIGHT;\n    }\n}\n\n/**\n * Handle the drawing related tasks of the drop down lists\n * @param ddlist pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    /*Return false if the object is not covers the mask_p area*/\n    if(mode == LV_DESIGN_COVER_CHK) {\n        return ancestor_design(ddlist, mask, mode);\n    }\n    /*Draw the object*/\n    else if(mode == LV_DESIGN_DRAW_MAIN) {\n        ancestor_design(ddlist, mask, mode);\n\n        lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n        lv_opa_t opa_scale    = lv_obj_get_opa_scale(ddlist);\n        /*If the list is opened draw a rectangle under the selected item*/\n        if(ext->opened != 0 || ext->force_sel) {\n            const lv_style_t * style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);\n            const lv_font_t * font   = style->text.font;\n            lv_coord_t font_h        = lv_font_get_line_height(font);\n\n            /*Draw the selected*/\n            lv_area_t rect_area;\n            rect_area.y1 = ext->label->coords.y1;\n            rect_area.y1 += ext->sel_opt_id * (font_h + style->text.line_space);\n            rect_area.y1 -= style->text.line_space / 2;\n\n            rect_area.y2 = rect_area.y1 + font_h + style->text.line_space - 1;\n            rect_area.x1 = ddlist->coords.x1;\n            rect_area.x2 = ddlist->coords.x2;\n\n            lv_draw_rect(&rect_area, mask, ext->sel_style, opa_scale);\n        }\n    }\n    /*Post draw when the children are drawn*/\n    else if(mode == LV_DESIGN_DRAW_POST) {\n        /*Redraw the text on the selected area with a different color*/\n        lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n        lv_opa_t opa_scale    = lv_obj_get_opa_scale(ddlist);\n\n        /*Redraw only in opened state*/\n        if(ext->opened || ext->force_sel) {\n            const lv_style_t * style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);\n            const lv_font_t * font   = style->text.font;\n            lv_coord_t font_h        = lv_font_get_line_height(font);\n\n            lv_area_t area_sel;\n            area_sel.y1 = ext->label->coords.y1;\n            area_sel.y1 += ext->sel_opt_id * (font_h + style->text.line_space);\n            area_sel.y1 -= style->text.line_space / 2;\n\n            area_sel.y2 = area_sel.y1 + font_h + style->text.line_space - 1;\n            area_sel.x1 = ddlist->coords.x1;\n            area_sel.x2 = ddlist->coords.x2;\n            lv_area_t mask_sel;\n            bool area_ok;\n            area_ok = lv_area_intersect(&mask_sel, mask, &area_sel);\n            if(area_ok) {\n                const lv_style_t * sel_style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_SEL);\n                lv_style_t new_style;\n                lv_style_copy(&new_style, style);\n                new_style.text.color = sel_style->text.color;\n                new_style.text.opa   = sel_style->text.opa;\n                lv_txt_flag_t flag   = lv_ddlist_get_txt_flag(ddlist);\n                lv_draw_label(&ext->label->coords, &mask_sel, &new_style, opa_scale, lv_label_get_text(ext->label),\n                              flag, NULL, -1, -1, NULL);\n            }\n        }\n\n        /*Add a down symbol in ddlist when closed*/\n        else {\n            /*Draw a arrow in ddlist if enabled*/\n            if(ext->draw_arrow) {\n                const lv_style_t * style     = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);\n                const lv_font_t * font       = style->text.font;\n                const lv_style_t * sel_style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);\n                lv_coord_t font_h            = lv_font_get_line_height(font);\n                lv_style_t new_style;\n                lv_style_copy(&new_style, style);\n                new_style.text.color = sel_style->text.color;\n                new_style.text.opa   = sel_style->text.opa;\n                lv_area_t area_arrow;\n                area_arrow.x2 = ddlist->coords.x2 - style->body.padding.right;\n                area_arrow.x1 = area_arrow.x2 -\n                                lv_txt_get_width(LV_SYMBOL_DOWN, strlen(LV_SYMBOL_DOWN), sel_style->text.font, 0, 0);\n\n                area_arrow.y1 = ddlist->coords.y1 + style->text.line_space;\n                area_arrow.y2 = area_arrow.y1 + font_h;\n\n                lv_area_t mask_arrow;\n                bool area_ok;\n                area_ok = lv_area_intersect(&mask_arrow, mask, &area_arrow);\n                if(area_ok) {\n                    lv_draw_label(&area_arrow, &mask_arrow, &new_style, opa_scale, LV_SYMBOL_DOWN, LV_TXT_FLAG_NONE,\n                                  NULL, -1, -1, NULL); /*Use a down arrow in ddlist, you can replace it with your\n                                                    custom symbol*/\n                }\n            }\n        }\n        /*Draw the scrollbar in the ancestor page design function*/\n        ancestor_design(ddlist, mask, mode);\n    }\n\n    return true;\n}\n\n/**\n * Signal function of the drop down list\n * @param ddlist pointer to a drop down list object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n    /* Include the ancient signal function */\n    res = ancestor_signal(ddlist, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n\n    if(sign == LV_SIGNAL_STYLE_CHG) {\n        lv_ddlist_refr_size(ddlist, 0);\n    } else if(sign == LV_SIGNAL_CLEANUP) {\n        ext->label = NULL;\n    } else if(sign == LV_SIGNAL_FOCUS) {\n#if LV_USE_GROUP\n        lv_group_t * g             = lv_obj_get_group(ddlist);\n        bool editing               = lv_group_get_editing(g);\n        lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());\n\n        /*Encoders need special handling*/\n        if(indev_type == LV_INDEV_TYPE_ENCODER) {\n            /*Open the list if editing*/\n            if(editing) {\n                ext->opened         = true;\n                ext->sel_opt_id_ori = ext->sel_opt_id;\n                lv_ddlist_refr_size(ddlist, true);\n            }\n            /*Close the lift if navigating*/\n            else {\n                ext->opened     = false;\n                ext->sel_opt_id = ext->sel_opt_id_ori;\n                lv_ddlist_refr_size(ddlist, true);\n            }\n        } else {\n            /*Open the list if closed*/\n            if(!ext->opened) {\n                ext->opened         = true;\n                ext->sel_opt_id_ori = ext->sel_opt_id; /*Save the current value. Used to revert this\n                                                          state if ENER wont't be pressed*/\n                lv_ddlist_refr_size(ddlist, true);\n            }\n        }\n#endif\n    } else if(sign == LV_SIGNAL_RELEASED) {\n        release_handler(ddlist);\n    } else if(sign == LV_SIGNAL_DEFOCUS) {\n        if(ext->opened) {\n            ext->opened     = false;\n            ext->sel_opt_id = ext->sel_opt_id_ori;\n            lv_ddlist_refr_size(ddlist, true);\n        }\n    } else if(sign == LV_SIGNAL_CONTROL) {\n        char c = *((char *)param);\n        if(c == LV_KEY_RIGHT || c == LV_KEY_DOWN) {\n            if(!ext->opened) {\n                ext->opened = 1;\n                lv_ddlist_refr_size(ddlist, true);\n            }\n\n            if(ext->sel_opt_id + 1 < ext->option_cnt) {\n                ext->sel_opt_id++;\n                lv_ddlist_pos_current_option(ddlist);\n                lv_obj_invalidate(ddlist);\n            }\n        } else if(c == LV_KEY_LEFT || c == LV_KEY_UP) {\n            if(!ext->opened) {\n                ext->opened = 1;\n                lv_ddlist_refr_size(ddlist, true);\n            }\n            if(ext->sel_opt_id > 0) {\n                ext->sel_opt_id--;\n                lv_ddlist_pos_current_option(ddlist);\n                lv_obj_invalidate(ddlist);\n            }\n        } else if(c == LV_KEY_ESC) {\n            if(ext->opened) {\n                ext->opened     = 0;\n                ext->sel_opt_id = ext->sel_opt_id_ori;\n                lv_ddlist_refr_size(ddlist, true);\n            }\n        }\n    } else if(sign == LV_SIGNAL_GET_EDITABLE) {\n        bool * editable = (bool *)param;\n        *editable       = true;\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_ddlist\";\n    }\n\n    return res;\n}\n\n/**\n * Signal function of the drop down list's scrollable part\n * @param scrl pointer to a drop down list's scrollable part\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_ddlist_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_scrl_signal(scrl, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_obj_t * ddlist = lv_obj_get_parent(scrl);\n\n    if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {\n        /*TODO review this*/\n        /* Because of the wider selected rectangle ext. size\n         * In this way by dragging the scrollable part the wider rectangle area can be redrawn too*/\n        const lv_style_t * style = lv_ddlist_get_style(ddlist, LV_DDLIST_STYLE_BG);\n        lv_coord_t hpad          = LV_MATH_MAX(style->body.padding.left, style->body.padding.right);\n        if(scrl->ext_draw_pad < hpad) scrl->ext_draw_pad = hpad;\n    } else if(sign == LV_SIGNAL_RELEASED) {\n        if(lv_indev_is_dragging(lv_indev_get_act()) == false) {\n            release_handler(ddlist);\n        }\n    } else if(sign == LV_SIGNAL_CLEANUP) {\n        lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n        ext->label            = NULL; /*The label is already deleted*/\n    }\n\n    return res;\n}\n\n/**\n * Called when a drop down list is released to open it or set new option\n * @param ddlist pointer to a drop down list object\n * @return LV_ACTION_RES_INV if the ddlist it deleted in the user callback else LV_ACTION_RES_OK\n */\nstatic lv_res_t release_handler(lv_obj_t * ddlist)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n\n    if(ext->opened == 0) { /*Open the list*/\n        ext->opened = 1;\n        lv_obj_set_drag(lv_page_get_scrl(ddlist), true);\n        lv_ddlist_refr_size(ddlist, true);\n    } else {\n\n        lv_indev_t * indev = lv_indev_get_act();\n#if LV_USE_GROUP\n        /*Leave edit mode once a new item is selected*/\n        if(lv_indev_get_type(indev) == LV_INDEV_TYPE_ENCODER) {\n            ext->sel_opt_id_ori = ext->sel_opt_id;\n            lv_group_t * g      = lv_obj_get_group(ddlist);\n            if(lv_group_get_editing(g)) {\n                lv_group_set_editing(g, false);\n            }\n        }\n#endif\n\n        /*Search the clicked option (For KEYPAD and ENCODER the new value should be already set)*/\n        if(lv_indev_get_type(indev) == LV_INDEV_TYPE_POINTER || lv_indev_get_type(indev) == LV_INDEV_TYPE_BUTTON) {\n            lv_point_t p;\n            lv_indev_get_point(indev, &p);\n            p.y -= ext->label->coords.y1;\n            p.x -= ext->label->coords.x1;\n            uint16_t letter_i;\n            letter_i = lv_label_get_letter_on(ext->label, &p);\n\n            uint16_t new_opt  = 0;\n            const char * txt  = lv_label_get_text(ext->label);\n            uint32_t i        = 0;\n            uint32_t line_cnt = 0;\n            uint32_t letter;\n            for(line_cnt = 0; line_cnt < letter_i; line_cnt++) {\n                letter = lv_txt_encoded_next(txt, &i);\n                /*Count he lines to reach the clicked letter. But ignore the last '\\n' because it\n                 * still belongs to the clicked line*/\n                if(letter == '\\n' && i != letter_i) new_opt++;\n            }\n\n            ext->sel_opt_id     = new_opt;\n            ext->sel_opt_id_ori = ext->sel_opt_id;\n        }\n\n        uint32_t id  = ext->sel_opt_id; /*Just to use uint32_t in event data*/\n        lv_res_t res = lv_event_send(ddlist, LV_EVENT_VALUE_CHANGED, &id);\n        if(res != LV_RES_OK) return res;\n\n        if(ext->stay_open == 0) {\n            ext->opened = 0;\n            lv_obj_set_drag(lv_page_get_scrl(ddlist), false);\n            lv_ddlist_refr_size(ddlist, true);\n        } else {\n            lv_obj_invalidate(ddlist);\n        }\n    }\n\n    return LV_RES_OK;\n}\n\n/**\n * Refresh the size of drop down list according to its status (open or closed)\n * @param ddlist pointer to a drop down list object\n * @param anim Change the size (open/close) with or without animation (true/false)\n */\nstatic void lv_ddlist_refr_size(lv_obj_t * ddlist, lv_anim_enable_t anim)\n{\n#if LV_USE_ANIMATION == 0\n    anim = false;\n#endif\n    lv_ddlist_ext_t * ext    = lv_obj_get_ext_attr(ddlist);\n    const lv_style_t * style = lv_obj_get_style(ddlist);\n    lv_coord_t new_height;\n\n    /*Open the list*/\n    if(ext->opened) {\n        if(ext->fix_height == 0) {\n            new_height =\n                lv_obj_get_height(lv_page_get_scrl(ddlist)) + style->body.padding.top + style->body.padding.bottom;\n        } else {\n            new_height = ext->fix_height;\n        }\n\n    }\n    /*Close the list*/\n    else {\n        const lv_font_t * font         = style->text.font;\n        const lv_style_t * label_style = lv_obj_get_style(ext->label);\n        lv_coord_t font_h              = lv_font_get_line_height(font);\n        new_height                     = font_h + 2 * label_style->text.line_space;\n\n        lv_page_set_sb_mode(ddlist, LV_SB_MODE_HIDE);\n    }\n\n    if(anim == LV_ANIM_OFF) {\n        lv_obj_set_height(ddlist, new_height);\n        lv_ddlist_pos_current_option(ddlist);\n        if(ext->opened) lv_page_set_sb_mode(ddlist, LV_SB_MODE_UNHIDE);\n#if LV_USE_ANIMATION\n        lv_anim_del(ddlist, (lv_anim_exec_xcb_t)lv_ddlist_adjust_height); /*If an animation is in progress then\n                                                                 it will overwrite this changes*/\n\n        /*Force animation complete to fix highlight selection*/\n        lv_ddlist_anim_finish(ddlist);\n    } else {\n        /*Run the animation only if the the size will be different*/\n        if(lv_obj_get_height(ddlist) != new_height) {\n            lv_anim_t a;\n            a.var            = ddlist;\n            a.start          = lv_obj_get_height(ddlist);\n            a.end            = new_height;\n            a.exec_cb        = (lv_anim_exec_xcb_t)lv_ddlist_adjust_height;\n            a.path_cb        = lv_anim_path_linear;\n            a.ready_cb       = lv_ddlist_anim_ready_cb;\n            a.act_time       = 0;\n            a.time           = lv_ddlist_get_anim_time(ddlist);\n            a.playback       = 0;\n            a.playback_pause = 0;\n            a.repeat         = 0;\n            a.repeat_pause   = 0;\n\n            ext->force_sel = 1; /*Keep the list item selected*/\n            lv_anim_create(&a);\n        }\n#endif\n    }\n}\n\n#if LV_USE_ANIMATION\n/**\n * Position the list and remove the selection highlight if it's closed.\n * Called at end of list animation.\n * @param a pointer to the animation\n */\nstatic void lv_ddlist_anim_ready_cb(lv_anim_t * a)\n{\n    lv_obj_t * ddlist = a->var;\n    lv_ddlist_anim_finish(ddlist);\n}\n\n/**\n * Clean up after the open animation\n * @param ddlist\n */\nstatic void lv_ddlist_anim_finish(lv_obj_t * ddlist)\n{\n    lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);\n\n    lv_ddlist_pos_current_option(ddlist);\n    ext->force_sel = 0; /*Turn off drawing of selection*/\n    if(ext->opened) lv_page_set_sb_mode(ddlist, LV_SB_MODE_UNHIDE);\n}\n\n/**\n * Adjusts the ddlist's height and then positions the option within it's new height.\n * This keeps the option visible during animation.\n * @param ddlist Drop down list object\n * @param height New drop down list height\n */\nstatic void lv_ddlist_adjust_height(lv_obj_t * ddlist, lv_anim_value_t height)\n{\n    lv_obj_set_height(ddlist, height);\n    lv_ddlist_pos_current_option(ddlist);\n}\n#endif\n\n/**\n * Set the position of list when it is closed to show the selected item\n * @param ddlist pointer to a drop down list\n */\nstatic void lv_ddlist_pos_current_option(lv_obj_t * ddlist)\n{\n    lv_ddlist_ext_t * ext          = lv_obj_get_ext_attr(ddlist);\n    const lv_style_t * style       = lv_obj_get_style(ddlist);\n    const lv_font_t * font         = style->text.font;\n    lv_coord_t font_h              = lv_font_get_line_height(font);\n    const lv_style_t * label_style = lv_obj_get_style(ext->label);\n    lv_obj_t * scrl                = lv_page_get_scrl(ddlist);\n\n    lv_coord_t h = lv_obj_get_height(ddlist);\n    lv_coord_t line_y1 =\n        ext->sel_opt_id * (font_h + label_style->text.line_space) + ext->label->coords.y1 - scrl->coords.y1;\n\n    lv_obj_set_y(scrl, -line_y1 + (h - font_h) / 2);\n    lv_obj_invalidate(ddlist);\n}\n\n/**\n * Be sure the width of the scrollable exactly fits the ddlist\n * @param ddlist pointer to a ddlist\n */\nstatic void lv_ddlist_refr_width(lv_obj_t * ddlist)\n{\n    /*Set the TIGHT fit horizontally the set the width to the content*/\n    lv_page_set_scrl_fit2(ddlist, LV_FIT_TIGHT, lv_page_get_scrl_fit_bottom(ddlist));\n\n    /*Revert FILL fit to fill the parent with the options area. It allows to RIGHT/CENTER align the text*/\n    lv_page_set_scrl_fit2(ddlist, LV_FIT_FILL, lv_page_get_scrl_fit_bottom(ddlist));\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_gauge.c",
    "content": "/**\n * @file lv_gauge.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_gauge.h\"\n#if LV_USE_GAUGE != 0\n\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_misc/lv_txt.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n#include \"libs/lvgl/lv_misc/lv_utils.h\"\n#include <stdio.h>\n#include <string.h>\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_GAUGE_DEF_NEEDLE_COLOR LV_COLOR_RED\n#define LV_GAUGE_DEF_LABEL_COUNT 6\n#define LV_GAUGE_DEF_LINE_COUNT 21 /*Should be: ((label_cnt - 1) * internal_lines) + 1*/\n#define LV_GAUGE_DEF_ANGLE 220\n#define LV_GAUGE_INTERPOLATE_SHIFT 5 /*Interpolate the needle drawing between to degrees*/\n#define LV_GAUGE_INTERPOLATE_MASK 0x1F\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_gauge_design(lv_obj_t * gauge, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_gauge_signal(lv_obj_t * gauge, lv_signal_t sign, void * param);\nstatic void lv_gauge_draw_scale(lv_obj_t * gauge, const lv_area_t * mask);\nstatic void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * mask);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_design_cb_t ancestor_design;\nstatic lv_signal_cb_t ancestor_signal;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a gauge objects\n * @param par pointer to an object, it will be the parent of the new gauge\n * @param copy pointer to a gauge object, if not NULL then the new object will be copied from it\n * @return pointer to the created gauge\n */\nlv_obj_t * lv_gauge_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"gauge create started\");\n\n    /*Create the ancestor gauge*/\n    lv_obj_t * new_gauge = lv_lmeter_create(par, copy);\n    lv_mem_assert(new_gauge);\n    if(new_gauge == NULL) return NULL;\n\n    /*Allocate the gauge type specific extended data*/\n    lv_gauge_ext_t * ext = lv_obj_allocate_ext_attr(new_gauge, sizeof(lv_gauge_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    /*Initialize the allocated 'ext' */\n    ext->needle_count  = 0;\n    ext->values        = NULL;\n    ext->needle_colors = NULL;\n    ext->label_count   = LV_GAUGE_DEF_LABEL_COUNT;\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_gauge);\n    if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_gauge);\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_cb(new_gauge, lv_gauge_signal);\n    lv_obj_set_design_cb(new_gauge, lv_gauge_design);\n\n    /*Init the new gauge gauge*/\n    if(copy == NULL) {\n        lv_gauge_set_scale(new_gauge, LV_GAUGE_DEF_ANGLE, LV_GAUGE_DEF_LINE_COUNT, LV_GAUGE_DEF_LABEL_COUNT);\n        lv_gauge_set_needle_count(new_gauge, 1, NULL);\n        lv_gauge_set_critical_value(new_gauge, 80);\n        lv_obj_set_size(new_gauge, 2 * LV_DPI, 2 * LV_DPI);\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_gauge_set_style(new_gauge, LV_GAUGE_STYLE_MAIN, th->style.gauge);\n        } else {\n            lv_gauge_set_style(new_gauge, LV_GAUGE_STYLE_MAIN, &lv_style_pretty_color);\n        }\n    }\n    /*Copy an existing gauge*/\n    else {\n        lv_gauge_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        lv_gauge_set_needle_count(new_gauge, copy_ext->needle_count, copy_ext->needle_colors);\n\n        uint8_t i;\n        for(i = 0; i < ext->needle_count; i++) {\n            ext->values[i] = copy_ext->values[i];\n        }\n        ext->label_count = copy_ext->label_count;\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_gauge);\n    }\n\n    LV_LOG_INFO(\"gauge created\");\n\n    return new_gauge;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the number of needles\n * @param gauge pointer to gauge object\n * @param needle_cnt new count of needles\n * @param colors an array of colors for needles (with 'num' elements)\n */\nvoid lv_gauge_set_needle_count(lv_obj_t * gauge, uint8_t needle_cnt, const lv_color_t colors[])\n{\n    lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);\n\n    if(ext->needle_count != needle_cnt) {\n        if(ext->values != NULL) {\n            lv_mem_free(ext->values);\n            ext->values = NULL;\n        }\n\n        ext->values = lv_mem_realloc(ext->values, needle_cnt * sizeof(int16_t));\n        lv_mem_assert(ext->values);\n        if(ext->values == NULL) return;\n\n        int16_t min = lv_gauge_get_min_value(gauge);\n        uint8_t n;\n        for(n = ext->needle_count; n < needle_cnt; n++) {\n            ext->values[n] = min;\n        }\n\n        ext->needle_count = needle_cnt;\n    }\n\n    ext->needle_colors = colors;\n    lv_obj_invalidate(gauge);\n}\n\n/**\n * Set the value of a needle\n * @param gauge pointer to a gauge\n * @param needle_id the id of the needle\n * @param value the new value\n */\nvoid lv_gauge_set_value(lv_obj_t * gauge, uint8_t needle_id, int16_t value)\n{\n    lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);\n\n    if(needle_id >= ext->needle_count) return;\n    if(ext->values[needle_id] == value) return;\n\n    int16_t min = lv_gauge_get_min_value(gauge);\n    int16_t max = lv_gauge_get_max_value(gauge);\n\n    if(value > max)\n        value = max;\n    else if(value < min)\n        value = min;\n\n    ext->values[needle_id] = value;\n\n    lv_obj_invalidate(gauge);\n}\n\n/**\n * Set the scale settings of a gauge\n * @param gauge pointer to a gauge object\n * @param angle angle of the scale (0..360)\n * @param line_cnt count of scale lines.\n * The get a given \"subdivision\" lines between label, `line_cnt` = (sub_div + 1) * (label_cnt - 1) +\n * 1\n * @param label_cnt count of scale labels.\n */\nvoid lv_gauge_set_scale(lv_obj_t * gauge, uint16_t angle, uint8_t line_cnt, uint8_t label_cnt)\n{\n    lv_lmeter_set_scale(gauge, angle, line_cnt);\n\n    lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);\n    ext->label_count     = label_cnt;\n    lv_obj_invalidate(gauge);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the value of a needle\n * @param gauge pointer to gauge object\n * @param needle the id of the needle\n * @return the value of the needle [min,max]\n */\nint16_t lv_gauge_get_value(const lv_obj_t * gauge, uint8_t needle)\n{\n    lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);\n    int16_t min          = lv_gauge_get_min_value(gauge);\n\n    if(needle >= ext->needle_count) return min;\n\n    return ext->values[needle];\n}\n\n/**\n * Get the count of needles on a gauge\n * @param gauge pointer to gauge\n * @return count of needles\n */\nuint8_t lv_gauge_get_needle_count(const lv_obj_t * gauge)\n{\n    lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);\n    return ext->needle_count;\n}\n\n/**\n * Set the number of labels (and the thicker lines too)\n * @param gauge pointer to a gauge object\n * @return count of labels\n */\nuint8_t lv_gauge_get_label_count(const lv_obj_t * gauge)\n{\n    lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);\n    return ext->label_count;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the gauges\n * @param gauge pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_gauge_design(lv_obj_t * gauge, const lv_area_t * mask, lv_design_mode_t mode)\n{\n\n    /*Return false if the object is not covers the mask_p area*/\n    if(mode == LV_DESIGN_COVER_CHK) {\n        return false;\n    }\n    /*Draw the object*/\n    else if(mode == LV_DESIGN_DRAW_MAIN) {\n\n        /* Store the real pointer because of 'lv_group'\n         * If the object is in focus 'lv_obj_get_style()' will give a pointer to tmp style\n         * and to the real object style. It is important because of style change tricks below*/\n        const lv_style_t * style_ori_p = gauge->style_p;\n        const lv_style_t * style       = lv_obj_get_style(gauge);\n        lv_gauge_ext_t * ext           = lv_obj_get_ext_attr(gauge);\n\n        lv_gauge_draw_scale(gauge, mask);\n\n        /*Draw the ancestor line meter with max value to show the rainbow like line colors*/\n        uint16_t line_cnt_tmp = ext->lmeter.line_cnt;\n        ancestor_design(gauge, mask, mode); /*To draw lines*/\n\n        /*Temporally modify the line meter to draw longer lines where labels are*/\n        lv_style_t style_tmp;\n        lv_style_copy(&style_tmp, style);\n        ext->lmeter.line_cnt         = ext->label_count;                 /*Only to labels*/\n        style_tmp.body.padding.left  = style_tmp.body.padding.left * 2;  /*Longer lines*/\n        style_tmp.body.padding.right = style_tmp.body.padding.right * 2; /*Longer lines*/\n        gauge->style_p               = &style_tmp;\n\n        ancestor_design(gauge, mask, mode); /*To draw lines*/\n\n        ext->lmeter.line_cnt = line_cnt_tmp; /*Restore the parameters*/\n        gauge->style_p       = style_ori_p;  /*Restore the ORIGINAL style pointer*/\n\n        lv_gauge_draw_needle(gauge, mask);\n\n    }\n    /*Post draw when the children are drawn*/\n    else if(mode == LV_DESIGN_DRAW_POST) {\n        ancestor_design(gauge, mask, mode);\n    }\n\n    return true;\n}\n\n/**\n * Signal function of the gauge\n * @param gauge pointer to a gauge object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_gauge_signal(lv_obj_t * gauge, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(gauge, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_gauge_ext_t * ext = lv_obj_get_ext_attr(gauge);\n    if(sign == LV_SIGNAL_CLEANUP) {\n        lv_mem_free(ext->values);\n        ext->values = NULL;\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_gauge\";\n    }\n\n    return res;\n}\n\n/**\n * Draw the scale on a gauge\n * @param gauge pointer to gauge object\n * @param mask mask of drawing\n */\nstatic void lv_gauge_draw_scale(lv_obj_t * gauge, const lv_area_t * mask)\n{\n    char scale_txt[16];\n\n    lv_gauge_ext_t * ext     = lv_obj_get_ext_attr(gauge);\n    const lv_style_t * style = lv_obj_get_style(gauge);\n    lv_opa_t opa_scale       = lv_obj_get_opa_scale(gauge);\n    lv_coord_t r             = lv_obj_get_width(gauge) / 2 - (3 * style->body.padding.left) - style->body.padding.inner;\n    lv_coord_t x_ofs         = lv_obj_get_width(gauge) / 2 + gauge->coords.x1;\n    lv_coord_t y_ofs         = lv_obj_get_height(gauge) / 2 + gauge->coords.y1;\n    int16_t scale_angle      = lv_lmeter_get_scale_angle(gauge);\n    uint16_t label_num       = ext->label_count;\n    int16_t angle_ofs        = 90 + (360 - scale_angle) / 2;\n    int16_t min              = lv_gauge_get_min_value(gauge);\n    int16_t max              = lv_gauge_get_max_value(gauge);\n\n    uint8_t i;\n    for(i = 0; i < label_num; i++) {\n        /*Calculate the position a scale label*/\n        int16_t angle = (i * scale_angle) / (label_num - 1) + angle_ofs;\n\n        lv_coord_t y = (int32_t)((int32_t)lv_trigo_sin(angle) * r) / LV_TRIGO_SIN_MAX;\n        y += y_ofs;\n\n        lv_coord_t x = (int32_t)((int32_t)lv_trigo_sin(angle + 90) * r) / LV_TRIGO_SIN_MAX;\n        x += x_ofs;\n\n        int16_t scale_act = (int32_t)((int32_t)(max - min) * i) / (label_num - 1);\n        scale_act += min;\n        lv_utils_num_to_str(scale_act, scale_txt);\n\n        lv_area_t label_cord;\n        lv_point_t label_size;\n        lv_txt_get_size(&label_size, scale_txt, style->text.font, style->text.letter_space, style->text.line_space,\n                        LV_COORD_MAX, LV_TXT_FLAG_NONE);\n\n        /*Draw the label*/\n        label_cord.x1 = x - label_size.x / 2;\n        label_cord.y1 = y - label_size.y / 2;\n        label_cord.x2 = label_cord.x1 + label_size.x;\n        label_cord.y2 = label_cord.y1 + label_size.y;\n\n        lv_draw_label(&label_cord, mask, style, opa_scale, scale_txt, LV_TXT_FLAG_NONE, NULL, -1, -1, NULL);\n    }\n}\n/**\n * Draw the needles of a gauge\n * @param gauge pointer to gauge object\n * @param mask mask of drawing\n */\nstatic void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * mask)\n{\n    lv_style_t style_needle;\n    lv_gauge_ext_t * ext     = lv_obj_get_ext_attr(gauge);\n    const lv_style_t * style = lv_gauge_get_style(gauge, LV_GAUGE_STYLE_MAIN);\n    lv_opa_t opa_scale       = lv_obj_get_opa_scale(gauge);\n\n    lv_coord_t r      = lv_obj_get_width(gauge) / 2 - style->body.padding.left;\n    lv_coord_t x_ofs  = lv_obj_get_width(gauge) / 2 + gauge->coords.x1;\n    lv_coord_t y_ofs  = lv_obj_get_height(gauge) / 2 + gauge->coords.y1;\n    uint16_t angle    = lv_lmeter_get_scale_angle(gauge);\n    int16_t angle_ofs = 90 + (360 - angle) / 2;\n    int16_t min       = lv_gauge_get_min_value(gauge);\n    int16_t max       = lv_gauge_get_max_value(gauge);\n    lv_point_t p_mid;\n    lv_point_t p_end;\n    lv_point_t p_end_low;\n    lv_point_t p_end_high;\n    uint8_t i;\n\n    lv_style_copy(&style_needle, style);\n\n    p_mid.x = x_ofs;\n    p_mid.y = y_ofs;\n    for(i = 0; i < ext->needle_count; i++) {\n        /*Calculate the end point of a needle*/\n        int16_t needle_angle =\n            (ext->values[i] - min) * angle * (1 << LV_GAUGE_INTERPOLATE_SHIFT) / (max - min);\n\n        int16_t needle_angle_low  = (needle_angle >> LV_GAUGE_INTERPOLATE_SHIFT) + angle_ofs;\n        int16_t needle_angle_high = needle_angle_low + 1;\n\n        p_end_low.y = (lv_trigo_sin(needle_angle_low) * r) / LV_TRIGO_SIN_MAX + y_ofs;\n        p_end_low.x = (lv_trigo_sin(needle_angle_low + 90) * r) / LV_TRIGO_SIN_MAX + x_ofs;\n\n        p_end_high.y = (lv_trigo_sin(needle_angle_high) * r) / LV_TRIGO_SIN_MAX + y_ofs;\n        p_end_high.x = (lv_trigo_sin(needle_angle_high + 90) * r) / LV_TRIGO_SIN_MAX + x_ofs;\n\n        uint16_t rem  = needle_angle & ((1 << LV_GAUGE_INTERPOLATE_SHIFT) - 1);\n        int16_t x_mod = ((LV_MATH_ABS(p_end_high.x - p_end_low.x)) * rem) >> LV_GAUGE_INTERPOLATE_SHIFT;\n        int16_t y_mod = ((LV_MATH_ABS(p_end_high.y - p_end_low.y)) * rem) >> LV_GAUGE_INTERPOLATE_SHIFT;\n\n        if(p_end_high.x < p_end_low.x) x_mod = -x_mod;\n        if(p_end_high.y < p_end_low.y) y_mod = -y_mod;\n\n        p_end.x = p_end_low.x + x_mod;\n        p_end.y = p_end_low.y + y_mod;\n\n        /*Draw the needle with the corresponding color*/\n        if(ext->needle_colors == NULL)\n            style_needle.line.color = LV_GAUGE_DEF_NEEDLE_COLOR;\n        else\n            style_needle.line.color = ext->needle_colors[i];\n\n        lv_draw_line(&p_mid, &p_end, mask, &style_needle, opa_scale);\n    }\n\n    /*Draw the needle middle area*/\n    lv_style_t style_neddle_mid;\n    lv_style_copy(&style_neddle_mid, &lv_style_plain);\n    style_neddle_mid.body.main_color = style->body.border.color;\n    style_neddle_mid.body.grad_color = style->body.border.color;\n    style_neddle_mid.body.radius     = LV_RADIUS_CIRCLE;\n\n    lv_area_t nm_cord;\n    nm_cord.x1 = x_ofs - style->body.radius;\n    nm_cord.y1 = y_ofs - style->body.radius;\n    nm_cord.x2 = x_ofs + style->body.radius;\n    nm_cord.y2 = y_ofs + style->body.radius;\n\n    lv_draw_rect(&nm_cord, mask, &style_neddle_mid, lv_obj_get_opa_scale(gauge));\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_img.c",
    "content": "/**\n * @file lv_img.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_img.h\"\n#if LV_USE_IMG != 0\n\n/*Testing of dependencies*/\n#if LV_USE_LABEL == 0\n#error \"lv_img: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL  1) \"\n#endif\n\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_draw/lv_img_decoder.h\"\n#include \"libs/lvgl/lv_misc/lv_fs.h\"\n#include \"libs/lvgl/lv_misc/lv_txt.h\"\n#include \"libs/lvgl/lv_misc/lv_log.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_img_design(lv_obj_t * img, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_img_signal(lv_obj_t * img, lv_signal_t sign, void * param);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create an image objects\n * @param par pointer to an object, it will be the parent of the new button\n * @param copy pointer to a image object, if not NULL then the new object will be copied from it\n * @return pointer to the created image\n */\nlv_obj_t * lv_img_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"image create started\");\n\n    lv_obj_t * new_img = NULL;\n\n    /*Create a basic object*/\n    new_img = lv_obj_create(par, copy);\n    lv_mem_assert(new_img);\n    if(new_img == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_img);\n\n    /*Extend the basic object to image object*/\n    lv_img_ext_t * ext = lv_obj_allocate_ext_attr(new_img, sizeof(lv_img_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    ext->src       = NULL;\n    ext->src_type  = LV_IMG_SRC_UNKNOWN;\n    ext->cf        = LV_IMG_CF_UNKNOWN;\n    ext->w         = lv_obj_get_width(new_img);\n    ext->h         = lv_obj_get_height(new_img);\n    ext->auto_size = 1;\n    ext->offset.x  = 0;\n    ext->offset.y  = 0;\n\n    /*Init the new object*/\n    lv_obj_set_signal_cb(new_img, lv_img_signal);\n    lv_obj_set_design_cb(new_img, lv_img_design);\n\n    if(copy == NULL) {\n        lv_obj_set_click(new_img, false);\n        /* Enable auto size for non screens\n         * because image screens are wallpapers\n         * and must be screen sized*/\n        if(par != NULL) {\n            ext->auto_size = 1;\n            lv_obj_set_style(new_img, NULL); /*Inherit the style  by default*/\n        } else {\n            ext->auto_size = 0;\n            lv_obj_set_style(new_img, &lv_style_plain); /*Set a style for screens*/\n        }\n    } else {\n        lv_img_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->auto_size          = copy_ext->auto_size;\n        lv_img_set_src(new_img, copy_ext->src);\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_img);\n    }\n\n    LV_LOG_INFO(\"image created\");\n\n    return new_img;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the pixel map to display by the image\n * @param img pointer to an image object\n * @param data the image data\n */\nvoid lv_img_set_src(lv_obj_t * img, const void * src_img)\n{\n    lv_img_src_t src_type = lv_img_src_get_type(src_img);\n    lv_img_ext_t * ext    = lv_obj_get_ext_attr(img);\n\n#if LV_USE_LOG && LV_LOG_LEVEL >= LV_LOG_LEVEL_INFO\n    switch(src_type) {\n        case LV_IMG_SRC_FILE: LV_LOG_TRACE(\"lv_img_set_src: `LV_IMG_SRC_FILE` type found\"); break;\n        case LV_IMG_SRC_VARIABLE: LV_LOG_TRACE(\"lv_img_set_src: `LV_IMG_SRC_VARIABLE` type found\"); break;\n        case LV_IMG_SRC_SYMBOL: LV_LOG_TRACE(\"lv_img_set_src: `LV_IMG_SRC_SYMBOL` type found\"); break;\n        default: LV_LOG_WARN(\"lv_img_set_src: unknown type\");\n    }\n#endif\n\n    /*If the new source type is unknown free the memories of the old source*/\n    if(src_type == LV_IMG_SRC_UNKNOWN) {\n        LV_LOG_WARN(\"lv_img_set_src: unknown image type\");\n        if(ext->src_type == LV_IMG_SRC_SYMBOL || ext->src_type == LV_IMG_SRC_FILE) {\n            lv_mem_free(ext->src);\n        }\n        ext->src      = NULL;\n        ext->src_type = LV_IMG_SRC_UNKNOWN;\n        return;\n    }\n\n    lv_img_header_t header;\n    lv_img_decoder_get_info(src_img, &header);\n\n    /*Save the source*/\n    if(src_type == LV_IMG_SRC_VARIABLE) {\n        LV_LOG_INFO(\"lv_img_set_src:  `LV_IMG_SRC_VARIABLE` type found\");\n\n        /*If memory was allocated because of the previous `src_type` then free it*/\n        if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_SYMBOL) {\n            lv_mem_free(ext->src);\n        }\n        ext->src = src_img;\n    } else if(src_type == LV_IMG_SRC_FILE || src_type == LV_IMG_SRC_SYMBOL) {\n        /* If the new and the old src are the same then it was only a refresh.*/\n        if(ext->src != src_img) {\n            /*If memory was allocated because of the previous `src_type` then free it*/\n            if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_SYMBOL) {\n                lv_mem_free(ext->src);\n            }\n            char * new_str = lv_mem_alloc(strlen(src_img) + 1);\n            lv_mem_assert(new_str);\n            if(new_str == NULL) return;\n            strcpy(new_str, src_img);\n            ext->src = new_str;\n        }\n    }\n\n    if(src_type == LV_IMG_SRC_SYMBOL) {\n        /*`lv_img_dsc_get_info` couldn't set the with and height of a font so set it here*/\n        const lv_style_t * style = lv_img_get_style(img, LV_IMG_STYLE_MAIN);\n        lv_point_t size;\n        lv_txt_get_size(&size, src_img, style->text.font, style->text.letter_space, style->text.line_space,\n                        LV_COORD_MAX, LV_TXT_FLAG_NONE);\n        header.w = size.x;\n        header.h = size.y;\n    }\n\n    ext->src_type = src_type;\n    ext->w        = header.w;\n    ext->h        = header.h;\n    ext->cf       = header.cf;\n\n    if(lv_img_get_auto_size(img) != false) {\n        lv_obj_set_size(img, ext->w, ext->h);\n    }\n\n    lv_obj_invalidate(img);\n}\n\n/**\n * Enable the auto size feature.\n * If enabled the object size will be same as the picture size.\n * @param img pointer to an image\n * @param en true: auto size enable, false: auto size disable\n */\nvoid lv_img_set_auto_size(lv_obj_t * img, bool en)\n{\n    lv_img_ext_t * ext = lv_obj_get_ext_attr(img);\n\n    ext->auto_size = (en == false ? 0 : 1);\n}\n\n/**\n * Set an offset for the source of an image.\n * so the image will be displayed from the new origin.\n * @param img pointer to an image\n * @param x: the new offset along x axis.\n */\nvoid lv_img_set_offset_x(lv_obj_t * img, lv_coord_t x)\n{\n    lv_img_ext_t * ext = lv_obj_get_ext_attr(img);\n\n    if(x < ext->w - 1) {\n        ext->offset.x = x;\n        lv_obj_invalidate(img);\n    }\n}\n\n/**\n * Set an offset for the source of an image.\n * so the image will be displayed from the new origin.\n * @param img pointer to an image\n * @param y: the new offset along y axis.\n */\nvoid lv_img_set_offset_y(lv_obj_t * img, lv_coord_t y)\n{\n    lv_img_ext_t * ext = lv_obj_get_ext_attr(img);\n\n    if(y < ext->h - 1) {\n        ext->offset.y = y;\n        lv_obj_invalidate(img);\n    }\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the source of the image\n * @param img pointer to an image object\n * @return the image source (symbol, file name or C array)\n */\nconst void * lv_img_get_src(lv_obj_t * img)\n{\n    lv_img_ext_t * ext = lv_obj_get_ext_attr(img);\n\n    return ext->src;\n}\n\n/**\n * Get the name of the file set for an image\n * @param img pointer to an image\n * @return file name\n */\nconst char * lv_img_get_file_name(const lv_obj_t * img)\n{\n    lv_img_ext_t * ext = lv_obj_get_ext_attr(img);\n\n    if(ext->src_type == LV_IMG_SRC_FILE)\n        return ext->src;\n    else\n        return \"\";\n}\n\n/**\n * Get the auto size enable attribute\n * @param img pointer to an image\n * @return true: auto size is enabled, false: auto size is disabled\n */\nbool lv_img_get_auto_size(const lv_obj_t * img)\n{\n    lv_img_ext_t * ext = lv_obj_get_ext_attr(img);\n\n    return ext->auto_size == 0 ? false : true;\n}\n\n/**\n * Get the offset.x attribute of the img object.\n * @param img pointer to an image\n * @return offset.x value.\n */\nlv_coord_t lv_img_get_offset_x(lv_obj_t * img)\n{\n    lv_img_ext_t * ext = lv_obj_get_ext_attr(img);\n\n    return ext->offset.x;\n}\n\n/**\n * Get the offset.y attribute of the img object.\n * @param img pointer to an image\n * @return offset.y value.\n */\nlv_coord_t lv_img_get_offset_y(lv_obj_t * img)\n{\n    lv_img_ext_t * ext = lv_obj_get_ext_attr(img);\n\n    return ext->offset.y;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the images\n * @param img pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_img_design(lv_obj_t * img, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    const lv_style_t * style = lv_obj_get_style(img);\n    lv_img_ext_t * ext       = lv_obj_get_ext_attr(img);\n\n    if(mode == LV_DESIGN_COVER_CHK) {\n        bool cover = false;\n        if(ext->src_type == LV_IMG_SRC_UNKNOWN || ext->src_type == LV_IMG_SRC_SYMBOL) return false;\n\n        if(ext->cf == LV_IMG_CF_TRUE_COLOR || ext->cf == LV_IMG_CF_RAW) cover = lv_area_is_in(mask, &img->coords);\n\n        return cover;\n    } else if(mode == LV_DESIGN_DRAW_MAIN) {\n        if(ext->h == 0 || ext->w == 0) return true;\n        lv_area_t coords;\n        lv_opa_t opa_scale = lv_obj_get_opa_scale(img);\n\n        lv_obj_get_coords(img, &coords);\n\n        if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_VARIABLE) {\n            coords.x1 -= ext->offset.x;\n            coords.y1 -= ext->offset.y;\n\n            LV_LOG_TRACE(\"lv_img_design: start to draw image\");\n            lv_area_t cords_tmp;\n            cords_tmp.y1 = coords.y1;\n            cords_tmp.y2 = coords.y1 + ext->h - 1;\n\n            for(; cords_tmp.y1 < coords.y2; cords_tmp.y1 += ext->h, cords_tmp.y2 += ext->h) {\n                cords_tmp.x1 = coords.x1;\n                cords_tmp.x2 = coords.x1 + ext->w - 1;\n                for(; cords_tmp.x1 < coords.x2; cords_tmp.x1 += ext->w, cords_tmp.x2 += ext->w) {\n                    lv_draw_img(&cords_tmp, mask, ext->src, style, opa_scale);\n                }\n            }\n        } else if(ext->src_type == LV_IMG_SRC_SYMBOL) {\n            LV_LOG_TRACE(\"lv_img_design: start to draw symbol\");\n            lv_style_t style_mod;\n            lv_style_copy(&style_mod, style);\n            style_mod.text.color = style->image.color;\n            lv_draw_label(&coords, mask, &style_mod, opa_scale, ext->src, LV_TXT_FLAG_NONE, NULL, -1, -1, NULL);\n        } else {\n            /*Trigger the error handler of image drawer*/\n            LV_LOG_WARN(\"lv_img_design: image source type is unknown\");\n            lv_draw_img(&img->coords, mask, NULL, style, opa_scale);\n        }\n    }\n\n    return true;\n}\n\n/**\n * Signal function of the image\n * @param img pointer to an image object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_img_signal(lv_obj_t * img, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(img, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_img_ext_t * ext = lv_obj_get_ext_attr(img);\n    if(sign == LV_SIGNAL_CLEANUP) {\n        if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_SYMBOL) {\n            lv_mem_free(ext->src);\n            ext->src      = NULL;\n            ext->src_type = LV_IMG_SRC_UNKNOWN;\n        }\n    } else if(sign == LV_SIGNAL_STYLE_CHG) {\n        /*Refresh the file name to refresh the symbol text size*/\n        if(ext->src_type == LV_IMG_SRC_SYMBOL) {\n            lv_img_set_src(img, ext->src);\n        }\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_img\";\n    }\n\n    return res;\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_imgbtn.c",
    "content": "/**\n * @file lv_imgbtn.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_imgbtn.h\"\n#if LV_USE_IMGBTN != 0\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_imgbtn_signal(lv_obj_t * imgbtn, lv_signal_t sign, void * param);\nstatic void refr_img(lv_obj_t * imgbtn);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\nstatic lv_design_cb_t ancestor_design;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a image button object\n * @param par pointer to an object, it will be the parent of the new image button\n * @param copy pointer to a image button object, if not NULL then the new object will be copied from\n * it\n * @return pointer to the created image button\n */\nlv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"image button create started\");\n\n    /*Create the ancestor of image button*/\n    lv_obj_t * new_imgbtn = lv_btn_create(par, copy);\n    lv_mem_assert(new_imgbtn);\n    if(new_imgbtn == NULL) return NULL;\n\n    /*Allocate the image button type specific extended data*/\n    lv_imgbtn_ext_t * ext = lv_obj_allocate_ext_attr(new_imgbtn, sizeof(lv_imgbtn_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_imgbtn);\n    if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_imgbtn);\n\n        /*Initialize the allocated 'ext' */\n#if LV_IMGBTN_TILED == 0\n    memset(ext->img_src, 0, sizeof(ext->img_src));\n#else\n    memset(ext->img_src_left, 0, sizeof(ext->img_src_left));\n    memset(ext->img_src_mid, 0, sizeof(ext->img_src_mid));\n    memset(ext->img_src_right, 0, sizeof(ext->img_src_right));\n#endif\n\n    ext->act_cf = LV_IMG_CF_UNKNOWN;\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_cb(new_imgbtn, lv_imgbtn_signal);\n    lv_obj_set_design_cb(new_imgbtn, lv_imgbtn_design);\n\n    /*Init the new image button image button*/\n    if(copy == NULL) {\n\n    }\n    /*Copy an existing image button*/\n    else {\n        lv_imgbtn_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n#if LV_IMGBTN_TILED == 0\n        memcpy(ext->img_src, copy_ext->img_src, sizeof(ext->img_src));\n#else\n        memcpy(ext->img_src_left, copy_ext->img_src_left, sizeof(ext->img_src_left));\n        memcpy(ext->img_src_mid, copy_ext->img_src_mid, sizeof(ext->img_src_mid));\n        memcpy(ext->img_src_right, copy_ext->img_src_right, sizeof(ext->img_src_right));\n#endif\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_imgbtn);\n    }\n\n    LV_LOG_INFO(\"image button created\");\n\n    return new_imgbtn;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n#if LV_IMGBTN_TILED == 0\n/**\n * Set images for a state of the image button\n * @param imgbtn pointer to an image button object\n * @param state for which state set the new image (from `lv_btn_state_t`) `\n * @param src pointer to an image source (a C array or path to a file)\n */\nvoid lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src)\n{\n    lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);\n\n    ext->img_src[state] = src;\n\n    refr_img(imgbtn);\n}\n\n#else\n/**\n * Set images for a state of the image button\n * @param imgbtn pointer to an image button object\n * @param state for which state set the new image (from `lv_btn_state_t`) `\n * @param src_left pointer to an image source for the left side of the button (a C array or path to\n * a file)\n * @param src_mid pointer to an image source for the middle of the button (ideally 1px wide) (a C\n * array or path to a file)\n * @param src_right pointer to an image source for the right side of the button (a C array or path\n * to a file)\n */\nvoid lv_imgbtn_set_src(lv_obj_t * imgbtn, lv_btn_state_t state, const void * src_left, const void * src_mid,\n                       const void * src_right)\n{\n    lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);\n\n    ext->img_src_left[state] = src_left;\n    ext->img_src_mid[state] = src_mid;\n    ext->img_src_right[state] = src_right;\n\n    refr_img(imgbtn);\n}\n\n#endif\n\n/**\n * Set a style of a image button.\n * @param imgbtn pointer to image button object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_imgbtn_set_style(lv_obj_t * imgbtn, lv_imgbtn_style_t type, const lv_style_t * style)\n{\n    lv_btn_set_style(imgbtn, type, style);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n#if LV_IMGBTN_TILED == 0\n/**\n * Get the images in a  given state\n * @param imgbtn pointer to an image button object\n * @param state the state where to get the image (from `lv_btn_state_t`) `\n * @return pointer to an image source (a C array or path to a file)\n */\nconst void * lv_imgbtn_get_src(lv_obj_t * imgbtn, lv_btn_state_t state)\n{\n    lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);\n\n    return ext->img_src[state];\n}\n#else\n\n/**\n * Get the left image in a given state\n * @param imgbtn pointer to an image button object\n * @param state the state where to get the image (from `lv_btn_state_t`) `\n * @return pointer to the left image source (a C array or path to a file)\n */\nconst void * lv_imgbtn_get_src_left(lv_obj_t * imgbtn, lv_btn_state_t state)\n{\n    lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);\n\n    return ext->img_src_left[state];\n}\n\n/**\n * Get the middle image in a given state\n * @param imgbtn pointer to an image button object\n * @param state the state where to get the image (from `lv_btn_state_t`) `\n * @return pointer to the middle image source (a C array or path to a file)\n */\nconst void * lv_imgbtn_get_src_middle(lv_obj_t * imgbtn, lv_btn_state_t state)\n{\n    lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);\n\n    return ext->img_src_mid[state];\n}\n\n/**\n * Get the right image in a given state\n * @param imgbtn pointer to an image button object\n * @param state the state where to get the image (from `lv_btn_state_t`) `\n * @return pointer to the left image source (a C array or path to a file)\n */\nconst void * lv_imgbtn_get_src_right(lv_obj_t * imgbtn, lv_btn_state_t state)\n{\n    lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);\n\n    return ext->img_src_right[state];\n}\n\n#endif\n\n/**\n * Get style of a image button.\n * @param imgbtn pointer to image button object\n * @param type which style should be get\n * @return style pointer to the style\n */\nconst lv_style_t * lv_imgbtn_get_style(const lv_obj_t * imgbtn, lv_imgbtn_style_t type)\n{\n    return lv_btn_get_style(imgbtn, type);\n}\n\n/*=====================\n * Other functions\n *====================*/\n\n/*\n * New object specific \"other\" functions come here\n */\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the image buttons\n * @param imgbtn pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    /*Return false if the object is not covers the mask_p area*/\n    if(mode == LV_DESIGN_COVER_CHK) {\n        lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);\n        bool cover            = false;\n        if(ext->act_cf == LV_IMG_CF_TRUE_COLOR || ext->act_cf == LV_IMG_CF_RAW) {\n            cover = lv_area_is_in(mask, &imgbtn->coords);\n        }\n\n        return cover;\n    }\n    /*Draw the object*/\n    else if(mode == LV_DESIGN_DRAW_MAIN) {\n        /*Just draw an image*/\n        lv_imgbtn_ext_t * ext    = lv_obj_get_ext_attr(imgbtn);\n        lv_btn_state_t state     = lv_imgbtn_get_state(imgbtn);\n        const lv_style_t * style = lv_imgbtn_get_style(imgbtn, state);\n        lv_opa_t opa_scale       = lv_obj_get_opa_scale(imgbtn);\n\n#if LV_IMGBTN_TILED == 0\n        const void * src = ext->img_src[state];\n        lv_draw_img(&imgbtn->coords, mask, src, style, opa_scale);\n#else\n        const void * src;\n        lv_img_header_t header;\n        lv_area_t coords;\n        lv_coord_t left_w = 0;\n        lv_coord_t right_w = 0;\n\n        src = ext->img_src_left[state];\n        if(src) {\n            lv_img_decoder_get_info(src, &header);\n            left_w = header.w;\n            coords.x1 = imgbtn->coords.x1;\n            coords.y1 = imgbtn->coords.y1;\n            coords.x2 = coords.x1 + header.w - 1;\n            coords.y2 = coords.y1 + header.h - 1;\n            lv_draw_img(&coords, mask, src, style, opa_scale);\n        }\n\n        src = ext->img_src_right[state];\n        if(src) {\n            lv_img_decoder_get_info(src, &header);\n            right_w = header.w;\n            coords.x1 = imgbtn->coords.x2 - header.w + 1;\n            coords.y1 = imgbtn->coords.y1;\n            coords.x2 = imgbtn->coords.x2;\n            coords.y2 = imgbtn->coords.y1 + header.h - 1;\n            lv_draw_img(&coords, mask, src, style, opa_scale);\n        }\n\n        src = ext->img_src_mid[state];\n        if(src) {\n            lv_coord_t obj_w = lv_obj_get_width(imgbtn);\n            lv_coord_t i;\n            lv_img_decoder_get_info(src, &header);\n\n            coords.x1 = imgbtn->coords.x1 + left_w;\n            coords.y1 = imgbtn->coords.y1;\n            coords.x2 = coords.x1 + header.w - 1;\n            coords.y2 = imgbtn->coords.y1 + header.h - 1;\n\n            for(i = 0; i < obj_w - right_w - left_w; i += header.w) {\n                lv_draw_img(&coords, mask, src, style, opa_scale);\n                coords.x1 = coords.x2 + 1;\n                coords.x2 += header.w;\n            }\n        }\n\n#endif\n\n    }\n    /*Post draw when the children are drawn*/\n    else if(mode == LV_DESIGN_DRAW_POST) {\n    }\n\n    return true;\n}\n\n/**\n * Signal function of the image button\n * @param imgbtn pointer to a image button object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_imgbtn_signal(lv_obj_t * imgbtn, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(imgbtn, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    if(sign == LV_SIGNAL_STYLE_CHG) {\n        /* If the style changed then the button was clicked, released etc. so probably the state was\n         * changed as well Set the new image for the new state.*/\n        refr_img(imgbtn);\n    } else if(sign == LV_SIGNAL_CLEANUP) {\n        /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_imgbtn\";\n    }\n\n    return res;\n}\n\nstatic void refr_img(lv_obj_t * imgbtn)\n{\n    lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);\n    lv_btn_state_t state  = lv_imgbtn_get_state(imgbtn);\n    lv_img_header_t header;\n\n#if LV_IMGBTN_TILED == 0\n    const void * src = ext->img_src[state];\n#else\n    const void * src = ext->img_src_mid[state];\n#endif\n\n    lv_res_t info_res;\n    info_res = lv_img_decoder_get_info(src, &header);\n    if(info_res == LV_RES_OK) {\n        ext->act_cf = header.cf;\n#if LV_IMGBTN_TILED == 0\n        lv_obj_set_size(imgbtn, header.w, header.h);\n#else\n        lv_obj_set_height(imgbtn, header.h);\n#endif\n    } else {\n        ext->act_cf = LV_IMG_CF_UNKNOWN;\n    }\n\n    lv_obj_invalidate(imgbtn);\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_kb.c",
    "content": "\n/**\n * @file lv_kb.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_kb.h\"\n#if LV_USE_KB != 0\n\n#include \"libs/lvgl/lv_objx/lv_ta.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_KB_CTRL_BTN_FLAGS (LV_BTNM_CTRL_NO_REPEAT | LV_BTNM_CTRL_CLICK_TRIG)\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic lv_res_t lv_kb_signal(lv_obj_t * kb, lv_signal_t sign, void * param);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\n/* clang-format off */\nstatic const char * kb_map_lc[] = {\"1#\", \"q\", \"w\", \"e\", \"r\", \"t\", \"y\", \"u\", \"i\", \"o\", \"p\", \"Bksp\", \"\\n\",\n                                   \"ABC\", \"a\", \"s\", \"d\", \"f\", \"g\", \"h\", \"j\", \"k\", \"l\", \"Enter\", \"\\n\",\n                                   \"_\", \"-\", \"z\", \"x\", \"c\", \"v\", \"b\", \"n\", \"m\", \".\", \",\", \":\", \"\\n\",\n                                   LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, \" \", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, \"\"};\n\nstatic const lv_btnm_ctrl_t kb_ctrl_lc_map[] = {\n    LV_KB_CTRL_BTN_FLAGS | 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7,\n    LV_KB_CTRL_BTN_FLAGS | 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    LV_KB_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KB_CTRL_BTN_FLAGS | 2};\n\nstatic const char * kb_map_uc[] = {\"1#\", \"Q\", \"W\", \"E\", \"R\", \"T\", \"Y\", \"U\", \"I\", \"O\", \"P\", \"Bksp\", \"\\n\",\n                                   \"abc\", \"A\", \"S\", \"D\", \"F\", \"G\", \"H\", \"J\", \"K\", \"L\", \"Enter\", \"\\n\",\n                                   \"_\", \"-\", \"Z\", \"X\", \"C\", \"V\", \"B\", \"N\", \"M\", \".\", \",\", \":\", \"\\n\",\n                                   LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, \" \", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, \"\"};\n\nstatic const lv_btnm_ctrl_t kb_ctrl_uc_map[] = {\n    LV_KB_CTRL_BTN_FLAGS | 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7,\n    LV_KB_CTRL_BTN_FLAGS | 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    LV_KB_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KB_CTRL_BTN_FLAGS | 2};\n\nstatic const char * kb_map_spec[] = {\"0\", \"1\", \"2\", \"3\", \"4\" ,\"5\", \"6\", \"7\", \"8\", \"9\", \"Bksp\", \"\\n\",\n                                     \"abc\", \"+\", \"-\", \"/\", \"*\", \"=\", \"%\", \"!\", \"?\", \"#\", \"<\", \">\", \"\\n\",\n                                     \"\\\\\",  \"@\", \"$\", \"(\", \")\", \"{\", \"}\", \"[\", \"]\", \";\", \"\\\"\", \"'\", \"\\n\",\n                                     LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, \" \", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, \"\"};\n\nstatic const lv_btnm_ctrl_t kb_ctrl_spec_map[] = {\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, LV_KB_CTRL_BTN_FLAGS | 2,\n    LV_KB_CTRL_BTN_FLAGS | 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    LV_KB_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KB_CTRL_BTN_FLAGS | 2};\n\nstatic const char * kb_map_num[] = {\"1\", \"2\", \"3\", LV_SYMBOL_CLOSE, \"\\n\",\n                                    \"4\", \"5\", \"6\", LV_SYMBOL_OK, \"\\n\",\n                                    \"7\", \"8\", \"9\", \"Bksp\", \"\\n\",\n                                    \"+/-\", \"0\", \".\", LV_SYMBOL_LEFT, LV_SYMBOL_RIGHT, \"\"};\n\nstatic const lv_btnm_ctrl_t kb_ctrl_num_map[] = {\n        1, 1, 1, LV_KB_CTRL_BTN_FLAGS | 2,\n        1, 1, 1, LV_KB_CTRL_BTN_FLAGS | 2,\n        1, 1, 1, 2,\n        1, 1, 1, 1, 1};\n/* clang-format on */\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a keyboard objects\n * @param par pointer to an object, it will be the parent of the new keyboard\n * @param copy pointer to a keyboard object, if not NULL then the new object will be copied from it\n * @return pointer to the created keyboard\n */\nlv_obj_t * lv_kb_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"keyboard create started\");\n\n    /*Create the ancestor of keyboard*/\n    lv_obj_t * new_kb = lv_btnm_create(par, copy);\n    lv_mem_assert(new_kb);\n    if(new_kb == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_kb);\n\n    /*Allocate the keyboard type specific extended data*/\n    lv_kb_ext_t * ext = lv_obj_allocate_ext_attr(new_kb, sizeof(lv_kb_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    /*Initialize the allocated 'ext' */\n\n    ext->ta         = NULL;\n    ext->mode       = LV_KB_MODE_TEXT;\n    ext->cursor_mng = 0;\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_cb(new_kb, lv_kb_signal);\n\n    /*Init the new keyboard keyboard*/\n    if(copy == NULL) {\n        /* Set a size which fits into the parent.\n         * Don't use `par` directly because if the window is created on a page it is moved to the\n         * scrollable so the parent has changed */\n        lv_obj_set_size(new_kb, lv_obj_get_width_fit(lv_obj_get_parent(new_kb)),\n                        lv_obj_get_height_fit(lv_obj_get_parent(new_kb)) / 2);\n\n        lv_obj_align(new_kb, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);\n        lv_obj_set_event_cb(new_kb, lv_kb_def_event_cb);\n        lv_btnm_set_map(new_kb, kb_map_lc);\n        lv_btnm_set_ctrl_map(new_kb, kb_ctrl_lc_map);\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_kb_set_style(new_kb, LV_KB_STYLE_BG, th->style.kb.bg);\n            lv_kb_set_style(new_kb, LV_KB_STYLE_BTN_REL, th->style.kb.btn.rel);\n            lv_kb_set_style(new_kb, LV_KB_STYLE_BTN_PR, th->style.kb.btn.pr);\n            lv_kb_set_style(new_kb, LV_KB_STYLE_BTN_TGL_REL, th->style.kb.btn.tgl_rel);\n            lv_kb_set_style(new_kb, LV_KB_STYLE_BTN_TGL_PR, th->style.kb.btn.tgl_pr);\n            lv_kb_set_style(new_kb, LV_KB_STYLE_BTN_INA, th->style.kb.btn.ina);\n        } else {\n            /*Let the button matrix's styles*/\n        }\n    }\n    /*Copy an existing keyboard*/\n    else {\n        lv_kb_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->ta                = NULL;\n        ext->ta                = copy_ext->ta;\n        ext->mode              = copy_ext->mode;\n        ext->cursor_mng        = copy_ext->cursor_mng;\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_kb);\n    }\n\n    LV_LOG_INFO(\"keyboard created\");\n\n    return new_kb;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Assign a Text Area to the Keyboard. The pressed characters will be put there.\n * @param kb pointer to a Keyboard object\n * @param ta pointer to a Text Area object to write there\n */\nvoid lv_kb_set_ta(lv_obj_t * kb, lv_obj_t * ta)\n{\n    lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);\n    lv_cursor_type_t cur_type;\n\n    /*Hide the cursor of the old Text area if cursor management is enabled*/\n    if(ext->ta && ext->cursor_mng) {\n        cur_type = lv_ta_get_cursor_type(ext->ta);\n        lv_ta_set_cursor_type(ext->ta, cur_type | LV_CURSOR_HIDDEN);\n    }\n\n    ext->ta = ta;\n\n    /*Show the cursor of the new Text area if cursor management is enabled*/\n    if(ext->ta && ext->cursor_mng) {\n        cur_type = lv_ta_get_cursor_type(ext->ta);\n        lv_ta_set_cursor_type(ext->ta, cur_type & (~LV_CURSOR_HIDDEN));\n    }\n}\n\n/**\n * Set a new a mode (text or number map)\n * @param kb pointer to a Keyboard object\n * @param mode the mode from 'lv_kb_mode_t'\n */\nvoid lv_kb_set_mode(lv_obj_t * kb, lv_kb_mode_t mode)\n{\n    lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);\n    if(ext->mode == mode) return;\n\n    ext->mode = mode;\n    if(mode == LV_KB_MODE_TEXT) {\n        lv_btnm_set_map(kb, kb_map_lc);\n        lv_btnm_set_ctrl_map(kb, kb_ctrl_lc_map);\n    } else if(mode == LV_KB_MODE_NUM) {\n        lv_btnm_set_map(kb, kb_map_num);\n        lv_btnm_set_ctrl_map(kb, kb_ctrl_num_map);\n    }\n}\n\n/**\n * Automatically hide or show the cursor of Text Area\n * @param kb pointer to a Keyboard object\n * @param en true: show cursor on the current text area, false: hide cursor\n */\nvoid lv_kb_set_cursor_manage(lv_obj_t * kb, bool en)\n{\n    lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);\n    if(ext->cursor_mng == en) return;\n\n    ext->cursor_mng = en == false ? 0 : 1;\n\n    if(ext->ta) {\n        lv_cursor_type_t cur_type;\n        cur_type = lv_ta_get_cursor_type(ext->ta);\n\n        if(ext->cursor_mng) {\n            lv_ta_set_cursor_type(ext->ta, cur_type & (~LV_CURSOR_HIDDEN));\n        } else {\n            lv_ta_set_cursor_type(ext->ta, cur_type | LV_CURSOR_HIDDEN);\n        }\n    }\n}\n\n/**\n * Set a style of a keyboard\n * @param kb pointer to a keyboard object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_kb_set_style(lv_obj_t * kb, lv_kb_style_t type, const lv_style_t * style)\n{\n    switch(type) {\n        case LV_KB_STYLE_BG: lv_btnm_set_style(kb, LV_BTNM_STYLE_BG, style); break;\n        case LV_KB_STYLE_BTN_REL: lv_btnm_set_style(kb, LV_BTNM_STYLE_BTN_REL, style); break;\n        case LV_KB_STYLE_BTN_PR: lv_btnm_set_style(kb, LV_BTNM_STYLE_BTN_PR, style); break;\n        case LV_KB_STYLE_BTN_TGL_REL: lv_btnm_set_style(kb, LV_BTNM_STYLE_BTN_TGL_REL, style); break;\n        case LV_KB_STYLE_BTN_TGL_PR: lv_btnm_set_style(kb, LV_BTNM_STYLE_BTN_TGL_PR, style); break;\n        case LV_KB_STYLE_BTN_INA: lv_btnm_set_style(kb, LV_BTNM_STYLE_BTN_INA, style); break;\n    }\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Assign a Text Area to the Keyboard. The pressed characters will be put there.\n * @param kb pointer to a Keyboard object\n * @return pointer to the assigned Text Area object\n */\nlv_obj_t * lv_kb_get_ta(const lv_obj_t * kb)\n{\n    lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);\n    return ext->ta;\n}\n\n/**\n * Set a new a mode (text or number map)\n * @param kb pointer to a Keyboard object\n * @return the current mode from 'lv_kb_mode_t'\n */\nlv_kb_mode_t lv_kb_get_mode(const lv_obj_t * kb)\n{\n    lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);\n    return ext->mode;\n}\n\n/**\n * Get the current cursor manage mode.\n * @param kb pointer to a Keyboard object\n * @return true: show cursor on the current text area, false: hide cursor\n */\nbool lv_kb_get_cursor_manage(const lv_obj_t * kb)\n{\n    lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);\n    return ext->cursor_mng == 0 ? false : true;\n}\n\n/**\n * Get a style of a keyboard\n * @param kb pointer to a keyboard object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_kb_get_style(const lv_obj_t * kb, lv_kb_style_t type)\n{\n    const lv_style_t * style = NULL;\n\n    switch(type) {\n        case LV_KB_STYLE_BG: style = lv_btnm_get_style(kb, LV_BTNM_STYLE_BG); break;\n        case LV_KB_STYLE_BTN_REL: style = lv_btnm_get_style(kb, LV_BTNM_STYLE_BTN_REL); break;\n        case LV_KB_STYLE_BTN_PR: style = lv_btnm_get_style(kb, LV_BTNM_STYLE_BTN_PR); break;\n        case LV_KB_STYLE_BTN_TGL_REL: style = lv_btnm_get_style(kb, LV_BTNM_STYLE_BTN_TGL_REL); break;\n        case LV_KB_STYLE_BTN_TGL_PR: style = lv_btnm_get_style(kb, LV_BTNM_STYLE_BTN_TGL_PR); break;\n        case LV_KB_STYLE_BTN_INA: style = lv_btnm_get_style(kb, LV_BTNM_STYLE_BTN_INA); break;\n        default: style = NULL; break;\n    }\n\n    return style;\n}\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Default keyboard event to add characters to the Text area and change the map.\n * If a custom `event_cb` is added to the keyboard this function be called from it to handle the\n * button clicks\n * @param kb pointer to a  keyboard\n * @param event the triggering event\n */\nvoid lv_kb_def_event_cb(lv_obj_t * kb, lv_event_t event)\n{\n    if(event != LV_EVENT_VALUE_CHANGED) return;\n\n    lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);\n    uint16_t btn_id   = lv_btnm_get_active_btn(kb);\n    if(btn_id == LV_BTNM_BTN_NONE) return;\n    if(lv_btnm_get_btn_ctrl(kb, btn_id, LV_BTNM_CTRL_HIDDEN | LV_BTNM_CTRL_INACTIVE)) return;\n    if(lv_btnm_get_btn_ctrl(kb, btn_id, LV_BTNM_CTRL_NO_REPEAT) && event == LV_EVENT_LONG_PRESSED_REPEAT) return;\n\n    const char * txt = lv_btnm_get_active_btn_text(kb);\n    if(txt == NULL) return;\n\n    /*Do the corresponding action according to the text of the button*/\n    if(strcmp(txt, \"abc\") == 0) {\n        lv_btnm_set_map(kb, kb_map_lc);\n        lv_btnm_set_ctrl_map(kb, kb_ctrl_lc_map);\n        return;\n    } else if(strcmp(txt, \"ABC\") == 0) {\n        lv_btnm_set_map(kb, kb_map_uc);\n        lv_btnm_set_ctrl_map(kb, kb_ctrl_uc_map);\n        return;\n    } else if(strcmp(txt, \"1#\") == 0) {\n        lv_btnm_set_map(kb, kb_map_spec);\n        lv_btnm_set_ctrl_map(kb, kb_ctrl_spec_map);\n        return;\n    } else if(strcmp(txt, LV_SYMBOL_CLOSE) == 0) {\n        if(kb->event_cb != lv_kb_def_event_cb) {\n            lv_res_t res = lv_event_send(kb, LV_EVENT_CANCEL, NULL);\n            if(res != LV_RES_OK) return;\n        } else {\n            lv_kb_set_ta(kb, NULL); /*De-assign the text area  to hide it cursor if needed*/\n            lv_obj_del(kb);\n            return;\n        }\n        return;\n    } else if(strcmp(txt, LV_SYMBOL_OK) == 0) {\n        if(kb->event_cb != lv_kb_def_event_cb) {\n            lv_res_t res = lv_event_send(kb, LV_EVENT_APPLY, NULL);\n            if(res != LV_RES_OK) return;\n        } else {\n            lv_kb_set_ta(kb, NULL); /*De-assign the text area to hide it cursor if needed*/\n        }\n        return;\n    }\n\n    /*Add the characters to the text area if set*/\n    if(ext->ta == NULL) return;\n\n    if(strcmp(txt, \"Enter\") == 0)\n        lv_ta_add_char(ext->ta, '\\n');\n    else if(strcmp(txt, LV_SYMBOL_LEFT) == 0)\n        lv_ta_cursor_left(ext->ta);\n    else if(strcmp(txt, LV_SYMBOL_RIGHT) == 0)\n        lv_ta_cursor_right(ext->ta);\n    else if(strcmp(txt, \"Bksp\") == 0)\n        lv_ta_del_char(ext->ta);\n    else if(strcmp(txt, \"+/-\") == 0) {\n        uint16_t cur        = lv_ta_get_cursor_pos(ext->ta);\n        const char * ta_txt = lv_ta_get_text(ext->ta);\n        if(ta_txt[0] == '-') {\n            lv_ta_set_cursor_pos(ext->ta, 1);\n            lv_ta_del_char(ext->ta);\n            lv_ta_add_char(ext->ta, '+');\n            lv_ta_set_cursor_pos(ext->ta, cur);\n        } else if(ta_txt[0] == '+') {\n            lv_ta_set_cursor_pos(ext->ta, 1);\n            lv_ta_del_char(ext->ta);\n            lv_ta_add_char(ext->ta, '-');\n            lv_ta_set_cursor_pos(ext->ta, cur);\n        } else {\n            lv_ta_set_cursor_pos(ext->ta, 0);\n            lv_ta_add_char(ext->ta, '-');\n            lv_ta_set_cursor_pos(ext->ta, cur + 1);\n        }\n    } else {\n        lv_ta_add_text(ext->ta, txt);\n    }\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Signal function of the keyboard\n * @param kb pointer to a keyboard object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_kb_signal(lv_obj_t * kb, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(kb, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    if(sign == LV_SIGNAL_CLEANUP) {\n        /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/\n    } else if(sign == LV_SIGNAL_FOCUS) {\n        lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);\n        /*Show the cursor of the new Text area if cursor management is enabled*/\n        if(ext->ta && ext->cursor_mng) {\n            lv_cursor_type_t cur_type = lv_ta_get_cursor_type(ext->ta);\n            lv_ta_set_cursor_type(ext->ta, cur_type & (~LV_CURSOR_HIDDEN));\n        }\n    } else if(sign == LV_SIGNAL_DEFOCUS) {\n        lv_kb_ext_t * ext = lv_obj_get_ext_attr(kb);\n        /*Show the cursor of the new Text area if cursor management is enabled*/\n        if(ext->ta && ext->cursor_mng) {\n            lv_cursor_type_t cur_type = lv_ta_get_cursor_type(ext->ta);\n            lv_ta_set_cursor_type(ext->ta, cur_type | LV_CURSOR_HIDDEN);\n        }\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_kb\";\n    }\n\n    return res;\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_label.c",
    "content": "/**\n * @file lv_rect.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_label.h\"\n#if LV_USE_LABEL != 0\n\n#include \"libs/lvgl/lv_core/lv_obj.h\"\n#include \"libs/lvgl/lv_core/lv_group.h\"\n#include \"libs/lvgl/lv_misc/lv_color.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n/*Test configurations*/\n#ifndef LV_LABEL_DEF_SCROLL_SPEED\n#define LV_LABEL_DEF_SCROLL_SPEED (25)\n#endif\n\n#define LV_LABEL_DOT_END_INV 0xFFFF\n#define LV_LABEL_HINT_HEIGHT_LIMIT                                                                                     \\\n    1024 /*Enable \"hint\" to buffer info about labels larger than this. (Speed up their drawing)*/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic lv_res_t lv_label_signal(lv_obj_t * label, lv_signal_t sign, void * param);\nstatic bool lv_label_design(lv_obj_t * label, const lv_area_t * mask, lv_design_mode_t mode);\nstatic void lv_label_refr_text(lv_obj_t * label);\nstatic void lv_label_revert_dots(lv_obj_t * label);\n\n#if LV_USE_ANIMATION\nstatic void lv_label_set_offset_x(lv_obj_t * label, lv_coord_t x);\nstatic void lv_label_set_offset_y(lv_obj_t * label, lv_coord_t y);\n#endif\n\nstatic bool lv_label_set_dot_tmp(lv_obj_t * label, char * data, uint16_t len);\nstatic char * lv_label_get_dot_tmp(lv_obj_t * label);\nstatic void lv_label_dot_tmp_free(lv_obj_t * label);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a label objects\n * @param par pointer to an object, it will be the parent of the new label\n * @param copy pointer to a button object, if not NULL then the new object will be copied from it\n * @return pointer to the created button\n */\nlv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"label create started\");\n\n    /*Create a basic object*/\n    lv_obj_t * new_label = lv_obj_create(par, copy);\n    lv_mem_assert(new_label);\n    if(new_label == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_label);\n\n    /*Extend the basic object to a label object*/\n    lv_obj_allocate_ext_attr(new_label, sizeof(lv_label_ext_t));\n\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(new_label);\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    ext->text       = NULL;\n    ext->static_txt = 0;\n    ext->recolor    = 0;\n    ext->body_draw  = 0;\n    ext->align      = LV_LABEL_ALIGN_LEFT;\n    ext->dot_end    = LV_LABEL_DOT_END_INV;\n    ext->long_mode  = LV_LABEL_LONG_EXPAND;\n#if LV_USE_ANIMATION\n    ext->anim_speed = LV_LABEL_DEF_SCROLL_SPEED;\n#endif\n    ext->offset.x = 0;\n    ext->offset.y = 0;\n\n#if LV_LABEL_LONG_TXT_HINT\n    ext->hint.line_start = -1;\n    ext->hint.coord_y    = 0;\n    ext->hint.y          = 0;\n#endif\n\n#if LV_LABEL_TEXT_SEL\n    ext->txt_sel_start = LV_LABEL_TEXT_SEL_OFF;\n    ext->txt_sel_end   = LV_LABEL_TEXT_SEL_OFF;\n#endif\n    ext->dot.tmp_ptr   = NULL;\n    ext->dot_tmp_alloc = 0;\n\n    lv_obj_set_design_cb(new_label, lv_label_design);\n    lv_obj_set_signal_cb(new_label, lv_label_signal);\n\n    /*Init the new label*/\n    if(copy == NULL) {\n        lv_obj_set_click(new_label, false);\n        lv_label_set_long_mode(new_label, LV_LABEL_LONG_EXPAND);\n        lv_label_set_text(new_label, \"Text\");\n        lv_label_set_style(new_label, LV_LABEL_STYLE_MAIN, NULL); /*Inherit parent's style*/\n    }\n    /*Copy 'copy' if not NULL*/\n    else {\n        lv_label_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        lv_label_set_long_mode(new_label, lv_label_get_long_mode(copy));\n        lv_label_set_recolor(new_label, lv_label_get_recolor(copy));\n        lv_label_set_body_draw(new_label, lv_label_get_body_draw(copy));\n        lv_label_set_align(new_label, lv_label_get_align(copy));\n        if(copy_ext->static_txt == 0)\n            lv_label_set_text(new_label, lv_label_get_text(copy));\n        else\n            lv_label_set_static_text(new_label, lv_label_get_text(copy));\n\n        /*In DOT mode save the text byte-to-byte because a '\\0' can be in the middle*/\n        if(copy_ext->long_mode == LV_LABEL_LONG_DOT) {\n            ext->text = lv_mem_realloc(ext->text, lv_mem_get_size(copy_ext->text));\n            lv_mem_assert(ext->text);\n            if(ext->text == NULL) return NULL;\n            memcpy(ext->text, copy_ext->text, lv_mem_get_size(copy_ext->text));\n        }\n\n        if(copy_ext->dot_tmp_alloc && copy_ext->dot.tmp_ptr) {\n            int len = strlen(copy_ext->dot.tmp_ptr);\n            lv_label_set_dot_tmp(new_label, ext->dot.tmp_ptr, len);\n        } else {\n            memcpy(ext->dot.tmp, copy_ext->dot.tmp, sizeof(ext->dot.tmp));\n        }\n        ext->dot_tmp_alloc = copy_ext->dot_tmp_alloc;\n        ext->dot_end       = copy_ext->dot_end;\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_label);\n    }\n\n    LV_LOG_INFO(\"label created\");\n\n    return new_label;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a new text for a label. Memory will be allocated to store the text by the label.\n * @param label pointer to a label object\n * @param text '\\0' terminated character string. NULL to refresh with the current text.\n */\nvoid lv_label_set_text(lv_obj_t * label, const char * text)\n{\n    lv_obj_invalidate(label);\n\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n\n    /*If text is NULL then refresh */\n    if(text == NULL) {\n        lv_label_refr_text(label);\n        return;\n    }\n\n    if(ext->text == text) {\n        /*If set its own text then reallocate it (maybe its size changed)*/\n        ext->text = lv_mem_realloc(ext->text, strlen(ext->text) + 1);\n        lv_mem_assert(ext->text);\n        if(ext->text == NULL) return;\n    } else {\n        /*Allocate space for the new text*/\n        uint32_t len = strlen(text) + 1;\n        if(ext->text != NULL && ext->static_txt == 0) {\n            lv_mem_free(ext->text);\n            ext->text = NULL;\n        }\n\n        ext->text = lv_mem_alloc(len);\n        lv_mem_assert(ext->text);\n        if(ext->text == NULL) return;\n\n        strcpy(ext->text, text);\n        ext->static_txt = 0; /*Now the text is dynamically allocated*/\n    }\n\n    lv_label_refr_text(label);\n}\n\n/**\n * Set a new text for a label from a character array. The array don't has to be '\\0' terminated.\n * Memory will be allocated to store the array by the label.\n * @param label pointer to a label object\n * @param array array of characters or NULL to refresh the label\n * @param size the size of 'array' in bytes\n */\nvoid lv_label_set_array_text(lv_obj_t * label, const char * array, uint16_t size)\n{\n    lv_obj_invalidate(label);\n\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n\n    /*If trying to set its own text or the array is NULL then refresh */\n    if(array == ext->text || array == NULL) {\n        lv_label_refr_text(label);\n        return;\n    }\n\n    /*Allocate space for the new text*/\n    if(ext->text != NULL && ext->static_txt == 0) {\n        lv_mem_free(ext->text);\n        ext->text = NULL;\n    }\n    ext->text = lv_mem_alloc(size + 1);\n    lv_mem_assert(ext->text);\n    if(ext->text == NULL) return;\n\n    memcpy(ext->text, array, size);\n    ext->text[size] = '\\0';\n    ext->static_txt = 0; /*Now the text is dynamically allocated*/\n\n    lv_label_refr_text(label);\n}\n\n/**\n * Set a static text. It will not be saved by the label so the 'text' variable\n * has to be 'alive' while the label exist.\n * @param label pointer to a label object\n * @param text pointer to a text. NULL to refresh with the current text.\n */\nvoid lv_label_set_static_text(lv_obj_t * label, const char * text)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    if(ext->static_txt == 0 && ext->text != NULL) {\n        lv_mem_free(ext->text);\n        ext->text = NULL;\n    }\n\n    if(text != NULL) {\n        ext->static_txt = 1;\n        ext->text       = (char *)text;\n    }\n\n    lv_label_refr_text(label);\n}\n\n/**\n * Set the behavior of the label with longer text then the object size\n * @param label pointer to a label object\n * @param long_mode the new mode from 'lv_label_long_mode' enum.\n *                  In LV_LONG_BREAK/LONG/ROLL the size of the label should be set AFTER this\n * function\n */\nvoid lv_label_set_long_mode(lv_obj_t * label, lv_label_long_mode_t long_mode)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n\n#if LV_USE_ANIMATION\n    /*Delete the old animation (if exists)*/\n    lv_anim_del(label, (lv_anim_exec_xcb_t)lv_obj_set_x);\n    lv_anim_del(label, (lv_anim_exec_xcb_t)lv_obj_set_y);\n    lv_anim_del(label, (lv_anim_exec_xcb_t)lv_label_set_offset_x);\n    lv_anim_del(label, (lv_anim_exec_xcb_t)lv_label_set_offset_y);\n#endif\n    ext->offset.x = 0;\n    ext->offset.y = 0;\n\n    if(long_mode == LV_LABEL_LONG_SROLL || long_mode == LV_LABEL_LONG_SROLL_CIRC || long_mode == LV_LABEL_LONG_CROP)\n        ext->expand = 1;\n    else\n        ext->expand = 0;\n\n    /*Restore the character under the dots*/\n    if(ext->long_mode == LV_LABEL_LONG_DOT && ext->dot_end != LV_LABEL_DOT_END_INV) {\n        lv_label_revert_dots(label);\n    }\n\n    ext->long_mode = long_mode;\n    lv_label_refr_text(label);\n}\n\n/**\n * Set the align of the label (left or center)\n * @param label pointer to a label object\n * @param align 'LV_LABEL_ALIGN_LEFT' or 'LV_LABEL_ALIGN_LEFT'\n */\nvoid lv_label_set_align(lv_obj_t * label, lv_label_align_t align)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    if(ext->align == align) return;\n\n    ext->align = align;\n\n    lv_obj_invalidate(label); /*Enough to invalidate because alignment is only drawing related\n                                 (lv_refr_label_text() not required)*/\n}\n\n/**\n * Enable the recoloring by in-line commands\n * @param label pointer to a label object\n * @param en true: enable recoloring, false: disable\n */\nvoid lv_label_set_recolor(lv_obj_t * label, bool en)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    if(ext->recolor == en) return;\n\n    ext->recolor = en == false ? 0 : 1;\n\n    lv_label_refr_text(label); /*Refresh the text because the potential colo codes in text needs to\n                                  be hided or revealed*/\n}\n\n/**\n * Set the label to draw (or not draw) background specified in its style's body\n * @param label pointer to a label object\n * @param en true: draw body; false: don't draw body\n */\nvoid lv_label_set_body_draw(lv_obj_t * label, bool en)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    if(ext->body_draw == en) return;\n\n    ext->body_draw = en == false ? 0 : 1;\n\n    lv_obj_refresh_ext_draw_pad(label);\n\n    lv_obj_invalidate(label);\n}\n\n/**\n * Set the label's animation speed in LV_LABEL_LONG_SROLL/SCROLL_CIRC modes\n * @param label pointer to a label object\n * @param anim_speed speed of animation in px/sec unit\n */\nvoid lv_label_set_anim_speed(lv_obj_t * label, uint16_t anim_speed)\n{\n#if LV_USE_ANIMATION\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    if(ext->anim_speed == anim_speed) return;\n\n    ext->anim_speed = anim_speed;\n\n    if(ext->long_mode == LV_LABEL_LONG_SROLL || ext->long_mode == LV_LABEL_LONG_SROLL_CIRC) {\n        lv_label_refr_text(label);\n    }\n#else\n    (void)label;      /*Unused*/\n    (void)anim_speed; /*Unused*/\n#endif\n}\n\nvoid lv_label_set_text_sel_start(lv_obj_t * label, uint16_t index)\n{\n#if LV_LABEL_TEXT_SEL\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    ext->txt_sel_start   = index;\n    lv_obj_invalidate(label);\n#else\n    (void)label;    /*Unused*/\n    (void)index;    /*Unused*/\n#endif\n}\n\nvoid lv_label_set_text_sel_end(lv_obj_t * label, uint16_t index)\n{\n#if LV_LABEL_TEXT_SEL\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    ext->txt_sel_end     = index;\n    lv_obj_invalidate(label);\n#else\n    (void)label;    /*Unused*/\n    (void)index;    /*Unused*/\n#endif\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the text of a label\n * @param label pointer to a label object\n * @return the text of the label\n */\nchar * lv_label_get_text(const lv_obj_t * label)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n\n    return ext->text;\n}\n\n/**\n * Get the long mode of a label\n * @param label pointer to a label object\n * @return the long mode\n */\nlv_label_long_mode_t lv_label_get_long_mode(const lv_obj_t * label)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    return ext->long_mode;\n}\n\n/**\n * Get the align attribute\n * @param label pointer to a label object\n * @return LV_LABEL_ALIGN_LEFT or LV_LABEL_ALIGN_CENTER\n */\nlv_label_align_t lv_label_get_align(const lv_obj_t * label)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    return ext->align;\n}\n\n/**\n * Get the recoloring attribute\n * @param label pointer to a label object\n * @return true: recoloring is enabled, false: disable\n */\nbool lv_label_get_recolor(const lv_obj_t * label)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    return ext->recolor == 0 ? false : true;\n}\n\n/**\n * Get the body draw attribute\n * @param label pointer to a label object\n * @return true: draw body; false: don't draw body\n */\nbool lv_label_get_body_draw(const lv_obj_t * label)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    return ext->body_draw == 0 ? false : true;\n}\n\n/**\n * Get the label's animation speed in LV_LABEL_LONG_ROLL and SCROLL modes\n * @param label pointer to a label object\n * @return speed of animation in px/sec unit\n */\nuint16_t lv_label_get_anim_speed(const lv_obj_t * label)\n{\n#if LV_USE_ANIMATION\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    return ext->anim_speed;\n#else\n    (void)label;      /*Unused*/\n    return 0;\n#endif\n}\n\n/**\n * Get the relative x and y coordinates of a letter\n * @param label pointer to a label object\n * @param index index of the letter [0 ... text length]. Expressed in character index, not byte\n * index (different in UTF-8)\n * @param pos store the result here (E.g. index = 0 gives 0;0 coordinates)\n */\nvoid lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t * pos)\n{\n    const char * txt         = lv_label_get_text(label);\n    lv_label_ext_t * ext     = lv_obj_get_ext_attr(label);\n    uint32_t line_start      = 0;\n    uint32_t new_line_start  = 0;\n    lv_coord_t max_w         = lv_obj_get_width(label);\n    const lv_style_t * style = lv_obj_get_style(label);\n    const lv_font_t * font   = style->text.font;\n    uint8_t letter_height    = lv_font_get_line_height(font);\n    lv_coord_t y             = 0;\n    lv_txt_flag_t flag       = LV_TXT_FLAG_NONE;\n\n    if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;\n    if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;\n    if(ext->align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER;\n\n    /*If the width will be expanded  the set the max length to very big */\n    if(ext->long_mode == LV_LABEL_LONG_EXPAND) {\n        max_w = LV_COORD_MAX;\n    }\n\n    index = lv_txt_encoded_get_byte_id(txt, index);\n\n    /*Search the line of the index letter */;\n    while(txt[new_line_start] != '\\0') {\n        new_line_start += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag);\n        if(index < new_line_start || txt[new_line_start] == '\\0')\n            break; /*The line of 'index' letter begins at 'line_start'*/\n\n        y += letter_height + style->text.line_space;\n        line_start = new_line_start;\n    }\n\n    /*If the last character is line break then go to the next line*/\n    if(index > 0) {\n        if((txt[index - 1] == '\\n' || txt[index - 1] == '\\r') && txt[index] == '\\0') {\n            y += letter_height + style->text.line_space;\n            line_start = index;\n        }\n    }\n\n    /*Calculate the x coordinate*/\n    lv_coord_t x = lv_txt_get_width(&txt[line_start], index - line_start, font, style->text.letter_space, flag);\n\n    if(index != line_start) x += style->text.letter_space;\n\n    if(ext->align == LV_LABEL_ALIGN_CENTER) {\n        lv_coord_t line_w;\n        line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);\n        x += lv_obj_get_width(label) / 2 - line_w / 2;\n\n    } else if(ext->align == LV_LABEL_ALIGN_RIGHT) {\n        lv_coord_t line_w;\n        line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);\n\n        x += lv_obj_get_width(label) - line_w;\n    }\n    pos->x = x;\n    pos->y = y;\n}\n\n/**\n * Get the index of letter on a relative point of a label\n * @param label pointer to label object\n * @param pos pointer to point with coordinates on a the label\n * @return the index of the letter on the 'pos_p' point (E.g. on 0;0 is the 0. letter)\n * Expressed in character index and not byte index (different in UTF-8)\n */\nuint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos)\n{\n    const char * txt         = lv_label_get_text(label);\n    lv_label_ext_t * ext     = lv_obj_get_ext_attr(label);\n    uint32_t line_start      = 0;\n    uint32_t new_line_start  = 0;\n    lv_coord_t max_w         = lv_obj_get_width(label);\n    const lv_style_t * style = lv_obj_get_style(label);\n    const lv_font_t * font   = style->text.font;\n    uint8_t letter_height    = lv_font_get_line_height(font);\n    lv_coord_t y             = 0;\n    lv_txt_flag_t flag       = LV_TXT_FLAG_NONE;\n\n    if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;\n    if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;\n    if(ext->align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER;\n\n    /*If the width will be expanded set the max length to very big */\n    if(ext->long_mode == LV_LABEL_LONG_EXPAND) {\n        max_w = LV_COORD_MAX;\n    }\n\n    /*Search the line of the index letter */;\n    while(txt[line_start] != '\\0') {\n        new_line_start += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag);\n\n        if(pos->y <= y + letter_height) break; /*The line is found (stored in 'line_start')*/\n        y += letter_height + style->text.line_space;\n\n        line_start = new_line_start;\n    }\n\n    /*Calculate the x coordinate*/\n    lv_coord_t x = 0;\n    if(ext->align == LV_LABEL_ALIGN_CENTER) {\n        lv_coord_t line_w;\n        line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);\n        x += lv_obj_get_width(label) / 2 - line_w / 2;\n    }\n\n    lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT;\n\n    uint32_t i         = line_start;\n    uint32_t i_current = i;\n    uint32_t letter;\n    uint32_t letter_next;\n\n    if(new_line_start > 0) {\n        while(i <= new_line_start - 1) {\n            /* Get the current letter.\n             * Be careful 'i' already points to the next character*/\n            letter = lv_txt_encoded_next(txt, &i);\n\n            /*Get the next letter too for kerning*/\n            letter_next = lv_txt_encoded_next(&txt[i], NULL);\n\n            /*Handle the recolor command*/\n            if((flag & LV_TXT_FLAG_RECOLOR) != 0) {\n                if(lv_txt_is_cmd(&cmd_state, txt[i]) != false) {\n                    continue; /*Skip the letter is it is part of a command*/\n                }\n            }\n\n            x += lv_font_get_glyph_width(font, letter, letter_next);\n            if(pos->x < x) {\n                i = i_current;\n                break;\n            }\n            x += style->text.letter_space;\n            i_current = i;\n        }\n    }\n\n    return lv_encoded_get_char_id(txt, i);\n}\n\n/**\n * @brief Get the selection start index.\n * @param label pointer to a label object.\n * @return selection start index. `LV_LABEL_TXT_SEL_OFF` if nothing is selected.\n */\nuint16_t lv_label_get_text_sel_start(const lv_obj_t * label)\n{\n#if LV_LABEL_TEXT_SEL\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    return ext->txt_sel_start;\n\n#else\n    (void)label;    /*Unused*/\n    return LV_LABEL_TEXT_SEL_OFF;\n#endif\n}\n\n/**\n * @brief Get the selection end index.\n * @param label pointer to a label object.\n * @return selection end index. `LV_LABEL_TXT_SEL_OFF` if nothing is selected.\n */\nuint16_t lv_label_get_text_sel_end(const lv_obj_t * label)\n{\n#if LV_LABEL_TEXT_SEL\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    return ext->txt_sel_end;\n#else\n    (void)label; /*Unused*/\n    return LV_LABEL_TEXT_SEL_OFF;\n#endif\n}\n\n/**\n * Check if a character is drawn under a point.\n * @param label Label object\n * @param pos Point to check for characte under\n * @return whether a character is drawn under the point\n */\nbool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos)\n{\n    const char * txt         = lv_label_get_text(label);\n    lv_label_ext_t * ext     = lv_obj_get_ext_attr(label);\n    uint32_t line_start      = 0;\n    uint32_t new_line_start  = 0;\n    lv_coord_t max_w         = lv_obj_get_width(label);\n    const lv_style_t * style = lv_obj_get_style(label);\n    const lv_font_t * font   = style->text.font;\n    uint8_t letter_height    = lv_font_get_line_height(font);\n    lv_coord_t y             = 0;\n    lv_txt_flag_t flag       = LV_TXT_FLAG_NONE;\n\n    if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;\n    if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;\n    if(ext->align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER;\n\n    /*If the width will be expanded set the max length to very big */\n    if(ext->long_mode == LV_LABEL_LONG_EXPAND) {\n        max_w = LV_COORD_MAX;\n    }\n\n    /*Search the line of the index letter */;\n    while(txt[line_start] != '\\0') {\n        new_line_start += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag);\n\n        if(pos->y <= y + letter_height) break; /*The line is found (stored in 'line_start')*/\n        y += letter_height + style->text.line_space;\n\n        line_start = new_line_start;\n    }\n\n    /*Calculate the x coordinate*/\n    lv_coord_t x      = 0;\n    lv_coord_t last_x = 0;\n    if(ext->align == LV_LABEL_ALIGN_CENTER) {\n        lv_coord_t line_w;\n        line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag);\n        x += lv_obj_get_width(label) / 2 - line_w / 2;\n    }\n\n    lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT;\n\n    uint32_t i           = line_start;\n    uint32_t i_current   = i;\n    uint32_t letter      = '\\0';\n    uint32_t letter_next = '\\0';\n\n    if(new_line_start > 0) {\n        while(i <= new_line_start - 1) {\n            /* Get the current letter\n             * Be careful 'i' already points to the next character */\n            letter = lv_txt_encoded_next(txt, &i);\n\n            /*Get the next letter for kerning*/\n            letter_next = lv_txt_encoded_next(&txt[i], NULL);\n\n            /*Handle the recolor command*/\n            if((flag & LV_TXT_FLAG_RECOLOR) != 0) {\n                if(lv_txt_is_cmd(&cmd_state, txt[i]) != false) {\n                    continue; /*Skip the letter is it is part of a command*/\n                }\n            }\n            last_x = x;\n            x += lv_font_get_glyph_width(font, letter, letter_next);\n            if(pos->x < x) {\n                i = i_current;\n                break;\n            }\n            x += style->text.letter_space;\n            i_current = i;\n        }\n    }\n\n    int32_t max_diff = lv_font_get_glyph_width(font, letter, letter_next) + style->text.letter_space + 1;\n    return (pos->x >= (last_x - style->text.letter_space) && pos->x <= (last_x + max_diff));\n}\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Insert a text to the label. The label text can not be static.\n * @param label pointer to a label object\n * @param pos character index to insert. Expressed in character index and not byte index (Different\n * in UTF-8) 0: before first char. LV_LABEL_POS_LAST: after last char.\n * @param txt pointer to the text to insert\n */\nvoid lv_label_ins_text(lv_obj_t * label, uint32_t pos, const char * txt)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n\n    /*Can not append to static text*/\n    if(ext->static_txt != 0) return;\n\n    lv_obj_invalidate(label);\n\n    /*Allocate space for the new text*/\n    uint32_t old_len = strlen(ext->text);\n    uint32_t ins_len = strlen(txt);\n    uint32_t new_len = ins_len + old_len;\n    ext->text        = lv_mem_realloc(ext->text, new_len + 1);\n    lv_mem_assert(ext->text);\n    if(ext->text == NULL) return;\n\n    if(pos == LV_LABEL_POS_LAST) {\n        pos = lv_txt_get_encoded_length(ext->text);\n    }\n\n    lv_txt_ins(ext->text, pos, txt);\n\n    lv_label_refr_text(label);\n}\n\n/**\n * Delete characters from a label. The label text can not be static.\n * @param label pointer to a label object\n * @param pos character index to insert. Expressed in character index and not byte index (Different\n * in UTF-8) 0: before first char.\n * @param cnt number of characters to cut\n */\nvoid lv_label_cut_text(lv_obj_t * label, uint32_t pos, uint32_t cnt)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n\n    /*Can not append to static text*/\n    if(ext->static_txt != 0) return;\n\n    lv_obj_invalidate(label);\n\n    char * label_txt = lv_label_get_text(label);\n    /*Delete the characters*/\n    lv_txt_cut(label_txt, pos, cnt);\n\n    /*Refresh the label*/\n    lv_label_refr_text(label);\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the labels\n * @param label pointer to a label object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_label_design(lv_obj_t * label, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    /* A label never covers an area */\n    if(mode == LV_DESIGN_COVER_CHK)\n        return false;\n    else if(mode == LV_DESIGN_DRAW_MAIN) {\n        lv_area_t coords;\n        const lv_style_t * style = lv_obj_get_style(label);\n        lv_opa_t opa_scale       = lv_obj_get_opa_scale(label);\n        lv_obj_get_coords(label, &coords);\n\n#if LV_USE_GROUP\n        lv_group_t * g = lv_obj_get_group(label);\n        if(lv_group_get_focused(g) == label) {\n            lv_draw_rect(&coords, mask, style, opa_scale);\n        }\n#endif\n\n        lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n\n        if(ext->body_draw) {\n            lv_area_t bg;\n            lv_obj_get_coords(label, &bg);\n            bg.x1 -= style->body.padding.left;\n            bg.x2 += style->body.padding.right;\n            bg.y1 -= style->body.padding.top;\n            bg.y2 += style->body.padding.bottom;\n\n            lv_draw_rect(&bg, mask, style, lv_obj_get_opa_scale(label));\n        }\n\n        /*TEST: draw a background for the label*/\n        // lv_draw_rect(&label->coords, mask, &lv_style_plain_color, LV_OPA_COVER);\n\n        lv_txt_flag_t flag = LV_TXT_FLAG_NONE;\n        if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;\n        if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;\n        if(ext->align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER;\n        if(ext->align == LV_LABEL_ALIGN_RIGHT) flag |= LV_TXT_FLAG_RIGHT;\n\n        /* In ROLL mode the CENTER and RIGHT are pointless so remove them.\n         * (In addition they will result mis-alignment is this case)*/\n        if((ext->long_mode == LV_LABEL_LONG_SROLL || ext->long_mode == LV_LABEL_LONG_SROLL_CIRC) &&\n           (ext->align == LV_LABEL_ALIGN_CENTER || ext->align == LV_LABEL_ALIGN_RIGHT)) {\n            lv_point_t size;\n            lv_txt_get_size(&size, ext->text, style->text.font, style->text.letter_space, style->text.line_space,\n                            LV_COORD_MAX, flag);\n            if(size.x > lv_obj_get_width(label)) {\n                flag &= ~LV_TXT_FLAG_RIGHT;\n                flag &= ~LV_TXT_FLAG_CENTER;\n            }\n        }\n#if LV_LABEL_LONG_TXT_HINT\n        lv_draw_label_hint_t * hint = &ext->hint;\n        if(ext->long_mode == LV_LABEL_LONG_SROLL_CIRC || lv_obj_get_height(label) < LV_LABEL_HINT_HEIGHT_LIMIT)\n            hint = NULL;\n\n#else\n        /*Just for compatibility*/\n        lv_draw_label_hint_t * hint = NULL;\n#endif\n        lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ext->offset,\n                              lv_label_get_text_sel_start(label), lv_label_get_text_sel_end(label), hint);\n\n\n        if(ext->long_mode == LV_LABEL_LONG_SROLL_CIRC) {\n            lv_point_t size;\n            lv_txt_get_size(&size, ext->text, style->text.font, style->text.letter_space, style->text.line_space,\n                            LV_COORD_MAX, flag);\n\n            lv_point_t ofs;\n\n            /*Draw the text again next to the original to make an circular effect */\n            if(size.x > lv_obj_get_width(label)) {\n                ofs.x = ext->offset.x + size.x +\n                        lv_font_get_glyph_width(style->text.font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT;\n                ofs.y = ext->offset.y;\n\n                lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs,\n                              lv_label_get_text_sel_start(label), lv_label_get_text_sel_end(label), NULL);\n            }\n\n            /*Draw the text again below the original to make an circular effect */\n            if(size.y > lv_obj_get_height(label)) {\n                ofs.x = ext->offset.x;\n                ofs.y = ext->offset.y + size.y + lv_font_get_line_height(style->text.font);\n                lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs,\n                              lv_label_get_text_sel_start(label), lv_label_get_text_sel_end(label), NULL);\n            }\n        }\n    }\n    return true;\n}\n\n/**\n * Signal function of the label\n * @param label pointer to a label object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_label_signal(lv_obj_t * label, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(label, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    if(sign == LV_SIGNAL_CLEANUP) {\n        if(ext->static_txt == 0) {\n            lv_mem_free(ext->text);\n            ext->text = NULL;\n        }\n        lv_label_dot_tmp_free(label);\n    } else if(sign == LV_SIGNAL_STYLE_CHG) {\n        /*Revert dots for proper refresh*/\n        lv_label_revert_dots(label);\n\n        lv_label_refr_text(label);\n    } else if(sign == LV_SIGNAL_CORD_CHG) {\n        if(lv_area_get_width(&label->coords) != lv_area_get_width(param) ||\n           lv_area_get_height(&label->coords) != lv_area_get_height(param)) {\n            lv_label_revert_dots(label);\n            lv_label_refr_text(label);\n        }\n    } else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {\n        if(ext->body_draw) {\n            const lv_style_t * style = lv_label_get_style(label, LV_LABEL_STYLE_MAIN);\n\n            label->ext_draw_pad = LV_MATH_MAX(label->ext_draw_pad, style->body.padding.left);\n            label->ext_draw_pad = LV_MATH_MAX(label->ext_draw_pad, style->body.padding.right);\n            label->ext_draw_pad = LV_MATH_MAX(label->ext_draw_pad, style->body.padding.top);\n            label->ext_draw_pad = LV_MATH_MAX(label->ext_draw_pad, style->body.padding.bottom);\n        }\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_label\";\n    }\n\n    return res;\n}\n\n/**\n * Refresh the label with its text stored in its extended data\n * @param label pointer to a label object\n */\nstatic void lv_label_refr_text(lv_obj_t * label)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n\n    if(ext->text == NULL) return;\n#if LV_LABEL_LONG_TXT_HINT\n    ext->hint.line_start = -1; /*The hint is invalid if the text changes*/\n#endif\n\n    lv_coord_t max_w         = lv_obj_get_width(label);\n    const lv_style_t * style = lv_obj_get_style(label);\n    const lv_font_t * font   = style->text.font;\n\n    /*If the width will be expanded set the max length to very big */\n    if(ext->long_mode == LV_LABEL_LONG_EXPAND) {\n        max_w = LV_COORD_MAX;\n    }\n\n    /*Calc. the height and longest line*/\n    lv_point_t size;\n    lv_txt_flag_t flag = LV_TXT_FLAG_NONE;\n    if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR;\n    if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND;\n    lv_txt_get_size(&size, ext->text, font, style->text.letter_space, style->text.line_space, max_w, flag);\n\n    /*Set the full size in expand mode*/\n    if(ext->long_mode == LV_LABEL_LONG_EXPAND) {\n        lv_obj_set_size(label, size.x, size.y);\n    }\n    /*In roll mode keep the size but start offset animations*/\n    else if(ext->long_mode == LV_LABEL_LONG_SROLL) {\n#if LV_USE_ANIMATION\n        lv_anim_t anim;\n        anim.var      = label;\n        anim.repeat   = 1;\n        anim.playback = 1;\n        anim.start    = 0;\n        anim.ready_cb = NULL;\n        anim.path_cb  = lv_anim_path_linear;\n        anim.playback_pause =\n            (((lv_font_get_glyph_width(style->text.font, ' ', ' ') + style->text.letter_space) * 1000) /\n             ext->anim_speed) *\n            LV_LABEL_WAIT_CHAR_COUNT;\n        anim.repeat_pause = anim.playback_pause;\n        anim.act_time     = -anim.playback_pause;\n\n        bool hor_anim = false;\n        if(size.x > lv_obj_get_width(label)) {\n            anim.end     = lv_obj_get_width(label) - size.x;\n            anim.exec_cb = (lv_anim_exec_xcb_t)lv_label_set_offset_x;\n            anim.time    = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);\n            lv_anim_create(&anim);\n            hor_anim = true;\n        } else {\n            /*Delete the offset animation if not required*/\n            lv_anim_del(label, (lv_anim_exec_xcb_t)lv_label_set_offset_x);\n            ext->offset.x = 0;\n        }\n\n        if(size.y > lv_obj_get_height(label) && hor_anim == false) {\n            anim.end     = lv_obj_get_height(label) - size.y - (lv_font_get_line_height(font));\n            anim.exec_cb = (lv_anim_exec_xcb_t)lv_label_set_offset_y;\n\n            anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);\n            lv_anim_create(&anim);\n        } else {\n            /*Delete the offset animation if not required*/\n            lv_anim_del(label, (lv_anim_exec_xcb_t)lv_label_set_offset_y);\n            ext->offset.y = 0;\n        }\n#endif\n    }\n    /*In roll inf. mode keep the size but start offset animations*/\n    else if(ext->long_mode == LV_LABEL_LONG_SROLL_CIRC) {\n#if LV_USE_ANIMATION\n        lv_anim_t anim;\n        anim.var      = label;\n        anim.repeat   = 1;\n        anim.playback = 0;\n        anim.start    = 0;\n        anim.act_time = -(((lv_font_get_glyph_width(style->text.font, ' ', ' ') + style->text.letter_space) * 1000) /\n                          ext->anim_speed) *\n                        LV_LABEL_WAIT_CHAR_COUNT;\n        anim.ready_cb       = NULL;\n        anim.path_cb        = lv_anim_path_linear;\n        anim.playback_pause = 0;\n        anim.repeat_pause   = 0;\n\n        bool hor_anim = false;\n        if(size.x > lv_obj_get_width(label)) {\n            anim.end     = -size.x - lv_font_get_glyph_width(font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT;\n            anim.exec_cb = (lv_anim_exec_xcb_t)lv_label_set_offset_x;\n            anim.time    = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);\n            lv_anim_create(&anim);\n            hor_anim = true;\n        } else {\n            /*Delete the offset animation if not required*/\n            lv_anim_del(label, (lv_anim_exec_xcb_t)lv_label_set_offset_x);\n            ext->offset.x = 0;\n        }\n\n        if(size.y > lv_obj_get_height(label) && hor_anim == false) {\n            anim.end     = -size.y - (lv_font_get_line_height(font));\n            anim.exec_cb = (lv_anim_exec_xcb_t)lv_label_set_offset_y;\n            anim.time    = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);\n            lv_anim_create(&anim);\n        } else {\n            /*Delete the offset animation if not required*/\n            lv_anim_del(label, (lv_anim_exec_xcb_t)lv_label_set_offset_y);\n            ext->offset.y = 0;\n        }\n#endif\n    } else if(ext->long_mode == LV_LABEL_LONG_DOT) {\n        if(size.y <= lv_obj_get_height(label)) { /*No dots are required, the text is short enough*/\n            ext->dot_end = LV_LABEL_DOT_END_INV;\n        } else if(lv_txt_get_encoded_length(ext->text) <= LV_LABEL_DOT_NUM) { /*Don't turn to dots all the characters*/\n            ext->dot_end = LV_LABEL_DOT_END_INV;\n        } else {\n            lv_point_t p;\n            p.x = lv_obj_get_width(label) -\n                  (lv_font_get_glyph_width(style->text.font, '.', '.') + style->text.letter_space) *\n                      LV_LABEL_DOT_NUM; /*Shrink with dots*/\n            p.y = lv_obj_get_height(label);\n            p.y -= p.y %\n                   (lv_font_get_line_height(style->text.font) + style->text.line_space); /*Round down to the last line*/\n            p.y -= style->text.line_space;                                               /*Trim the last line space*/\n            uint32_t letter_id = lv_label_get_letter_on(label, &p);\n\n            /*Save letters under the dots and replace them with dots*/\n            uint32_t i;\n            uint32_t byte_id     = lv_txt_encoded_get_byte_id(ext->text, letter_id);\n            uint32_t byte_id_ori = byte_id;\n            uint8_t len          = 0;\n            for(i = 0; i <= LV_LABEL_DOT_NUM; i++) {\n                len += lv_txt_encoded_size(&ext->text[byte_id]);\n                lv_txt_encoded_next(ext->text, &byte_id);\n            }\n\n            if(lv_label_set_dot_tmp(label, &ext->text[byte_id_ori], len)) {\n                for(i = 0; i < LV_LABEL_DOT_NUM; i++) {\n                    ext->text[byte_id_ori + i] = '.';\n                }\n                ext->text[byte_id_ori + LV_LABEL_DOT_NUM] = '\\0';\n                ext->dot_end                              = letter_id + LV_LABEL_DOT_NUM;\n            }\n        }\n    }\n    /*In break mode only the height can change*/\n    else if(ext->long_mode == LV_LABEL_LONG_BREAK) {\n        lv_obj_set_height(label, size.y);\n    }\n    /*Do not set the size in Clip mode*/\n    else if(ext->long_mode == LV_LABEL_LONG_CROP) {\n        /*Do nothing*/\n    }\n\n    lv_obj_invalidate(label);\n}\n\nstatic void lv_label_revert_dots(lv_obj_t * label)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    if(ext->long_mode != LV_LABEL_LONG_DOT) return;\n    if(ext->dot_end == LV_LABEL_DOT_END_INV) return;\n    uint32_t letter_i = ext->dot_end - LV_LABEL_DOT_NUM;\n    uint32_t byte_i   = lv_txt_encoded_get_byte_id(ext->text, letter_i);\n\n    /*Restore the characters*/\n    uint8_t i      = 0;\n    char * dot_tmp = lv_label_get_dot_tmp(label);\n    while(ext->text[byte_i + i] != '\\0') {\n        ext->text[byte_i + i] = dot_tmp[i];\n        i++;\n    }\n    ext->text[byte_i + i] = dot_tmp[i];\n    lv_label_dot_tmp_free(label);\n\n    ext->dot_end = LV_LABEL_DOT_END_INV;\n}\n\n#if LV_USE_ANIMATION\nstatic void lv_label_set_offset_x(lv_obj_t * label, lv_coord_t x)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    ext->offset.x        = x;\n    lv_obj_invalidate(label);\n}\n\nstatic void lv_label_set_offset_y(lv_obj_t * label, lv_coord_t y)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    ext->offset.y        = y;\n    lv_obj_invalidate(label);\n}\n#endif\n\n/**\n * Store `len` characters from `data`. Allocates space if necessary.\n *\n * @param label pointer to label object\n * @param len Number of characters to store.\n * @return true on success.\n */\nstatic bool lv_label_set_dot_tmp(lv_obj_t * label, char * data, uint16_t len)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    lv_label_dot_tmp_free(label); /* Deallocate any existing space */\n    if(len > sizeof(char *)) {\n        /* Memory needs to be allocated. Allocates an additional byte\n         * for a NULL-terminator so it can be copied. */\n        ext->dot.tmp_ptr = lv_mem_alloc(len + 1);\n        if(ext->dot.tmp_ptr == NULL) {\n            LV_LOG_ERROR(\"Failed to allocate memory for dot_tmp_ptr\");\n            return false;\n        }\n        memcpy(ext->dot.tmp_ptr, data, len);\n        ext->dot.tmp_ptr[len] = '\\0';\n        ext->dot_tmp_alloc    = true;\n    } else {\n        /* Characters can be directly stored in object */\n        ext->dot_tmp_alloc = false;\n        memcpy(ext->dot.tmp, data, len);\n    }\n    return true;\n}\n\n/**\n * Get the stored dot_tmp characters\n * @param label pointer to label object\n * @return char pointer to a stored characters. Is *not* necessarily NULL-terminated.\n */\nstatic char * lv_label_get_dot_tmp(lv_obj_t * label)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    if(ext->dot_tmp_alloc) {\n        return ext->dot.tmp_ptr;\n    } else {\n        return ext->dot.tmp;\n    }\n}\n\n/**\n * Free the dot_tmp_ptr field if it was previously allocated.\n * Always clears the field\n * @param label pointer to label object.\n */\nstatic void lv_label_dot_tmp_free(lv_obj_t * label)\n{\n    lv_label_ext_t * ext = lv_obj_get_ext_attr(label);\n    if(ext->dot_tmp_alloc && ext->dot.tmp_ptr) {\n        lv_mem_free(ext->dot.tmp_ptr);\n    }\n    ext->dot_tmp_alloc = false;\n    ext->dot.tmp_ptr   = NULL;\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_led.c",
    "content": "/**\n * @file lv_led.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_led.h\"\n#if LV_USE_LED != 0\n\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_LED_WIDTH_DEF (LV_DPI / 3)\n#define LV_LED_HEIGHT_DEF (LV_DPI / 3)\n#define LV_LED_BRIGHT_OFF 100\n#define LV_LED_BRIGHT_ON 255\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_led_design(lv_obj_t * led, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_led_signal(lv_obj_t * led, lv_signal_t sign, void * param);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_design_cb_t ancestor_design_f;\nstatic lv_signal_cb_t ancestor_signal;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a led objects\n * @param par pointer to an object, it will be the parent of the new led\n * @param copy pointer to a led object, if not NULL then the new object will be copied from it\n * @return pointer to the created led\n */\nlv_obj_t * lv_led_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"led create started\");\n\n    /*Create the ancestor basic object*/\n    lv_obj_t * new_led = lv_obj_create(par, copy);\n    lv_mem_assert(new_led);\n    if(new_led == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_led);\n    if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_cb(new_led);\n\n    /*Allocate the object type specific extended data*/\n    lv_led_ext_t * ext = lv_obj_allocate_ext_attr(new_led, sizeof(lv_led_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    ext->bright = LV_LED_BRIGHT_ON;\n\n    lv_obj_set_signal_cb(new_led, lv_led_signal);\n    lv_obj_set_design_cb(new_led, lv_led_design);\n\n    /*Init the new led object*/\n    if(copy == NULL) {\n        lv_obj_set_size(new_led, LV_LED_WIDTH_DEF, LV_LED_HEIGHT_DEF);\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_led_set_style(new_led, LV_LED_STYLE_MAIN, th->style.led);\n        } else {\n            lv_led_set_style(new_led, LV_LED_STYLE_MAIN, &lv_style_pretty_color);\n        }\n    }\n    /*Copy an existing object*/\n    else {\n        lv_led_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->bright             = copy_ext->bright;\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_led);\n    }\n\n    LV_LOG_INFO(\"led created\");\n\n    return new_led;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the brightness of a LED object\n * @param led pointer to a LED object\n * @param bright 0 (max. dark) ... 255 (max. light)\n */\nvoid lv_led_set_bright(lv_obj_t * led, uint8_t bright)\n{\n    /*Set the brightness*/\n    lv_led_ext_t * ext = lv_obj_get_ext_attr(led);\n    if(ext->bright == bright) return;\n\n    ext->bright = bright;\n\n    /*Invalidate the object there fore it will be redrawn*/\n    lv_obj_invalidate(led);\n}\n\n/**\n * Light on a LED\n * @param led pointer to a LED object\n */\nvoid lv_led_on(lv_obj_t * led)\n{\n    lv_led_set_bright(led, LV_LED_BRIGHT_ON);\n}\n\n/**\n * Light off a LED\n * @param led pointer to a LED object\n */\nvoid lv_led_off(lv_obj_t * led)\n{\n    lv_led_set_bright(led, LV_LED_BRIGHT_OFF);\n}\n\n/**\n * Toggle the state of a LED\n * @param led pointer to a LED object\n */\nvoid lv_led_toggle(lv_obj_t * led)\n{\n    uint8_t bright = lv_led_get_bright(led);\n    if(bright > (LV_LED_BRIGHT_OFF + LV_LED_BRIGHT_ON) >> 1)\n        lv_led_off(led);\n    else\n        lv_led_on(led);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the brightness of a LEd object\n * @param led pointer to LED object\n * @return bright 0 (max. dark) ... 255 (max. light)\n */\nuint8_t lv_led_get_bright(const lv_obj_t * led)\n{\n    lv_led_ext_t * ext = lv_obj_get_ext_attr(led);\n    return ext->bright;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the leds\n * @param led pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_led_design(lv_obj_t * led, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    if(mode == LV_DESIGN_COVER_CHK) {\n        /*Return false if the object is not covers the mask area*/\n        return ancestor_design_f(led, mask, mode);\n    } else if(mode == LV_DESIGN_DRAW_MAIN) {\n        /*Make darker colors in a temporary style according to the brightness*/\n        lv_led_ext_t * ext       = lv_obj_get_ext_attr(led);\n        const lv_style_t * style = lv_obj_get_style(led);\n\n        /* Store the real pointer because of 'lv_group'\n         * If the object is in focus 'lv_obj_get_style()' will give a pointer to tmp style\n         * and to the real object style. It is important because of style change tricks below*/\n        const lv_style_t * style_ori_p = led->style_p;\n\n        /*Create a temporal style*/\n        lv_style_t leds_tmp;\n        memcpy(&leds_tmp, style, sizeof(leds_tmp));\n\n        /*Mix. the color with black proportionally with brightness*/\n        leds_tmp.body.main_color   = lv_color_mix(leds_tmp.body.main_color, LV_COLOR_BLACK, ext->bright);\n        leds_tmp.body.grad_color   = lv_color_mix(leds_tmp.body.grad_color, LV_COLOR_BLACK, ext->bright);\n        leds_tmp.body.border.color = lv_color_mix(leds_tmp.body.border.color, LV_COLOR_BLACK, ext->bright);\n\n        /*Set the current swidth according to brightness proportionally between LV_LED_BRIGHT_OFF\n         * and LV_LED_BRIGHT_ON*/\n        uint16_t bright_tmp = ext->bright;\n        leds_tmp.body.shadow.width =\n            ((bright_tmp - LV_LED_BRIGHT_OFF) * style->body.shadow.width) / (LV_LED_BRIGHT_ON - LV_LED_BRIGHT_OFF);\n\n        led->style_p = &leds_tmp;\n        ancestor_design_f(led, mask, mode);\n        led->style_p = style_ori_p; /*Restore the ORIGINAL style pointer*/\n    }\n    return true;\n}\n\n/**\n * Signal function of the led\n * @param led pointer to a led object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_led_signal(lv_obj_t * led, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(led, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_led\";\n    }\n\n    return res;\n}\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_line.c",
    "content": "/**\n * @file lv_line.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_line.h\"\n\n#if LV_USE_LINE != 0\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n#include \"utils/types.h\"\n#include <stdint.h>\n#include <string.h>\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_line_design(lv_obj_t * line, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_line_signal(lv_obj_t * line, lv_signal_t sign, void * param);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a line objects\n * @param par pointer to an object, it will be the parent of the new line\n * @return pointer to the created line\n */\nlv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"line create started\");\n\n    /*Create a basic object*/\n    lv_obj_t * new_line = lv_obj_create(par, copy);\n    lv_mem_assert(new_line);\n    if(new_line == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_line);\n\n    /*Extend the basic object to line object*/\n    lv_line_ext_t * ext = lv_obj_allocate_ext_attr(new_line, sizeof(lv_line_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    ext->point_num   = 0;\n    ext->point_array = NULL;\n    ext->auto_size   = 1;\n    ext->y_inv       = 0;\n\n    lv_obj_set_design_cb(new_line, lv_line_design);\n    lv_obj_set_signal_cb(new_line, lv_line_signal);\n\n    /*Init the new line*/\n    if(copy == NULL) {\n        lv_obj_set_size(new_line, LV_DPI,\n                        LV_DPI);          /*Auto size is enables, but set default size until no points are added*/\n        lv_obj_set_style(new_line, NULL); /*Inherit parent's style*/\n        lv_obj_set_click(new_line, false);\n    }\n    /*Copy an existing object*/\n    else {\n        lv_line_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        lv_line_set_auto_size(new_line, lv_line_get_auto_size(copy));\n        lv_line_set_y_invert(new_line, lv_line_get_y_invert(copy));\n        lv_line_set_auto_size(new_line, lv_line_get_auto_size(copy));\n        lv_line_set_points(new_line, copy_ext->point_array, copy_ext->point_num);\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_line);\n    }\n\n    LV_LOG_INFO(\"line created\");\n\n    return new_line;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set an array of points. The line object will connect these points.\n * @param line pointer to a line object\n * @param point_a an array of points. Only the address is saved,\n * so the array can NOT be a local variable which will be destroyed\n * @param point_num number of points in 'point_a'\n */\nvoid lv_line_set_points(lv_obj_t * line, const lv_point_t point_a[], uint16_t point_num)\n{\n    lv_line_ext_t * ext = lv_obj_get_ext_attr(line);\n    ext->point_array    = point_a;\n    ext->point_num      = point_num;\n\n    if(point_num > 0 && ext->auto_size != 0) {\n        uint16_t i;\n        lv_coord_t xmax = LV_COORD_MIN;\n        lv_coord_t ymax = LV_COORD_MIN;\n        for(i = 0; i < point_num; i++) {\n            xmax = LV_MATH_MAX(point_a[i].x, xmax);\n            ymax = LV_MATH_MAX(point_a[i].y, ymax);\n        }\n\n        const lv_style_t * style = lv_line_get_style(line, LV_LINE_STYLE_MAIN);\n        lv_obj_set_size(line, xmax + style->line.width, ymax + style->line.width);\n    }\n\n    lv_obj_invalidate(line);\n}\n\n/**\n * Enable (or disable) the auto-size option. The size of the object will fit to its points.\n * (set width to x max and height to y max)\n * @param line pointer to a line object\n * @param en true: auto size is enabled, false: auto size is disabled\n */\nvoid lv_line_set_auto_size(lv_obj_t * line, bool en)\n{\n    lv_line_ext_t * ext = lv_obj_get_ext_attr(line);\n    if(ext->auto_size == en) return;\n\n    ext->auto_size = en == false ? 0 : 1;\n\n    /*Refresh the object*/\n    if(en) lv_line_set_points(line, ext->point_array, ext->point_num);\n}\n\n/**\n * Enable (or disable) the y coordinate inversion.\n * If enabled then y will be subtracted from the height of the object,\n * therefore the y=0 coordinate will be on the bottom.\n * @param line pointer to a line object\n * @param en true: enable the y inversion, false:disable the y inversion\n */\nvoid lv_line_set_y_invert(lv_obj_t * line, bool en)\n{\n    lv_line_ext_t * ext = lv_obj_get_ext_attr(line);\n    if(ext->y_inv == en) return;\n\n    ext->y_inv = en == false ? 0 : 1;\n\n    lv_obj_invalidate(line);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the auto size attribute\n * @param line pointer to a line object\n * @return true: auto size is enabled, false: disabled\n */\nbool lv_line_get_auto_size(const lv_obj_t * line)\n{\n    lv_line_ext_t * ext = lv_obj_get_ext_attr(line);\n\n    return ext->auto_size == 0 ? false : true;\n}\n\n/**\n * Get the y inversion attribute\n * @param line pointer to a line object\n * @return true: y inversion is enabled, false: disabled\n */\nbool lv_line_get_y_invert(const lv_obj_t * line)\n{\n    lv_line_ext_t * ext = lv_obj_get_ext_attr(line);\n\n    return ext->y_inv == 0 ? false : true;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the lines\n * @param line pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_line_design(lv_obj_t * line, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    /*A line never covers an area*/\n    if(mode == LV_DESIGN_COVER_CHK)\n        return false;\n    else if(mode == LV_DESIGN_DRAW_MAIN) {\n        lv_line_ext_t * ext = lv_obj_get_ext_attr(line);\n\n        if(ext->point_num == 0 || ext->point_array == NULL) return false;\n\n        const lv_style_t * style = lv_obj_get_style(line);\n        lv_opa_t opa_scale       = lv_obj_get_opa_scale(line);\n        lv_area_t area;\n        lv_obj_get_coords(line, &area);\n        lv_coord_t x_ofs = area.x1;\n        lv_coord_t y_ofs = area.y1;\n        lv_point_t p1;\n        lv_point_t p2;\n        lv_coord_t h = lv_obj_get_height(line);\n        uint16_t i;\n\n        lv_style_t circle_style_tmp; /*If rounded...*/\n        lv_style_copy(&circle_style_tmp, style);\n        circle_style_tmp.body.radius     = LV_RADIUS_CIRCLE;\n        circle_style_tmp.body.main_color = style->line.color;\n        circle_style_tmp.body.grad_color = style->line.color;\n        circle_style_tmp.body.opa        = style->line.opa;\n        lv_area_t circle_area;\n\n        /*Read all points and draw the lines*/\n        for(i = 0; i < ext->point_num - 1; i++) {\n\n            p1.x = ext->point_array[i].x + x_ofs;\n            p2.x = ext->point_array[i + 1].x + x_ofs;\n\n            if(ext->y_inv == 0) {\n                p1.y = ext->point_array[i].y + y_ofs;\n                p2.y = ext->point_array[i + 1].y + y_ofs;\n            } else {\n                p1.y = h - ext->point_array[i].y + y_ofs;\n                p2.y = h - ext->point_array[i + 1].y + y_ofs;\n            }\n            lv_draw_line(&p1, &p2, mask, style, opa_scale);\n\n            /*Draw circle on the joints if enabled*/\n            if(style->line.rounded) {\n                circle_area.x1 = p1.x - ((style->line.width - 1) >> 1) - ((style->line.width - 1) & 0x1);\n                circle_area.y1 = p1.y - ((style->line.width - 1) >> 1) - ((style->line.width - 1) & 0x1);\n                circle_area.x2 = p1.x + ((style->line.width - 1) >> 1);\n                circle_area.y2 = p1.y + ((style->line.width - 1) >> 1);\n                lv_draw_rect(&circle_area, mask, &circle_style_tmp, opa_scale);\n            }\n        }\n\n        /*Draw circle on the last point too if enabled*/\n        if(style->line.rounded) {\n            circle_area.x1 = p2.x - ((style->line.width - 1) >> 1) - ((style->line.width - 1) & 0x1);\n            circle_area.y1 = p2.y - ((style->line.width - 1) >> 1) - ((style->line.width - 1) & 0x1);\n            circle_area.x2 = p2.x + ((style->line.width - 1) >> 1);\n            circle_area.y2 = p2.y + ((style->line.width - 1) >> 1);\n            lv_draw_rect(&circle_area, mask, &circle_style_tmp, opa_scale);\n        }\n    }\n    return true;\n}\n\n/**\n * Signal function of the line\n * @param line pointer to a line object\n * @param sign a signal type from lv_signal_t enum\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_line_signal(lv_obj_t * line, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(line, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_line\";\n    } else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {\n        const lv_style_t * style = lv_line_get_style(line, LV_LINE_STYLE_MAIN);\n        if(line->ext_draw_pad < style->line.width) line->ext_draw_pad = style->line.width;\n    }\n\n    return res;\n}\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_list.c",
    "content": "/**\n * @file lv_list.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_list.h\"\n#if LV_USE_LIST != 0\n\n#include \"libs/lvgl/lv_core/lv_group.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_misc/lv_anim.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_LIST_LAYOUT_DEF LV_LAYOUT_COL_M\n\n#if LV_USE_ANIMATION == 0\n#undef LV_LIST_DEF_ANIM_TIME\n#define LV_LIST_DEF_ANIM_TIME 0\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param);\nstatic lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param);\nstatic void lv_list_btn_single_select(lv_obj_t * btn);\nstatic bool lv_list_is_list_btn(lv_obj_t * list_btn);\nstatic bool lv_list_is_list_img(lv_obj_t * list_btn);\nstatic bool lv_list_is_list_label(lv_obj_t * list_btn);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n#if LV_USE_IMG\nstatic lv_signal_cb_t img_signal;\n#endif\nstatic lv_signal_cb_t label_signal;\nstatic lv_signal_cb_t ancestor_page_signal;\nstatic lv_signal_cb_t ancestor_btn_signal;\n#if LV_USE_GROUP\n/*Used to make the last clicked button pressed (selected) when the list become focused and\n * `click_focus == 1`*/\nstatic lv_obj_t * last_clicked_btn;\n#endif\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a list objects\n * @param par pointer to an object, it will be the parent of the new list\n * @param copy pointer to a list object, if not NULL then the new object will be copied from it\n * @return pointer to the created list\n */\nlv_obj_t * lv_list_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"list create started\");\n\n    /*Create the ancestor basic object*/\n    lv_obj_t * new_list = lv_page_create(par, copy);\n    lv_mem_assert(new_list);\n    if(new_list == NULL) return NULL;\n\n    if(ancestor_page_signal == NULL) ancestor_page_signal = lv_obj_get_signal_cb(new_list);\n\n    lv_list_ext_t * ext = lv_obj_allocate_ext_attr(new_list, sizeof(lv_list_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    ext->style_img                        = NULL;\n    ext->styles_btn[LV_BTN_STATE_REL]     = &lv_style_btn_rel;\n    ext->styles_btn[LV_BTN_STATE_PR]      = &lv_style_btn_pr;\n    ext->styles_btn[LV_BTN_STATE_TGL_REL] = &lv_style_btn_tgl_rel;\n    ext->styles_btn[LV_BTN_STATE_TGL_PR]  = &lv_style_btn_tgl_pr;\n    ext->styles_btn[LV_BTN_STATE_INA]     = &lv_style_btn_ina;\n    ext->single_mode                      = false;\n    ext->size                             = 0;\n\n#if LV_USE_GROUP\n    ext->last_sel     = NULL;\n    ext->selected_btn = NULL;\n#endif\n\n    lv_obj_set_signal_cb(new_list, lv_list_signal);\n\n    /*Init the new list object*/\n    if(copy == NULL) {\n        lv_page_set_anim_time(new_list, LV_LIST_DEF_ANIM_TIME);\n        lv_page_set_scrl_fit2(new_list, LV_FIT_FLOOD, LV_FIT_TIGHT);\n        lv_obj_set_size(new_list, 2 * LV_DPI, 3 * LV_DPI);\n        lv_page_set_scrl_layout(new_list, LV_LIST_LAYOUT_DEF);\n        lv_list_set_sb_mode(new_list, LV_SB_MODE_DRAG);\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_list_set_style(new_list, LV_LIST_STYLE_BG, th->style.list.bg);\n            lv_list_set_style(new_list, LV_LIST_STYLE_SCRL, th->style.list.scrl);\n            lv_list_set_style(new_list, LV_LIST_STYLE_SB, th->style.list.sb);\n            lv_list_set_style(new_list, LV_LIST_STYLE_BTN_REL, th->style.list.btn.rel);\n            lv_list_set_style(new_list, LV_LIST_STYLE_BTN_PR, th->style.list.btn.pr);\n            lv_list_set_style(new_list, LV_LIST_STYLE_BTN_TGL_REL, th->style.list.btn.tgl_rel);\n            lv_list_set_style(new_list, LV_LIST_STYLE_BTN_TGL_PR, th->style.list.btn.tgl_pr);\n            lv_list_set_style(new_list, LV_LIST_STYLE_BTN_INA, th->style.list.btn.ina);\n        } else {\n            lv_list_set_style(new_list, LV_LIST_STYLE_BG, &lv_style_transp_fit);\n            lv_list_set_style(new_list, LV_LIST_STYLE_SCRL, &lv_style_pretty);\n        }\n    } else {\n        lv_list_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n\n        lv_obj_t * copy_btn = lv_list_get_next_btn(copy, NULL);\n        while(copy_btn) {\n            const void * img_src = NULL;\n#if LV_USE_IMG\n            lv_obj_t * copy_img = lv_list_get_btn_img(copy_btn);\n            if(copy_img) img_src = lv_img_get_src(copy_img);\n#endif\n            lv_list_add_btn(new_list, img_src, lv_list_get_btn_text(copy_btn));\n            copy_btn = lv_list_get_next_btn(copy, copy_btn);\n        }\n\n        lv_list_set_style(new_list, LV_LIST_STYLE_BTN_REL, copy_ext->styles_btn[LV_BTN_STATE_REL]);\n        lv_list_set_style(new_list, LV_LIST_STYLE_BTN_PR, copy_ext->styles_btn[LV_BTN_STATE_PR]);\n        lv_list_set_style(new_list, LV_LIST_STYLE_BTN_TGL_REL, copy_ext->styles_btn[LV_BTN_STATE_TGL_REL]);\n        lv_list_set_style(new_list, LV_LIST_STYLE_BTN_TGL_PR, copy_ext->styles_btn[LV_BTN_STATE_TGL_REL]);\n        lv_list_set_style(new_list, LV_LIST_STYLE_BTN_INA, copy_ext->styles_btn[LV_BTN_STATE_INA]);\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_list);\n    }\n\n    LV_LOG_INFO(\"list created\");\n\n    return new_list;\n}\n\n/**\n * Delete all children of the scrl object, without deleting scrl child.\n * @param obj pointer to an object\n */\nvoid lv_list_clean(lv_obj_t * obj)\n{\n    lv_obj_t * scrl = lv_page_get_scrl(obj);\n    lv_obj_clean(scrl);\n    lv_list_ext_t * ext = lv_obj_get_ext_attr(obj);\n    ext->size           = 0;\n}\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/**\n * Add a list element to the list\n * @param list pointer to list object\n * @param img_fn file name of an image before the text (NULL if unused)\n * @param txt text of the list element (NULL if unused)\n * @return pointer to the new list element which can be customized (a button)\n */\nlv_obj_t * lv_list_add_btn(lv_obj_t * list, const void * img_src, const char * txt)\n{\n    lv_list_ext_t * ext = lv_obj_get_ext_attr(list);\n    ext->size++;\n    /*Create a list element with the image an the text*/\n    lv_obj_t * liste;\n    liste = lv_btn_create(list, NULL);\n\n    /*Save the original signal function because it will be required in `lv_list_btn_signal`*/\n    if(ancestor_btn_signal == NULL) ancestor_btn_signal = lv_obj_get_signal_cb(liste);\n\n    /*Set the default styles*/\n    lv_btn_set_style(liste, LV_BTN_STYLE_REL, ext->styles_btn[LV_BTN_STATE_REL]);\n    lv_btn_set_style(liste, LV_BTN_STYLE_PR, ext->styles_btn[LV_BTN_STATE_PR]);\n    lv_btn_set_style(liste, LV_BTN_STYLE_TGL_REL, ext->styles_btn[LV_BTN_STATE_TGL_REL]);\n    lv_btn_set_style(liste, LV_BTN_STYLE_TGL_PR, ext->styles_btn[LV_BTN_STATE_TGL_PR]);\n    lv_btn_set_style(liste, LV_BTN_STYLE_INA, ext->styles_btn[LV_BTN_STATE_INA]);\n\n    lv_page_glue_obj(liste, true);\n    lv_btn_set_layout(liste, LV_LAYOUT_ROW_M);\n    lv_btn_set_fit2(liste, LV_FIT_FLOOD, LV_FIT_TIGHT);\n    lv_obj_set_protect(liste, LV_PROTECT_PRESS_LOST);\n    lv_obj_set_signal_cb(liste, lv_list_btn_signal);\n\n#if LV_USE_IMG != 0\n    lv_obj_t * img = NULL;\n    if(img_src) {\n        img = lv_img_create(liste, NULL);\n        lv_img_set_src(img, img_src);\n        lv_obj_set_style(img, ext->style_img);\n        lv_obj_set_click(img, false);\n        if(img_signal == NULL) img_signal = lv_obj_get_signal_cb(img);\n    }\n#endif\n    if(txt != NULL) {\n        lv_coord_t btn_hor_pad = ext->styles_btn[LV_BTN_STYLE_REL]->body.padding.left -\n                                 ext->styles_btn[LV_BTN_STYLE_REL]->body.padding.right;\n        lv_obj_t * label = lv_label_create(liste, NULL);\n        lv_label_set_text(label, txt);\n        lv_obj_set_click(label, false);\n        lv_label_set_long_mode(label, LV_LABEL_LONG_SROLL_CIRC);\n        lv_obj_set_width(label, liste->coords.x2 - label->coords.x1 - btn_hor_pad);\n        if(label_signal == NULL) label_signal = lv_obj_get_signal_cb(label);\n    }\n#if LV_USE_GROUP\n    /* If this is the first item to be added to the list and the list is\n     * focused, select it */\n    {\n        lv_group_t * g = lv_obj_get_group(list);\n        if(ext->size == 1 && lv_group_get_focused(g) == list) {\n            lv_list_set_btn_selected(list, liste);\n        }\n    }\n#endif\n\n    return liste;\n}\n\n/**\n * Remove the index of the button in the list\n * @param list pointer to a list object\n * @param index pointer to a the button's index in the list, index must be 0 <= index <\n * lv_list_ext_t.size\n * @return true: successfully deleted\n */\nbool lv_list_remove(const lv_obj_t * list, uint16_t index)\n{\n    lv_list_ext_t * ext = lv_obj_get_ext_attr(list);\n    if(index >= ext->size) return false;\n    uint16_t count = 0;\n    lv_obj_t * e   = lv_list_get_next_btn(list, NULL);\n    while(e != NULL) {\n        if(count == index) {\n            lv_obj_del(e);\n            ext->size--;\n            return true;\n        }\n        e = lv_list_get_next_btn(list, e);\n        count++;\n    }\n    return false;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set single button selected mode, only one button will be selected if enabled.\n * @param list pointer to the currently pressed list object\n * @param mode, enable(true)/disable(false) single selected mode.\n */\nvoid lv_list_set_single_mode(lv_obj_t * list, bool mode)\n{\n    lv_list_ext_t * ext = lv_obj_get_ext_attr(list);\n\n    ext->single_mode = mode;\n}\n\n#if LV_USE_GROUP\n\n/**\n * Make a button selected\n * @param list pointer to a list object\n * @param btn pointer to a button to select\n *            NULL to not select any buttons\n */\nvoid lv_list_set_btn_selected(lv_obj_t * list, lv_obj_t * btn)\n{\n    lv_list_ext_t * ext = lv_obj_get_ext_attr(list);\n\n    if(ext->selected_btn) {\n        lv_btn_state_t s = lv_btn_get_state(ext->selected_btn);\n        if(s == LV_BTN_STATE_PR)\n            lv_btn_set_state(ext->selected_btn, LV_BTN_STATE_REL);\n        else if(s == LV_BTN_STATE_TGL_PR)\n            lv_btn_set_state(ext->selected_btn, LV_BTN_STATE_TGL_REL);\n    }\n\n    ext->selected_btn = btn;\n\n    /*Don't forget which button was selected.\n     * It will be restored when the list is focused.*/\n    if(btn != NULL) {\n        ext->last_sel = btn;\n    }\n\n    if(ext->selected_btn) {\n        lv_btn_state_t s = lv_btn_get_state(ext->selected_btn);\n        if(s == LV_BTN_STATE_REL)\n            lv_btn_set_state(ext->selected_btn, LV_BTN_STATE_PR);\n        else if(s == LV_BTN_STATE_TGL_REL)\n            lv_btn_set_state(ext->selected_btn, LV_BTN_STATE_TGL_PR);\n\n        lv_page_focus(list, ext->selected_btn, lv_list_get_anim_time(list));\n    }\n}\n\n#endif\n\n/**\n * Set a style of a list\n * @param list pointer to a list object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_list_set_style(lv_obj_t * list, lv_list_style_t type, const lv_style_t * style)\n{\n    lv_list_ext_t * ext           = lv_obj_get_ext_attr(list);\n    lv_btn_style_t btn_style_refr = LV_BTN_STYLE_REL;\n    lv_obj_t * btn;\n\n    switch(type) {\n        case LV_LIST_STYLE_BG:\n            lv_page_set_style(list, LV_PAGE_STYLE_BG, style);\n            /*style change signal will call 'refr_btn_width' */\n            break;\n        case LV_LIST_STYLE_SCRL: lv_page_set_style(list, LV_PAGE_STYLE_SCRL, style); break;\n        case LV_LIST_STYLE_SB: lv_page_set_style(list, LV_PAGE_STYLE_SB, style); break;\n        case LV_LIST_STYLE_EDGE_FLASH: lv_page_set_style(list, LV_PAGE_STYLE_EDGE_FLASH, style); break;\n        case LV_LIST_STYLE_BTN_REL:\n            ext->styles_btn[LV_BTN_STATE_REL] = style;\n            btn_style_refr                    = LV_BTN_STYLE_REL;\n            break;\n        case LV_LIST_STYLE_BTN_PR:\n            ext->styles_btn[LV_BTN_STATE_PR] = style;\n            btn_style_refr                   = LV_BTN_STYLE_PR;\n            break;\n        case LV_LIST_STYLE_BTN_TGL_REL:\n            ext->styles_btn[LV_BTN_STATE_TGL_REL] = style;\n            btn_style_refr                        = LV_BTN_STYLE_TGL_REL;\n            break;\n        case LV_LIST_STYLE_BTN_TGL_PR:\n            ext->styles_btn[LV_BTN_STATE_TGL_PR] = style;\n            btn_style_refr                       = LV_BTN_STYLE_TGL_PR;\n            break;\n        case LV_LIST_STYLE_BTN_INA:\n            ext->styles_btn[LV_BTN_STATE_INA] = style;\n            btn_style_refr                    = LV_BTN_STYLE_INA;\n            break;\n    }\n\n    /*Refresh existing buttons' style*/\n    if(type == LV_LIST_STYLE_BTN_PR || type == LV_LIST_STYLE_BTN_REL || type == LV_LIST_STYLE_BTN_TGL_REL ||\n       type == LV_LIST_STYLE_BTN_TGL_PR || type == LV_LIST_STYLE_BTN_INA) {\n        btn = lv_list_get_prev_btn(list, NULL);\n        while(btn != NULL) {\n            lv_btn_set_style(btn, btn_style_refr, ext->styles_btn[btn_style_refr]);\n            btn = lv_list_get_prev_btn(list, btn);\n        }\n    }\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get single button selected mode.\n * @param list pointer to the currently pressed list object.\n */\nbool lv_list_get_single_mode(lv_obj_t * list)\n{\n    lv_list_ext_t * ext = lv_obj_get_ext_attr(list);\n\n    return (ext->single_mode);\n}\n\n/**\n * Get the text of a list element\n * @param btn pointer to list element\n * @return pointer to the text\n */\nconst char * lv_list_get_btn_text(const lv_obj_t * btn)\n{\n    lv_obj_t * label = lv_list_get_btn_label(btn);\n    if(label == NULL) return \"\";\n    return lv_label_get_text(label);\n}\n\n/**\n * Get the label object from a list element\n * @param btn pointer to a list element (button)\n * @return pointer to the label from the list element or NULL if not found\n */\nlv_obj_t * lv_list_get_btn_label(const lv_obj_t * btn)\n{\n    lv_obj_t * label = lv_obj_get_child(btn, NULL);\n    if(label == NULL) return NULL;\n\n    while(lv_list_is_list_label(label) == false) {\n        label = lv_obj_get_child(btn, label);\n        if(label == NULL) break;\n    }\n\n    return label;\n}\n\n/**\n * Get the image object from a list element\n * @param btn pointer to a list element (button)\n * @return pointer to the image from the list element or NULL if not found\n */\nlv_obj_t * lv_list_get_btn_img(const lv_obj_t * btn)\n{\n#if LV_USE_IMG != 0\n    lv_obj_t * img = lv_obj_get_child(btn, NULL);\n    if(img == NULL) return NULL;\n\n    while(lv_list_is_list_img(img) == false) {\n        img = lv_obj_get_child(btn, img);\n        if(img == NULL) break;\n    }\n\n    return img;\n#else\n    return NULL;\n#endif\n}\n\n/**\n * Get the previous button from list. (Starts from the bottom button)\n * @param list pointer to a list object\n * @param prev_btn pointer to button. Search the previous before it.\n * @return pointer to the previous button or NULL when no more buttons\n */\nlv_obj_t * lv_list_get_prev_btn(const lv_obj_t * list, lv_obj_t * prev_btn)\n{\n    /* Not a good practice but user can add/create objects to the lists manually.\n     * When getting the next button try to be sure that it is at least a button */\n\n    lv_obj_t * btn;\n    lv_obj_t * scrl = lv_page_get_scrl(list);\n\n    btn = lv_obj_get_child(scrl, prev_btn);\n    if(btn == NULL) return NULL;\n\n    while(lv_list_is_list_btn(btn) == false) {\n        btn = lv_obj_get_child(scrl, btn);\n        if(btn == NULL) break;\n    }\n\n    return btn;\n}\n\n/**\n * Get the next button from list. (Starts from the top button)\n * @param list pointer to a list object\n * @param prev_btn pointer to button. Search the next after it.\n * @return pointer to the next button or NULL when no more buttons\n */\nlv_obj_t * lv_list_get_next_btn(const lv_obj_t * list, lv_obj_t * prev_btn)\n{\n    /* Not a good practice but user can add/create objects to the lists manually.\n     * When getting the next button try to be sure that it is at least a button */\n\n    lv_obj_t * btn;\n    lv_obj_t * scrl = lv_page_get_scrl(list);\n\n    btn = lv_obj_get_child_back(scrl, prev_btn);\n    if(btn == NULL) return NULL;\n\n    while(lv_list_is_list_btn(btn) == false) {\n        btn = lv_obj_get_child_back(scrl, btn);\n        if(btn == NULL) break;\n    }\n\n    return btn;\n}\n\n/**\n * Get the index of the button in the list\n * @param list pointer to a list object. If NULL, assumes btn is part of a list.\n * @param btn pointer to a list element (button)\n * @return the index of the button in the list, or -1 of the button not in this list\n */\nint32_t lv_list_get_btn_index(const lv_obj_t * list, const lv_obj_t * btn)\n{\n    int index = 0;\n    if(list == NULL) {\n        /* no list provided, assuming btn is part of a list */\n        list = lv_obj_get_parent(lv_obj_get_parent(btn));\n    }\n    lv_obj_t * e = lv_list_get_next_btn(list, NULL);\n    while(e != NULL) {\n        if(e == btn) {\n            return index;\n        }\n        index++;\n        e = lv_list_get_next_btn(list, e);\n    }\n    return -1;\n}\n\n/**\n * Get the number of buttons in the list\n * @param list pointer to a list object\n * @return the number of buttons in the list\n */\nuint16_t lv_list_get_size(const lv_obj_t * list)\n{\n    lv_list_ext_t * ext = lv_obj_get_ext_attr(list);\n    return ext->size;\n}\n\n#if LV_USE_GROUP\n/**\n * Get the currently selected button\n * @param list pointer to a list object\n * @return pointer to the selected button\n */\nlv_obj_t * lv_list_get_btn_selected(const lv_obj_t * list)\n{\n    lv_list_ext_t * ext = lv_obj_get_ext_attr(list);\n    return ext->selected_btn;\n}\n\n#endif\n\n/**\n * Get a style of a list\n * @param list pointer to a list object\n * @param type which style should be get\n * @return style pointer to a style\n *  */\nconst lv_style_t * lv_list_get_style(const lv_obj_t * list, lv_list_style_t type)\n{\n    const lv_style_t * style = NULL;\n    lv_list_ext_t * ext      = lv_obj_get_ext_attr(list);\n\n    switch(type) {\n        case LV_LIST_STYLE_BG: style = lv_page_get_style(list, LV_PAGE_STYLE_BG); break;\n        case LV_LIST_STYLE_SCRL: style = lv_page_get_style(list, LV_PAGE_STYLE_SCRL); break;\n        case LV_LIST_STYLE_SB: style = lv_page_get_style(list, LV_PAGE_STYLE_SB); break;\n        case LV_LIST_STYLE_EDGE_FLASH: style = lv_page_get_style(list, LV_PAGE_STYLE_EDGE_FLASH); break;\n        case LV_LIST_STYLE_BTN_REL: style = ext->styles_btn[LV_BTN_STATE_REL]; break;\n        case LV_LIST_STYLE_BTN_PR: style = ext->styles_btn[LV_BTN_STATE_PR]; break;\n        case LV_LIST_STYLE_BTN_TGL_REL: style = ext->styles_btn[LV_BTN_STATE_TGL_REL]; break;\n        case LV_LIST_STYLE_BTN_TGL_PR: style = ext->styles_btn[LV_BTN_STATE_TGL_PR]; break;\n        case LV_LIST_STYLE_BTN_INA: style = ext->styles_btn[LV_BTN_STATE_INA]; break;\n        default: style = NULL; break;\n    }\n\n    return style;\n}\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Move the list elements up by one\n * @param list pointer a to list object\n */\nvoid lv_list_up(const lv_obj_t * list)\n{\n    /*Search the first list element which 'y' coordinate is below the parent\n     * and position the list to show this element on the bottom*/\n    lv_obj_t * scrl = lv_page_get_scrl(list);\n    lv_obj_t * e;\n    lv_obj_t * e_prev = NULL;\n\n    e                 = lv_list_get_prev_btn(list, NULL);\n    while(e != NULL) {\n        if(e->coords.y2 <= list->coords.y2) {\n            if(e_prev != NULL) {\n                lv_coord_t new_y = lv_obj_get_height(list) - (lv_obj_get_y(e_prev) + lv_obj_get_height(e_prev));\n                if(lv_list_get_anim_time(list) == 0) {\n                    lv_obj_set_y(scrl, new_y);\n                } else {\n#if LV_USE_ANIMATION\n                    lv_anim_t a;\n                    a.var            = scrl;\n                    a.start          = lv_obj_get_y(scrl);\n                    a.end            = new_y;\n                    a.exec_cb        = (lv_anim_exec_xcb_t)lv_obj_set_y;\n                    a.path_cb        = lv_anim_path_linear;\n                    a.ready_cb       = NULL;\n                    a.act_time       = 0;\n                    a.time           = LV_LIST_DEF_ANIM_TIME;\n                    a.playback       = 0;\n                    a.playback_pause = 0;\n                    a.repeat         = 0;\n                    a.repeat_pause   = 0;\n                    lv_anim_create(&a);\n#endif\n                }\n            }\n            break;\n        }\n        e_prev = e;\n        e      = lv_list_get_prev_btn(list, e);\n    }\n}\n\n/**\n * Move the list elements down by one\n * @param list pointer to a list object\n */\nvoid lv_list_down(const lv_obj_t * list)\n{\n    /*Search the first list element which 'y' coordinate is above the parent\n     * and position the list to show this element on the top*/\n    lv_obj_t * scrl = lv_page_get_scrl(list);\n    lv_obj_t * e;\n    e = lv_list_get_prev_btn(list, NULL);\n    while(e != NULL) {\n        if(e->coords.y1 < list->coords.y1) {\n            lv_coord_t new_y = -lv_obj_get_y(e);\n            if(lv_list_get_anim_time(list) == 0) {\n                lv_obj_set_y(scrl, new_y);\n            } else {\n#if LV_USE_ANIMATION\n                lv_anim_t a;\n                a.var            = scrl;\n                a.start          = lv_obj_get_y(scrl);\n                a.end            = new_y;\n                a.exec_cb        = (lv_anim_exec_xcb_t)lv_obj_set_y;\n                a.path_cb        = lv_anim_path_linear;\n                a.ready_cb       = NULL;\n                a.act_time       = 0;\n                a.time           = LV_LIST_DEF_ANIM_TIME;\n                a.playback       = 0;\n                a.playback_pause = 0;\n                a.repeat         = 0;\n                a.repeat_pause   = 0;\n                lv_anim_create(&a);\n#endif\n            }\n            break;\n        }\n        e = lv_list_get_prev_btn(list, e);\n    }\n}\n\n/**\n * Focus on a list button. It ensures that the button will be visible on the list.\n * @param btn pointer to a list button to focus\n * @param anim_en LV_ANIM_ON: scroll with animation, LV_ANOM_OFF: without animation\n */\nvoid lv_list_focus(const lv_obj_t * btn, lv_anim_enable_t anim)\n{\n\n#if LV_USE_ANIMATION == 0\n    anim = false;\n#endif\n\n    lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));\n\n    lv_page_focus(list, btn, anim == LV_ANIM_OFF ? 0 : lv_list_get_anim_time(list));\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Signal function of the list\n * @param list pointer to a list object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_page_signal(list, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_PRESSING ||\n       sign == LV_SIGNAL_LONG_PRESS || sign == LV_SIGNAL_LONG_PRESS_REP) {\n#if LV_USE_GROUP\n        /*If pressed/released etc by a KEYPAD or ENCODER delegate signal to the button*/\n        lv_indev_t * indev         = lv_indev_get_act();\n        lv_indev_type_t indev_type = lv_indev_get_type(indev);\n        if(indev_type == LV_INDEV_TYPE_KEYPAD ||\n           (indev_type == LV_INDEV_TYPE_ENCODER && lv_group_get_editing(lv_obj_get_group(list)))) {\n            /*Get the 'pressed' button*/\n            lv_obj_t * btn = NULL;\n            btn            = lv_list_get_prev_btn(list, btn);\n            while(btn != NULL) {\n                if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;\n                btn = lv_list_get_prev_btn(list, btn);\n            }\n            lv_list_ext_t * ext = lv_obj_get_ext_attr(list);\n\n            /*The page receives the key presses so the events should be propagated to the selected\n             * button*/\n            if(btn) {\n                if(sign == LV_SIGNAL_PRESSED) {\n                    res = lv_event_send(btn, LV_EVENT_PRESSED, NULL);\n                } else if(sign == LV_SIGNAL_PRESSING) {\n                    res = lv_event_send(btn, LV_EVENT_PRESSING, NULL);\n                } else if(sign == LV_SIGNAL_LONG_PRESS) {\n                    res = lv_event_send(btn, LV_EVENT_LONG_PRESSED, NULL);\n                } else if(sign == LV_SIGNAL_LONG_PRESS_REP) {\n                    res = lv_event_send(btn, LV_EVENT_LONG_PRESSED_REPEAT, NULL);\n                } else if(sign == LV_SIGNAL_RELEASED) {\n#if LV_USE_GROUP\n                    ext->last_sel = btn;\n#endif\n                    if(indev->proc.long_pr_sent == 0) {\n                        res = lv_event_send(btn, LV_EVENT_SHORT_CLICKED, NULL);\n                    }\n                    if(lv_indev_is_dragging(indev) == false && res == LV_RES_OK) {\n                        res = lv_event_send(btn, LV_EVENT_CLICKED, NULL);\n                    }\n                    if(res == LV_RES_OK) {\n                        res = lv_event_send(btn, LV_EVENT_RELEASED, NULL);\n                    }\n                }\n            }\n        }\n#endif\n    } else if(sign == LV_SIGNAL_FOCUS) {\n\n#if LV_USE_GROUP\n        lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());\n        /*With ENCODER select the first button only in edit mode*/\n        if(indev_type == LV_INDEV_TYPE_ENCODER) {\n            lv_group_t * g = lv_obj_get_group(list);\n            if(lv_group_get_editing(g)) {\n                lv_list_ext_t * ext = lv_obj_get_ext_attr(list);\n                if(ext->last_sel) {\n                    /* Select the    last used button */\n                    lv_list_set_btn_selected(list, ext->last_sel);\n                } else {\n                    /*Get the first button and mark it as selected*/\n                    lv_list_set_btn_selected(list, lv_list_get_next_btn(list, NULL));\n                }\n            } else {\n                lv_list_set_btn_selected(list, NULL);\n            }\n        }\n        /*Else select the clicked button*/\n        else {\n            /*Mark the last clicked button (if any) as selected because it triggered the focus*/\n            if(last_clicked_btn) {\n                lv_list_set_btn_selected(list, last_clicked_btn);\n            } else {\n                lv_list_ext_t * ext = lv_obj_get_ext_attr(list);\n                if(ext->last_sel) {\n                    /* Select the last used button */\n                    lv_list_set_btn_selected(list, ext->last_sel);\n                } else {\n                    /*Get the first button and mark it as selected*/\n                    lv_list_set_btn_selected(list, lv_list_get_next_btn(list, NULL));\n                }\n            }\n        }\n#endif\n    } else if(sign == LV_SIGNAL_DEFOCUS) {\n\n#if LV_USE_GROUP\n        /*De-select the selected btn*/\n        lv_list_set_btn_selected(list, NULL);\n        last_clicked_btn    = NULL; /*button click will be set if click happens before focus*/\n        lv_list_ext_t * ext = lv_obj_get_ext_attr(list);\n        ext->selected_btn   = NULL;\n#endif\n    } else if(sign == LV_SIGNAL_GET_EDITABLE) {\n        bool * editable = (bool *)param;\n        *editable       = true;\n    } else if(sign == LV_SIGNAL_CONTROL) {\n\n#if LV_USE_GROUP\n        char c = *((char *)param);\n        if(c == LV_KEY_RIGHT || c == LV_KEY_DOWN) {\n            lv_list_ext_t * ext = lv_obj_get_ext_attr(list);\n            /*If there is a valid selected button the make the previous selected*/\n            if(ext->selected_btn) {\n                lv_obj_t * btn_prev = lv_list_get_next_btn(list, ext->selected_btn);\n                if(btn_prev) lv_list_set_btn_selected(list, btn_prev);\n            }\n            /*If there is no selected button the make the first selected*/\n            else {\n                lv_obj_t * btn = lv_list_get_next_btn(list, NULL);\n                if(btn)\n                    lv_list_set_btn_selected(list,\n                                             btn); /*If there are no buttons on the list then there is no first button*/\n            }\n        } else if(c == LV_KEY_LEFT || c == LV_KEY_UP) {\n            lv_list_ext_t * ext = lv_obj_get_ext_attr(list);\n            /*If there is a valid selected button the make the next selected*/\n            if(ext->selected_btn != NULL) {\n                lv_obj_t * btn_next = lv_list_get_prev_btn(list, ext->selected_btn);\n                if(btn_next) lv_list_set_btn_selected(list, btn_next);\n            }\n            /*If there is no selected button the make the first selected*/\n            else {\n                lv_obj_t * btn = lv_list_get_next_btn(list, NULL);\n                if(btn) lv_list_set_btn_selected(list, btn);\n            }\n        }\n#endif\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_list\";\n    }\n    return res;\n}\n\n/**\n * Signal function of the list buttons\n * @param btn pointer to a button on the list\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_btn_signal(btn, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    if(sign == LV_SIGNAL_RELEASED) {\n        lv_obj_t * list          = lv_obj_get_parent(lv_obj_get_parent(btn));\n        lv_list_ext_t * ext      = lv_obj_get_ext_attr(list);\n        ext->page.scroll_prop_ip = 0;\n\n#if LV_USE_GROUP\n        lv_group_t * g = lv_obj_get_group(list);\n        if(lv_group_get_focused(g) == list && lv_indev_is_dragging(lv_indev_get_act()) == false) {\n            /* Is the list is focused then be sure only the button being released\n             * has a pressed state to indicate the selected state on the list*/\n            lv_obj_t * btn_i = lv_list_get_prev_btn(list, NULL);\n            while(btn_i) {\n                lv_btn_state_t s = lv_btn_get_state(btn_i);\n                if(s == LV_BTN_STATE_PR)\n                    lv_btn_set_state(btn_i, LV_BTN_STATE_REL);\n                else if(s == LV_BTN_STATE_TGL_PR)\n                    lv_btn_set_state(btn_i, LV_BTN_STATE_TGL_REL);\n                btn_i = lv_list_get_prev_btn(list, btn_i);\n            }\n\n            /*Make the released button \"selected\"*/\n            lv_list_set_btn_selected(list, btn);\n        }\n\n        /* If `click_focus == 1` then LV_SIGNAL_FOCUS need to know which button triggered the focus\n         * to mark it as selected (pressed state)*/\n        last_clicked_btn = btn;\n#endif\n        if(lv_indev_is_dragging(lv_indev_get_act()) == false && ext->single_mode) {\n            lv_list_btn_single_select(btn);\n        }\n    } else if(sign == LV_SIGNAL_PRESS_LOST) {\n        lv_obj_t * list          = lv_obj_get_parent(lv_obj_get_parent(btn));\n        lv_list_ext_t * ext      = lv_obj_get_ext_attr(list);\n        ext->page.scroll_prop_ip = 0;\n    } else if(sign == LV_SIGNAL_CLEANUP) {\n\n#if LV_USE_GROUP\n        lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));\n        lv_obj_t * sel  = lv_list_get_btn_selected(list);\n        if(sel == btn) lv_list_set_btn_selected(list, lv_list_get_next_btn(list, btn));\n#endif\n    }\n\n    return res;\n}\n\n/**\n * Make a single button selected in the list, deselect others.\n * @param btn pointer to the currently pressed list btn object\n */\nstatic void lv_list_btn_single_select(lv_obj_t * btn)\n{\n    lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));\n\n    lv_obj_t * e = lv_list_get_next_btn(list, NULL);\n    do {\n        if(e == btn) {\n            lv_btn_set_state(e, LV_BTN_STATE_TGL_REL);\n        } else {\n            lv_btn_set_state(e, LV_BTN_STATE_REL);\n        }\n        e = lv_list_get_next_btn(list, e);\n    } while(e != NULL);\n}\n\n/**\n * Check if this is really a list button or another object.\n * @param list_btn List button\n */\nstatic bool lv_list_is_list_btn(lv_obj_t * list_btn)\n{\n    lv_obj_type_t type;\n\n    lv_obj_get_type(list_btn, &type);\n    uint8_t cnt;\n    for(cnt = 0; cnt < LV_MAX_ANCESTOR_NUM; cnt++) {\n        if(type.type[cnt] == NULL) break;\n        if(!strcmp(type.type[cnt], \"lv_btn\")) return true;\n    }\n    return false;\n}\n\n/**\n * Check if this is really a list label or another object.\n * @param list_label List label\n */\nstatic bool lv_list_is_list_label(lv_obj_t * list_label)\n{\n    lv_obj_type_t type;\n\n    lv_obj_get_type(list_label, &type);\n    uint8_t cnt;\n    for(cnt = 0; cnt < LV_MAX_ANCESTOR_NUM; cnt++) {\n        if(type.type[cnt] == NULL) break;\n        if(!strcmp(type.type[cnt], \"lv_label\")) return true;\n    }\n    return false;\n}\n\n/**\n * Check if this is really a list image or another object.\n * @param list_image List image\n */\nstatic bool lv_list_is_list_img(lv_obj_t * list_img)\n{\n    lv_obj_type_t type;\n\n    lv_obj_get_type(list_img, &type);\n    uint8_t cnt;\n    for(cnt = 0; cnt < LV_MAX_ANCESTOR_NUM; cnt++) {\n        if(type.type[cnt] == NULL) break;\n        if(!strcmp(type.type[cnt], \"lv_img\")) return true;\n    }\n    return false;\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_lmeter.c",
    "content": "/**\n * @file lv_lmeter.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_lmeter.h\"\n#if LV_USE_LMETER != 0\n\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_core/lv_group.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_LMETER_LINE_UPSCALE 5 /*2^x upscale of line to make rounding*/\n#define LV_LMETER_LINE_UPSCALE_MASK ((1 << LV_LMETER_LINE_UPSCALE) - 1)\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_lmeter_design(lv_obj_t * lmeter, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_lmeter_signal(lv_obj_t * lmeter, lv_signal_t sign, void * param);\nstatic lv_coord_t lv_lmeter_coord_round(int32_t x);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a line meter objects\n * @param par pointer to an object, it will be the parent of the new line meter\n * @param copy pointer to a line meter object, if not NULL then the new object will be copied from\n * it\n * @return pointer to the created line meter\n */\nlv_obj_t * lv_lmeter_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"line meter create started\");\n\n    /*Create the ancestor of line meter*/\n    lv_obj_t * new_lmeter = lv_obj_create(par, copy);\n    lv_mem_assert(new_lmeter);\n    if(new_lmeter == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_lmeter);\n\n    /*Allocate the line meter type specific extended data*/\n    lv_lmeter_ext_t * ext = lv_obj_allocate_ext_attr(new_lmeter, sizeof(lv_lmeter_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    /*Initialize the allocated 'ext' */\n    ext->min_value   = 0;\n    ext->max_value   = 100;\n    ext->cur_value   = 0;\n    ext->line_cnt    = 21;  /*Odd scale number looks better*/\n    ext->scale_angle = 240; /*(scale_num - 1) * N looks better */\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_cb(new_lmeter, lv_lmeter_signal);\n    lv_obj_set_design_cb(new_lmeter, lv_lmeter_design);\n\n    /*Init the new line meter line meter*/\n    if(copy == NULL) {\n        lv_obj_set_size(new_lmeter, LV_DPI, LV_DPI);\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_lmeter_set_style(new_lmeter, LV_LMETER_STYLE_MAIN, th->style.lmeter);\n        } else {\n            lv_lmeter_set_style(new_lmeter, LV_LMETER_STYLE_MAIN, &lv_style_pretty_color);\n        }\n    }\n    /*Copy an existing line meter*/\n    else {\n        lv_lmeter_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->scale_angle           = copy_ext->scale_angle;\n        ext->line_cnt              = copy_ext->line_cnt;\n        ext->min_value             = copy_ext->min_value;\n        ext->max_value             = copy_ext->max_value;\n        ext->cur_value             = copy_ext->cur_value;\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_lmeter);\n    }\n\n    LV_LOG_INFO(\"line meter created\");\n\n    return new_lmeter;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a new value on the line meter\n * @param lmeter pointer to a line meter object\n * @param value new value\n */\nvoid lv_lmeter_set_value(lv_obj_t * lmeter, int16_t value)\n{\n    lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);\n    if(ext->cur_value == value) return;\n\n    ext->cur_value = value > ext->max_value ? ext->max_value : value;\n    ext->cur_value = ext->cur_value < ext->min_value ? ext->min_value : ext->cur_value;\n    lv_obj_invalidate(lmeter);\n}\n\n/**\n * Set minimum and the maximum values of a line meter\n * @param lmeter pointer to he line meter object\n * @param min minimum value\n * @param max maximum value\n */\nvoid lv_lmeter_set_range(lv_obj_t * lmeter, int16_t min, int16_t max)\n{\n    lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);\n    if(ext->min_value == min && ext->max_value == max) return;\n\n    ext->max_value = max;\n    ext->min_value = min;\n    if(ext->cur_value > max) {\n        ext->cur_value = max;\n        lv_lmeter_set_value(lmeter, ext->cur_value);\n    }\n    if(ext->cur_value < min) {\n        ext->cur_value = min;\n        lv_lmeter_set_value(lmeter, ext->cur_value);\n    }\n    lv_obj_invalidate(lmeter);\n}\n\n/**\n * Set the scale settings of a line meter\n * @param lmeter pointer to a line meter object\n * @param angle angle of the scale (0..360)\n * @param line_cnt number of lines\n */\nvoid lv_lmeter_set_scale(lv_obj_t * lmeter, uint16_t angle, uint8_t line_cnt)\n{\n    lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);\n    if(ext->scale_angle == angle && ext->line_cnt == line_cnt) return;\n\n    ext->scale_angle = angle;\n    ext->line_cnt    = line_cnt;\n\n    lv_obj_invalidate(lmeter);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the value of a line meter\n * @param lmeter pointer to a line meter object\n * @return the value of the line meter\n */\nint16_t lv_lmeter_get_value(const lv_obj_t * lmeter)\n{\n    lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);\n    return ext->cur_value;\n}\n\n/**\n * Get the minimum value of a line meter\n * @param lmeter pointer to a line meter object\n * @return the minimum value of the line meter\n */\nint16_t lv_lmeter_get_min_value(const lv_obj_t * lmeter)\n{\n    lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);\n    return ext->min_value;\n}\n\n/**\n * Get the maximum value of a line meter\n * @param lmeter pointer to a line meter object\n * @return the maximum value of the line meter\n */\nint16_t lv_lmeter_get_max_value(const lv_obj_t * lmeter)\n{\n    lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);\n    return ext->max_value;\n}\n\n/**\n * Get the scale number of a line meter\n * @param lmeter pointer to a line meter object\n * @return number of the scale units\n */\nuint8_t lv_lmeter_get_line_count(const lv_obj_t * lmeter)\n{\n    lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);\n    return ext->line_cnt;\n}\n\n/**\n * Get the scale angle of a line meter\n * @param lmeter pointer to a line meter object\n * @return angle of the scale\n */\nuint16_t lv_lmeter_get_scale_angle(const lv_obj_t * lmeter)\n{\n    lv_lmeter_ext_t * ext = lv_obj_get_ext_attr(lmeter);\n    return ext->scale_angle;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the line meters\n * @param lmeter pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_lmeter_design(lv_obj_t * lmeter, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    /*Return false if the object is not covers the mask_p area*/\n    if(mode == LV_DESIGN_COVER_CHK) {\n        return false;\n    }\n    /*Draw the object*/\n    else if(mode == LV_DESIGN_DRAW_MAIN) {\n        lv_lmeter_ext_t * ext    = lv_obj_get_ext_attr(lmeter);\n        const lv_style_t * style = lv_obj_get_style(lmeter);\n        lv_opa_t opa_scale       = lv_obj_get_opa_scale(lmeter);\n        lv_style_t style_tmp;\n        lv_style_copy(&style_tmp, style);\n\n#if LV_USE_GROUP\n        lv_group_t * g = lv_obj_get_group(lmeter);\n        if(lv_group_get_focused(g) == lmeter) {\n            style_tmp.line.width += 1;\n        }\n#endif\n\n        lv_coord_t r_out = lv_obj_get_width(lmeter) / 2;\n        lv_coord_t r_in  = r_out - style->body.padding.left;\n        if(r_in < 1) r_in = 1;\n\n        lv_coord_t x_ofs  = lv_obj_get_width(lmeter) / 2 + lmeter->coords.x1;\n        lv_coord_t y_ofs  = lv_obj_get_height(lmeter) / 2 + lmeter->coords.y1;\n        int16_t angle_ofs = 90 + (360 - ext->scale_angle) / 2;\n        int16_t level =\n            (int32_t)((int32_t)(ext->cur_value - ext->min_value) * ext->line_cnt) / (ext->max_value - ext->min_value);\n        uint8_t i;\n\n        style_tmp.line.color = style->body.main_color;\n\n        /*Calculate every coordinate in a bigger size to make rounding later*/\n        r_out = r_out << LV_LMETER_LINE_UPSCALE;\n        r_in  = r_in << LV_LMETER_LINE_UPSCALE;\n\n        for(i = 0; i < ext->line_cnt; i++) {\n            /*Calculate the position a scale label*/\n            int16_t angle = (i * ext->scale_angle) / (ext->line_cnt - 1) + angle_ofs;\n\n            lv_coord_t y_out = (int32_t)((int32_t)lv_trigo_sin(angle) * r_out) >> LV_TRIGO_SHIFT;\n            lv_coord_t x_out = (int32_t)((int32_t)lv_trigo_sin(angle + 90) * r_out) >> LV_TRIGO_SHIFT;\n            lv_coord_t y_in  = (int32_t)((int32_t)lv_trigo_sin(angle) * r_in) >> LV_TRIGO_SHIFT;\n            lv_coord_t x_in  = (int32_t)((int32_t)lv_trigo_sin(angle + 90) * r_in) >> LV_TRIGO_SHIFT;\n\n            /*Rounding*/\n            x_out = lv_lmeter_coord_round(x_out);\n            x_in  = lv_lmeter_coord_round(x_in);\n            y_out = lv_lmeter_coord_round(y_out);\n            y_in  = lv_lmeter_coord_round(y_in);\n\n            lv_point_t p1;\n            lv_point_t p2;\n\n            p2.x = x_in + x_ofs;\n            p2.y = y_in + y_ofs;\n\n            p1.x = x_out + x_ofs;\n            p1.y = y_out + y_ofs;\n\n            if(i >= level)\n                style_tmp.line.color = style->line.color;\n            else {\n                style_tmp.line.color =\n                    lv_color_mix(style->body.grad_color, style->body.main_color, (255 * i) / ext->line_cnt);\n            }\n\n            lv_draw_line(&p1, &p2, mask, &style_tmp, opa_scale);\n        }\n\n    }\n    /*Post draw when the children are drawn*/\n    else if(mode == LV_DESIGN_DRAW_POST) {\n    }\n\n    return true;\n}\n\n/**\n * Signal function of the line meter\n * @param lmeter pointer to a line meter object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_lmeter_signal(lv_obj_t * lmeter, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(lmeter, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    if(sign == LV_SIGNAL_CLEANUP) {\n        /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/\n    } else if(sign == LV_SIGNAL_STYLE_CHG) {\n        lv_obj_refresh_ext_draw_pad(lmeter);\n    } else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {\n        const lv_style_t * style = lv_lmeter_get_style(lmeter, LV_LMETER_STYLE_MAIN);\n        lmeter->ext_draw_pad     = LV_MATH_MAX(lmeter->ext_draw_pad, style->line.width);\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_lmeter\";\n    }\n\n    return res;\n}\n\n/**\n * Round a coordinate which is upscaled  (>=x.5 -> x + 1;   <x.5 -> x)\n * @param x a coordinate which is greater then it should be\n * @return the downscaled and rounded coordinate  (+-1)\n */\nstatic lv_coord_t lv_lmeter_coord_round(int32_t x)\n{\n#if LV_LMETER_LINE_UPSCALE > 0\n    bool was_negative = false;\n    if(x < 0) {\n        was_negative = true;\n        x            = -x;\n    }\n\n    x = (x >> LV_LMETER_LINE_UPSCALE) + ((x & LV_LMETER_LINE_UPSCALE_MASK) >> (LV_LMETER_LINE_UPSCALE - 1));\n\n    if(was_negative) x = -x;\n\n    return x;\n#else\n    return x;\n#endif\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_mbox.c",
    "content": "/**\n * @file lv_mbox.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_mbox.h\"\n#if LV_USE_MBOX != 0\n\n#include \"libs/lvgl/lv_core/lv_group.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_misc/lv_anim.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n#if LV_USE_ANIMATION\n#ifndef LV_MBOX_CLOSE_ANIM_TIME\n#define LV_MBOX_CLOSE_ANIM_TIME 200 /*List close animation time)  */\n#endif\n#else\n#undef LV_MBOX_CLOSE_ANIM_TIME\n#define LV_MBOX_CLOSE_ANIM_TIME 0 /*No animations*/\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic lv_res_t lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param);\nstatic void mbox_realign(lv_obj_t * mbox);\n#if LV_USE_ANIMATION\nstatic void lv_mbox_close_ready_cb(lv_anim_t * a);\n#endif\nstatic void lv_mbox_default_event_cb(lv_obj_t * mbox, lv_event_t event);\nstatic void lv_mbox_btnm_event_cb(lv_obj_t * btnm, lv_event_t event);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a message box objects\n * @param par pointer to an object, it will be the parent of the new message box\n * @param copy pointer to a message box object, if not NULL then the new object will be copied from\n * it\n * @return pointer to the created message box\n */\nlv_obj_t * lv_mbox_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"mesasge box create started\");\n\n    /*Create the ancestor message box*/\n    lv_obj_t * new_mbox = lv_cont_create(par, copy);\n    lv_mem_assert(new_mbox);\n    if(new_mbox == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_mbox);\n\n    /*Allocate the message box type specific extended data*/\n    lv_mbox_ext_t * ext = lv_obj_allocate_ext_attr(new_mbox, sizeof(lv_mbox_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    ext->text = NULL;\n    ext->btnm = NULL;\n#if LV_USE_ANIMATION\n    ext->anim_time = LV_MBOX_CLOSE_ANIM_TIME;\n#endif\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_cb(new_mbox, lv_mbox_signal);\n\n    /*Init the new message box message box*/\n    if(copy == NULL) {\n        ext->text = lv_label_create(new_mbox, NULL);\n        lv_label_set_align(ext->text, LV_LABEL_ALIGN_CENTER);\n        lv_label_set_long_mode(ext->text, LV_LABEL_LONG_BREAK);\n        lv_label_set_text(ext->text, \"Message\");\n\n        lv_cont_set_layout(new_mbox, LV_LAYOUT_COL_M);\n        lv_cont_set_fit2(new_mbox, LV_FIT_NONE, LV_FIT_TIGHT);\n        lv_obj_set_width(new_mbox, LV_DPI * 2);\n        lv_obj_align(new_mbox, NULL, LV_ALIGN_CENTER, 0, 0);\n        lv_obj_set_event_cb(new_mbox, lv_mbox_default_event_cb);\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_mbox_set_style(new_mbox, LV_MBOX_STYLE_BG, th->style.mbox.bg);\n        } else {\n            lv_mbox_set_style(new_mbox, LV_MBOX_STYLE_BG, &lv_style_pretty);\n        }\n\n    }\n    /*Copy an existing message box*/\n    else {\n        lv_mbox_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n\n        ext->text = lv_label_create(new_mbox, copy_ext->text);\n\n        /*Copy the buttons and the label on them*/\n        if(copy_ext->btnm) ext->btnm = lv_btnm_create(new_mbox, copy_ext->btnm);\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_mbox);\n    }\n\n    LV_LOG_INFO(\"mesasge box created\");\n\n    return new_mbox;\n}\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/**\n * Add button to the message box\n * @param mbox pointer to message box object\n * @param btn_map button descriptor (button matrix map).\n *                E.g.  a const char *txt[] = {\"ok\", \"close\", \"\"} (Can not be local variable)\n */\nvoid lv_mbox_add_btns(lv_obj_t * mbox, const char ** btn_map)\n{\n    lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);\n\n    /*Create a button matrix if not exists yet*/\n    if(ext->btnm == NULL) {\n        ext->btnm = lv_btnm_create(mbox, NULL);\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_mbox_set_style(mbox, LV_MBOX_STYLE_BTN_BG, th->style.mbox.btn.bg);\n            lv_mbox_set_style(mbox, LV_MBOX_STYLE_BTN_REL, th->style.mbox.btn.rel);\n            lv_mbox_set_style(mbox, LV_MBOX_STYLE_BTN_PR, th->style.mbox.btn.pr);\n        } else {\n            lv_btnm_set_style(ext->btnm, LV_BTNM_STYLE_BG, &lv_style_transp_fit);\n        }\n    }\n\n    lv_btnm_set_map(ext->btnm, btn_map);\n    lv_btnm_set_btn_ctrl_all(ext->btnm, LV_BTNM_CTRL_CLICK_TRIG | LV_BTNM_CTRL_NO_REPEAT);\n    lv_obj_set_event_cb(ext->btnm, lv_mbox_btnm_event_cb);\n\n    mbox_realign(mbox);\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the text of the message box\n * @param mbox pointer to a message box\n * @param txt a '\\0' terminated character string which will be the message box text\n */\nvoid lv_mbox_set_text(lv_obj_t * mbox, const char * txt)\n{\n    lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);\n    lv_label_set_text(ext->text, txt);\n\n    mbox_realign(mbox);\n}\n\n/**\n * Set animation duration\n * @param mbox pointer to a message box object\n * @param anim_time animation length in  milliseconds (0: no animation)\n */\nvoid lv_mbox_set_anim_time(lv_obj_t * mbox, uint16_t anim_time)\n{\n#if LV_USE_ANIMATION\n    lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);\n    anim_time           = 0;\n    ext->anim_time      = anim_time;\n#else\n    (void)mbox;\n    (void)anim_time;\n#endif\n}\n\n/**\n * Automatically delete the message box after a given time\n * @param mbox pointer to a message box object\n * @param delay a time (in milliseconds) to wait before delete the message box\n */\nvoid lv_mbox_start_auto_close(lv_obj_t * mbox, uint16_t delay)\n{\n#if LV_USE_ANIMATION\n    if(lv_mbox_get_anim_time(mbox) != 0) {\n        /*Add shrinking animations*/\n        lv_anim_t a;\n        a.var            = mbox;\n        a.start          = lv_obj_get_height(mbox);\n        a.end            = 0;\n        a.exec_cb        = (lv_anim_exec_xcb_t)lv_obj_set_height;\n        a.path_cb        = lv_anim_path_linear;\n        a.ready_cb       = NULL;\n        a.act_time       = -delay;\n        a.time           = lv_mbox_get_anim_time(mbox);\n        a.playback       = 0;\n        a.playback_pause = 0;\n        a.repeat         = 0;\n        a.repeat_pause   = 0;\n        lv_anim_create(&a);\n\n        a.start    = lv_obj_get_width(mbox);\n        a.exec_cb  = (lv_anim_exec_xcb_t)lv_obj_set_width;\n        a.ready_cb = lv_mbox_close_ready_cb;\n        lv_anim_create(&a);\n\n        /*Disable fit to let shrinking work*/\n        lv_cont_set_fit(mbox, LV_FIT_NONE);\n    } else {\n        /*Create an animation to delete the mbox `delay` ms later*/\n        lv_anim_t a;\n        a.var            = mbox;\n        a.start          = 0;\n        a.end            = 1;\n        a.exec_cb        = (lv_anim_exec_xcb_t)NULL;\n        a.path_cb        = lv_anim_path_linear;\n        a.ready_cb       = lv_mbox_close_ready_cb;\n        a.act_time       = -delay;\n        a.time           = 0;\n        a.playback       = 0;\n        a.playback_pause = 0;\n        a.repeat         = 0;\n        a.repeat_pause   = 0;\n        lv_anim_create(&a);\n    }\n#else\n    (void)delay; /*Unused*/\n    lv_obj_del(mbox);\n#endif\n}\n\n/**\n * Stop the auto. closing of message box\n * @param mbox pointer to a message box object\n */\nvoid lv_mbox_stop_auto_close(lv_obj_t * mbox)\n{\n#if LV_USE_ANIMATION\n    lv_anim_del(mbox, NULL);\n#else\n    (void)mbox; /*Unused*/\n#endif\n}\n\n/**\n * Set a style of a message box\n * @param mbox pointer to a message box object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_mbox_set_style(lv_obj_t * mbox, lv_mbox_style_t type, const lv_style_t * style)\n{\n    lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);\n\n    switch(type) {\n        case LV_MBOX_STYLE_BG: lv_obj_set_style(mbox, style); break;\n        case LV_MBOX_STYLE_BTN_BG: lv_btnm_set_style(ext->btnm, LV_BTNM_STYLE_BG, style); break;\n        case LV_MBOX_STYLE_BTN_REL: lv_btnm_set_style(ext->btnm, LV_BTNM_STYLE_BTN_REL, style); break;\n        case LV_MBOX_STYLE_BTN_PR: lv_btnm_set_style(ext->btnm, LV_BTNM_STYLE_BTN_PR, style); break;\n        case LV_MBOX_STYLE_BTN_TGL_REL: lv_btnm_set_style(ext->btnm, LV_BTNM_STYLE_BTN_TGL_REL, style); break;\n        case LV_MBOX_STYLE_BTN_TGL_PR: lv_btnm_set_style(ext->btnm, LV_BTNM_STYLE_BTN_TGL_PR, style); break;\n        case LV_MBOX_STYLE_BTN_INA: lv_btnm_set_style(ext->btnm, LV_BTNM_STYLE_BTN_INA, style); break;\n    }\n\n    mbox_realign(mbox);\n}\n\n/**\n * Set whether recoloring is enabled\n * @param btnm pointer to button matrix object\n * @param en whether recoloring is enabled\n */\nvoid lv_mbox_set_recolor(lv_obj_t * mbox, bool en)\n{\n    lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);\n\n    if(ext->btnm) lv_btnm_set_recolor(ext->btnm, en);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the text of the message box\n * @param mbox pointer to a message box object\n * @return pointer to the text of the message box\n */\nconst char * lv_mbox_get_text(const lv_obj_t * mbox)\n{\n    lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);\n\n    return lv_label_get_text(ext->text);\n}\n\n/**\n * Get the index of the lastly \"activated\" button by the user (pressed, released etc)\n * Useful in the the `event_cb`.\n * @param btnm pointer to button matrix object\n * @return  index of the last released button (LV_BTNM_BTN_NONE: if unset)\n */\nuint16_t lv_mbox_get_active_btn(lv_obj_t * mbox)\n{\n    lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);\n    if(ext->btnm)\n        return lv_btnm_get_active_btn(ext->btnm);\n    else\n        return LV_BTNM_BTN_NONE;\n}\n\n/**\n * Get the text of the lastly \"activated\" button by the user (pressed, released etc)\n * Useful in the the `event_cb`.\n * @param btnm pointer to button matrix object\n * @return text of the last released button (NULL: if unset)\n */\nconst char * lv_mbox_get_active_btn_text(lv_obj_t * mbox)\n{\n    lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);\n    if(ext->btnm)\n        return lv_btnm_get_active_btn_text(ext->btnm);\n    else\n        return NULL;\n}\n\n/**\n * Get the animation duration (close animation time)\n * @param mbox pointer to a message box object\n * @return animation length in  milliseconds (0: no animation)\n */\nuint16_t lv_mbox_get_anim_time(const lv_obj_t * mbox)\n{\n#if LV_USE_ANIMATION\n    lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);\n    return ext->anim_time;\n#else\n    (void)mbox;\n    return 0;\n#endif\n}\n\n/**\n * Get a style of a message box\n * @param mbox pointer to a message box object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_mbox_get_style(const lv_obj_t * mbox, lv_mbox_style_t type)\n{\n    const lv_style_t * style = NULL;\n    lv_mbox_ext_t * ext      = lv_obj_get_ext_attr(mbox);\n\n    switch(type) {\n        case LV_MBOX_STYLE_BG: style = lv_obj_get_style(mbox); break;\n        case LV_MBOX_STYLE_BTN_BG: style = lv_btnm_get_style(ext->btnm, LV_BTNM_STYLE_BG); break;\n        case LV_MBOX_STYLE_BTN_REL: style = lv_btnm_get_style(ext->btnm, LV_BTNM_STYLE_BTN_REL); break;\n        case LV_MBOX_STYLE_BTN_PR: style = lv_btnm_get_style(ext->btnm, LV_BTNM_STYLE_BTN_PR); break;\n        case LV_MBOX_STYLE_BTN_TGL_REL: style = lv_btnm_get_style(ext->btnm, LV_BTNM_STYLE_BTN_TGL_REL); break;\n        case LV_MBOX_STYLE_BTN_TGL_PR: style = lv_btnm_get_style(ext->btnm, LV_BTNM_STYLE_BTN_TGL_PR); break;\n        case LV_MBOX_STYLE_BTN_INA: style = lv_btnm_get_style(ext->btnm, LV_BTNM_STYLE_BTN_INA); break;\n        default: style = NULL; break;\n    }\n\n    return style;\n}\n\n/**\n * Get whether recoloring is enabled\n * @param mbox pointer to a message box object\n * @return whether recoloring is enabled\n */\nbool lv_mbox_get_recolor(const lv_obj_t * mbox)\n{\n    lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);\n\n    if(!ext->btnm) return false;\n\n    return lv_btnm_get_recolor(ext->btnm);\n}\n\n/**\n * Get message box button matrix\n * @param mbox pointer to a message box object\n * @return pointer to button matrix object\n * @remarks return value will be NULL unless `lv_mbox_add_btns` has been already called\n */\nlv_obj_t * lv_mbox_get_btnm(lv_obj_t * mbox)\n{\n    lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);\n    return ext->btnm;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Signal function of the message box\n * @param mbox pointer to a message box object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /*Translate LV_KEY_UP/DOWN to LV_KEY_LEFT/RIGHT */\n    char c_trans = 0;\n    if(sign == LV_SIGNAL_CONTROL) {\n        c_trans = *((char *)param);\n        if(c_trans == LV_KEY_DOWN) c_trans = LV_KEY_LEFT;\n        if(c_trans == LV_KEY_UP) c_trans = LV_KEY_RIGHT;\n\n        param = &c_trans;\n    }\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(mbox, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);\n    if(sign == LV_SIGNAL_CORD_CHG) {\n        if(lv_obj_get_width(mbox) != lv_area_get_width(param)) {\n            mbox_realign(mbox);\n        }\n    } else if(sign == LV_SIGNAL_STYLE_CHG) {\n        mbox_realign(mbox);\n    } else if(sign == LV_SIGNAL_RELEASED) {\n        if(ext->btnm) {\n            uint32_t btn_id = lv_btnm_get_active_btn(ext->btnm);\n            if(btn_id != LV_BTNM_BTN_NONE) lv_event_send(mbox, LV_EVENT_VALUE_CHANGED, &btn_id);\n        }\n    } else if(sign == LV_SIGNAL_FOCUS || sign == LV_SIGNAL_DEFOCUS || sign == LV_SIGNAL_CONTROL ||\n              sign == LV_SIGNAL_GET_EDITABLE) {\n        if(ext->btnm) {\n            ext->btnm->signal_cb(ext->btnm, sign, param);\n        }\n\n        /* The button matrix with ENCODER input supposes it's in a group but in this case it isn't\n         * (Only the message box's container) So so some actions here instead*/\n        if(sign == LV_SIGNAL_FOCUS) {\n#if LV_USE_GROUP\n            lv_indev_t * indev         = lv_indev_get_act();\n            lv_indev_type_t indev_type = lv_indev_get_type(indev);\n            if(indev_type == LV_INDEV_TYPE_ENCODER) {\n                /*In navigation mode don't select any button but in edit mode select the fist*/\n                lv_btnm_ext_t * btnm_ext = lv_obj_get_ext_attr(ext->btnm);\n                if(lv_group_get_editing(lv_obj_get_group(mbox)))\n                    btnm_ext->btn_id_pr = 0;\n                else\n                    btnm_ext->btn_id_pr = LV_BTNM_BTN_NONE;\n            }\n#endif\n        }\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_mbox\";\n    }\n\n    return res;\n}\n\n/**\n * Resize the button holder to fit\n * @param mbox pointer to message box object\n */\nstatic void mbox_realign(lv_obj_t * mbox)\n{\n    lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);\n\n    const lv_style_t * style = lv_mbox_get_style(mbox, LV_MBOX_STYLE_BG);\n    lv_coord_t w             = lv_obj_get_width(mbox) - style->body.padding.left - style->body.padding.right;\n\n    if(ext->text) {\n        lv_obj_set_width(ext->text, w);\n    }\n\n    if(ext->btnm) {\n        const lv_style_t * btn_bg_style  = lv_mbox_get_style(mbox, LV_MBOX_STYLE_BTN_BG);\n        const lv_style_t * btn_rel_style = lv_mbox_get_style(mbox, LV_MBOX_STYLE_BTN_REL);\n        lv_coord_t font_h                = lv_font_get_line_height(btn_rel_style->text.font);\n        lv_obj_set_size(ext->btnm, w,\n                        font_h + btn_rel_style->body.padding.top + btn_rel_style->body.padding.bottom +\n                            btn_bg_style->body.padding.top + btn_bg_style->body.padding.bottom);\n    }\n}\n\n#if LV_USE_ANIMATION\nstatic void lv_mbox_close_ready_cb(lv_anim_t * a)\n{\n    lv_obj_del(a->var);\n}\n#endif\n\nstatic void lv_mbox_default_event_cb(lv_obj_t * mbox, lv_event_t event)\n{\n    if(event != LV_EVENT_VALUE_CHANGED) return;\n\n    uint32_t btn_id = lv_mbox_get_active_btn(mbox);\n    if(btn_id == LV_BTNM_BTN_NONE) return;\n\n    lv_mbox_start_auto_close(mbox, 0);\n}\n\nstatic void lv_mbox_btnm_event_cb(lv_obj_t * btnm, lv_event_t event)\n{\n    lv_obj_t * mbox = lv_obj_get_parent(btnm);\n\n    /*clang-format off*/\n    if(event == LV_EVENT_PRESSED || event == LV_EVENT_PRESSING || event == LV_EVENT_PRESS_LOST ||\n       event == LV_EVENT_RELEASED || event == LV_EVENT_SHORT_CLICKED || event == LV_EVENT_CLICKED ||\n       event == LV_EVENT_LONG_PRESSED || event == LV_EVENT_LONG_PRESSED_REPEAT ||\n       event == LV_EVENT_VALUE_CHANGED) {\n        lv_event_send(mbox, event, lv_event_get_data());\n    }\n    /*clang-format on*/\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_objx.mk",
    "content": "CSRCS += lv_arc.c\nCSRCS += lv_bar.c\nCSRCS += lv_cb.c\nCSRCS += lv_ddlist.c\nCSRCS += lv_kb.c\nCSRCS += lv_line.c\nCSRCS += lv_mbox.c\nCSRCS += lv_preload.c\nCSRCS += lv_roller.c\nCSRCS += lv_table.c\nCSRCS += lv_tabview.c\nCSRCS += lv_tileview.c\nCSRCS += lv_btn.c\nCSRCS += lv_calendar.c\nCSRCS += lv_chart.c\nCSRCS += lv_canvas.c\nCSRCS += lv_gauge.c\nCSRCS += lv_label.c\nCSRCS += lv_list.c\nCSRCS += lv_slider.c\nCSRCS += lv_ta.c\nCSRCS += lv_spinbox.c\nCSRCS += lv_btnm.c\nCSRCS += lv_cont.c\nCSRCS += lv_img.c\nCSRCS += lv_imgbtn.c\nCSRCS += lv_led.c\nCSRCS += lv_lmeter.c\nCSRCS += lv_page.c\nCSRCS += lv_sw.c\nCSRCS += lv_win.c\n\nDEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_objx\nVPATH += :$(LVGL_DIR)/lvgl/src/lv_objx\n\nCFLAGS += \"-I$(LVGL_DIR)/lvgl/src/lv_objx\"\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_objx_templ.c",
    "content": "/**\n * @file lv_templ.c\n *\n */\n\n/* TODO Remove these instructions\n * Search an replace: template -> object normal name with lower case (e.g. button, label etc.)\n *                    templ -> object short name with lower case(e.g. btn, label etc)\n *                    TEMPL -> object short name with upper case (e.g. BTN, LABEL etc.)\n *\n * You can remove the defined() clause from the #if statement below. This exists because\n * LV_USE_TEMPL is not in lv_conf.h or lv_conf_templ.h by default.\n */\n\n/*********************\n *      INCLUDES\n *********************/\n//#include \"lv_templ.h\" /*TODO uncomment this*/\n\n#if defined(LV_USE_TEMPL) && LV_USE_TEMPL != 0\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_templ_design(lv_obj_t * templ, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_templ_signal(lv_obj_t * templ, lv_signal_t sign, void * param);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_func_t ancestor_signal;\nstatic lv_design_func_t ancestor_design;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a template object\n * @param par pointer to an object, it will be the parent of the new template\n * @param copy pointer to a template object, if not NULL then the new object will be copied from it\n * @return pointer to the created template\n */\nlv_obj_t * lv_templ_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"template create started\");\n\n    /*Create the ancestor of template*/\n    /*TODO modify it to the ancestor create function */\n    lv_obj_t * new_templ = lv_ANCESTOR_create(par, copy);\n    lv_mem_assert(new_templ);\n    if(new_templ == NULL) return NULL;\n\n    /*Allocate the template type specific extended data*/\n    lv_templ_ext_t * ext = lv_obj_allocate_ext_attr(new_templ, sizeof(lv_templ_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_templ);\n    if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_func(new_templ);\n\n    /*Initialize the allocated 'ext' */\n    ext->xyz = 0;\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_func(new_templ, lv_templ_signal);\n    lv_obj_set_design_func(new_templ, lv_templ_design);\n\n    /*Init the new template template*/\n    if(copy == NULL) {\n\n    }\n    /*Copy an existing template*/\n    else {\n        lv_templ_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_templ);\n    }\n\n    LV_LOG_INFO(\"template created\");\n\n    return new_templ;\n}\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/*\n * New object specific \"add\" or \"remove\" functions come here\n */\n\n/*=====================\n * Setter functions\n *====================*/\n\n/*\n * New object specific \"set\" functions come here\n */\n\n/**\n * Set a style of a template.\n * @param templ pointer to template object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_templ_set_style(lv_obj_t * templ, lv_templ_style_t type, const lv_style_t * style)\n{\n    lv_templ_ext_t * ext = lv_obj_get_ext_attr(templ);\n\n    switch(type) {\n        case LV_TEMPL_STYLE_X: break;\n        case LV_TEMPL_STYLE_Y: break;\n    }\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/*\n * New object specific \"get\" functions come here\n */\n\n/**\n * Get style of a template.\n * @param templ pointer to template object\n * @param type which style should be get\n * @return style pointer to the style\n */\nlv_style_t * lv_templ_get_style(const lv_obj_t * templ, lv_templ_style_t type)\n{\n    lv_templ_ext_t * ext = lv_obj_get_ext_attr(templ);\n    lv_style_t * style   = NULL;\n\n    switch(type) {\n        case LV_TEMPL_STYLE_X: style = NULL; /*Replace NULL with a pointer to the style*/\n        case LV_TEMPL_STYLE_Y: style = NULL; /*Replace NULL with a pointer to the style*/\n        default: style = NULL;\n    }\n\n    return style;\n}\n\n/*=====================\n * Other functions\n *====================*/\n\n/*\n * New object specific \"other\" functions come here\n */\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the templates\n * @param templ pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_templ_design(lv_obj_t * templ, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    /*Return false if the object is not covers the mask_p area*/\n    if(mode == LV_DESIGN_COVER_CHK) {\n        return false;\n    }\n    /*Draw the object*/\n    else if(mode == LV_DESIGN_DRAW_MAIN) {\n\n    }\n    /*Post draw when the children are drawn*/\n    else if(mode == LV_DESIGN_DRAW_POST) {\n    }\n\n    return true;\n}\n\n/**\n * Signal function of the template\n * @param templ pointer to a template object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_templ_signal(lv_obj_t * templ, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(templ, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    if(sign == LV_SIGNAL_CLEANUP) {\n        /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_templ\";\n    }\n\n    return res;\n}\n\n#else /* Enable this file at the top */\n\n/* This dummy typedef exists purely to silence -Wpedantic. */\ntypedef int keep_pedantic_happy;\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_page.c",
    "content": "/**\n * @file lv_page.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_page.h\"\n#if LV_USE_PAGE != 0\n\n#include \"libs/lvgl/lv_core/lv_group.h\"\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_core/lv_refr.h\"\n#include \"libs/lvgl/lv_misc/lv_anim.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_PAGE_SB_MIN_SIZE (LV_DPI / 8)\n\n/*[ms] Scroll anim time on `lv_page_scroll_up/down/left/rigth`*/\n#define LV_PAGE_SCROLL_ANIM_TIME 200\n\n#define LV_PAGE_END_FLASH_SIZE (LV_DPI / 4)\n#define LV_PAGE_END_ANIM_TIME 300\n#define LV_PAGE_END_ANIM_WAIT_TIME 300\n\n#if LV_USE_ANIMATION == 0\n#undef LV_PAGE_DEF_ANIM_TIME\n#define LV_PAGE_DEF_ANIM_TIME 0 /*No animation*/\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic void lv_page_sb_refresh(lv_obj_t * page);\nstatic bool lv_page_design(lv_obj_t * page, const lv_area_t * mask, lv_design_mode_t mode);\nstatic bool lv_scrl_design(lv_obj_t * scrl, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param);\nstatic lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, void * param);\nstatic void scrl_def_event_cb(lv_obj_t * scrl, lv_event_t event);\n#if LV_USE_ANIMATION\nstatic void edge_flash_anim(void * page, lv_anim_value_t v);\nstatic void edge_flash_anim_end(lv_anim_t * a);\n#endif\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_design_cb_t ancestor_design;\nstatic lv_signal_cb_t ancestor_signal;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a page objects\n * @param par pointer to an object, it will be the parent of the new page\n * @param copy pointer to a page object, if not NULL then the new object will be copied from it\n * @return pointer to the created page\n */\nlv_obj_t * lv_page_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"page create started\");\n\n    /*Create the ancestor object*/\n    lv_obj_t * new_page = lv_cont_create(par, copy);\n    lv_mem_assert(new_page);\n    if(new_page == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_page);\n    if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_page);\n\n    /*Allocate the object type specific extended data*/\n    lv_page_ext_t * ext = lv_obj_allocate_ext_attr(new_page, sizeof(lv_page_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    ext->scrl        = NULL;\n    ext->sb.hor_draw = 0;\n    ext->sb.ver_draw = 0;\n    ext->sb.style    = &lv_style_pretty;\n    ext->sb.mode     = LV_SB_MODE_AUTO;\n#if LV_USE_ANIMATION\n    ext->edge_flash.enabled   = 0;\n    ext->edge_flash.bottom_ip = 0;\n    ext->edge_flash.top_ip    = 0;\n    ext->edge_flash.left_ip   = 0;\n    ext->edge_flash.right_ip  = 0;\n    ext->edge_flash.state     = 0;\n    ext->edge_flash.style     = &lv_style_plain_color;\n    ext->anim_time            = LV_PAGE_DEF_ANIM_TIME;\n#endif\n    ext->scroll_prop    = 0;\n    ext->scroll_prop_ip = 0;\n\n    /*Init the new page object*/\n    if(copy == NULL) {\n        ext->scrl = lv_cont_create(new_page, NULL);\n        lv_obj_set_signal_cb(ext->scrl, lv_page_scrollable_signal);\n        lv_obj_set_design_cb(ext->scrl, lv_scrl_design);\n        lv_obj_set_drag(ext->scrl, true);\n        lv_obj_set_drag_throw(ext->scrl, true);\n        lv_obj_set_protect(ext->scrl, LV_PROTECT_PARENT | LV_PROTECT_PRESS_LOST);\n        lv_cont_set_fit4(ext->scrl, LV_FIT_FILL, LV_FIT_FILL, LV_FIT_FILL, LV_FIT_FILL);\n        lv_obj_set_event_cb(ext->scrl, scrl_def_event_cb); /*Propagate some event to the background\n                                                              object by default for convenience */\n\n        /* Add the signal function only if 'scrolling' is created\n         * because everything has to be ready before any signal is received*/\n        lv_obj_set_signal_cb(new_page, lv_page_signal);\n        lv_obj_set_design_cb(new_page, lv_page_design);\n\n        lv_page_set_sb_mode(new_page, ext->sb.mode);\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            if(par == NULL) { /*Different styles if it is screen*/\n                lv_page_set_style(new_page, LV_PAGE_STYLE_BG, th->style.bg);\n                lv_page_set_style(new_page, LV_PAGE_STYLE_SCRL, &lv_style_transp);\n            } else {\n                lv_page_set_style(new_page, LV_PAGE_STYLE_BG, th->style.page.bg);\n                lv_page_set_style(new_page, LV_PAGE_STYLE_SCRL, th->style.page.scrl);\n            }\n            lv_page_set_style(new_page, LV_PAGE_STYLE_SB, th->style.page.sb);\n        } else {\n            lv_page_set_style(new_page, LV_PAGE_STYLE_BG, &lv_style_pretty_color);\n            lv_page_set_style(new_page, LV_PAGE_STYLE_SCRL, &lv_style_pretty);\n            lv_page_set_style(new_page, LV_PAGE_STYLE_SB, &lv_style_pretty_color);\n        }\n\n    } else {\n        lv_page_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->scrl                = lv_cont_create(new_page, copy_ext->scrl);\n        lv_obj_set_signal_cb(ext->scrl, lv_page_scrollable_signal);\n\n        lv_page_set_sb_mode(new_page, copy_ext->sb.mode);\n\n        lv_page_set_style(new_page, LV_PAGE_STYLE_BG, lv_page_get_style(copy, LV_PAGE_STYLE_BG));\n        lv_page_set_style(new_page, LV_PAGE_STYLE_SCRL, lv_page_get_style(copy, LV_PAGE_STYLE_SCRL));\n        lv_page_set_style(new_page, LV_PAGE_STYLE_SB, lv_page_get_style(copy, LV_PAGE_STYLE_SB));\n\n        /* Add the signal function only if 'scrolling' is created\n         * because everything has to be ready before any signal is received*/\n        lv_obj_set_signal_cb(new_page, lv_page_signal);\n        lv_obj_set_design_cb(new_page, lv_page_design);\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_page);\n    }\n\n    lv_page_sb_refresh(new_page);\n\n    LV_LOG_INFO(\"page created\");\n\n    return new_page;\n}\n\n/**\n * Delete all children of the scrl object, without deleting scrl child.\n * @param obj pointer to an object\n */\nvoid lv_page_clean(lv_obj_t * obj)\n{\n    lv_obj_t * scrl = lv_page_get_scrl(obj);\n    lv_obj_clean(scrl);\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the scroll bar mode on a page\n * @param page pointer to a page object\n * @param sb_mode the new mode from 'lv_page_sb.mode_t' enum\n */\nvoid lv_page_set_sb_mode(lv_obj_t * page, lv_sb_mode_t sb_mode)\n{\n    lv_page_ext_t * ext = lv_obj_get_ext_attr(page);\n    if(ext->sb.mode == sb_mode) return;\n\n    if(sb_mode == LV_SB_MODE_HIDE)\n        ext->sb.mode |= LV_SB_MODE_HIDE; /*Set the hidden flag*/\n    else if(sb_mode == LV_SB_MODE_UNHIDE)\n        ext->sb.mode &= (~LV_SB_MODE_HIDE); /*Clear the hidden flag*/\n    else {\n        if(ext->sb.mode & LV_SB_MODE_HIDE) sb_mode |= LV_SB_MODE_HIDE;\n        ext->sb.mode = sb_mode;\n    }\n\n    ext->sb.hor_draw = 0;\n    ext->sb.ver_draw = 0;\n\n    lv_page_sb_refresh(page);\n    lv_obj_invalidate(page);\n}\n\n/**\n * Set the animation time for the page\n * @param page pointer to a page object\n * @param anim_time animation time in milliseconds\n */\nvoid lv_page_set_anim_time(lv_obj_t * page, uint16_t anim_time)\n{\n#if LV_USE_ANIMATION\n    lv_page_ext_t * ext = lv_obj_get_ext_attr(page);\n    ext->anim_time      = anim_time;\n#else\n    (void)page;      /*Unused*/\n    (void)anim_time; /*Unused*/\n#endif\n}\n\n/**\n * Enable the scroll propagation feature. If enabled then the page will move its parent if there is\n * no more space to scroll.\n * @param page pointer to a Page\n * @param en true or false to enable/disable scroll propagation\n */\nvoid lv_page_set_scroll_propagation(lv_obj_t * page, bool en)\n{\n    lv_page_ext_t * ext = lv_obj_get_ext_attr(page);\n    ext->scroll_prop    = en ? 1 : 0;\n}\n\n/**\n * Enable the edge flash effect. (Show an arc when the an edge is reached)\n * @param page pointer to a Page\n * @param en true or false to enable/disable end flash\n */\nvoid lv_page_set_edge_flash(lv_obj_t * page, bool en)\n{\n#if LV_USE_ANIMATION\n    lv_page_ext_t * ext     = lv_obj_get_ext_attr(page);\n    ext->edge_flash.enabled = en ? 1 : 0;\n#else\n    (void)page;\n    (void)en;\n#endif\n}\n\n/**\n * Set a style of a page\n * @param page pointer to a page object\n * @param type which style should be set\n * @param style pointer to a style\n *  */\nvoid lv_page_set_style(lv_obj_t * page, lv_page_style_t type, const lv_style_t * style)\n{\n    lv_page_ext_t * ext = lv_obj_get_ext_attr(page);\n\n    switch(type) {\n        case LV_PAGE_STYLE_BG: lv_obj_set_style(page, style); break;\n        case LV_PAGE_STYLE_SCRL: lv_obj_set_style(ext->scrl, style); break;\n        case LV_PAGE_STYLE_SB:\n            ext->sb.style = style;\n            lv_area_set_height(&ext->sb.hor_area, ext->sb.style->body.padding.inner);\n            lv_area_set_width(&ext->sb.ver_area, ext->sb.style->body.padding.inner);\n            lv_page_sb_refresh(page);\n            lv_obj_refresh_ext_draw_pad(page);\n            lv_obj_invalidate(page);\n            break;\n#if LV_USE_ANIMATION\n        case LV_PAGE_STYLE_EDGE_FLASH: ext->edge_flash.style = style; break;\n#endif\n    }\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the scrollable object of a page\n * @param page pointer to a page object\n * @return pointer to a container which is the scrollable part of the page\n */\nlv_obj_t * lv_page_get_scrl(const lv_obj_t * page)\n{\n    lv_page_ext_t * ext = lv_obj_get_ext_attr(page);\n\n    return ext->scrl;\n}\n\n/**\n * Get the animation time\n * @param page pointer to a page object\n * @return the animation time in milliseconds\n */\nuint16_t lv_page_get_anim_time(const lv_obj_t * page)\n{\n#if LV_USE_ANIMATION\n    lv_page_ext_t * ext = lv_obj_get_ext_attr(page);\n    return ext->anim_time;\n#else\n    (void)page; /*Unused*/\n    return 0;\n#endif\n}\n\n/**\n * Set the scroll bar mode on a page\n * @param page pointer to a page object\n * @return the mode from 'lv_page_sb.mode_t' enum\n */\nlv_sb_mode_t lv_page_get_sb_mode(const lv_obj_t * page)\n{\n    lv_page_ext_t * ext = lv_obj_get_ext_attr(page);\n    return ext->sb.mode;\n}\n\n/**\n * Get the scroll propagation property\n * @param page pointer to a Page\n * @return true or false\n */\nbool lv_page_get_scroll_propagation(lv_obj_t * page)\n{\n    lv_page_ext_t * ext = lv_obj_get_ext_attr(page);\n    return ext->scroll_prop == 0 ? false : true;\n}\n\n/**\n * Get the edge flash effect property.\n * @param page pointer to a Page\n * return true or false\n */\nbool lv_page_get_edge_flash(lv_obj_t * page)\n{\n#if LV_USE_ANIMATION\n    lv_page_ext_t * ext = lv_obj_get_ext_attr(page);\n    return ext->edge_flash.enabled == 0 ? false : true;\n#else\n    (void)page;\n    return false;\n#endif\n}\n\n/**\n * Get that width which can be set to the children to still not cause overflow (show scrollbars)\n * @param page pointer to a page object\n * @return the width which still fits into the page\n */\nlv_coord_t lv_page_get_fit_width(lv_obj_t * page)\n{\n    const lv_style_t * bg_style   = lv_page_get_style(page, LV_PAGE_STYLE_BG);\n    const lv_style_t * scrl_style = lv_page_get_style(page, LV_PAGE_STYLE_SCRL);\n\n    return lv_obj_get_width(page) - bg_style->body.padding.left - bg_style->body.padding.right -\n           scrl_style->body.padding.left - scrl_style->body.padding.right;\n}\n\n/**\n * Get that height which can be set to the children to still not cause overflow (show scrollbars)\n * @param page pointer to a page object\n * @return the height which still fits into the page\n */\nlv_coord_t lv_page_get_fit_height(lv_obj_t * page)\n{\n    const lv_style_t * bg_style   = lv_page_get_style(page, LV_PAGE_STYLE_BG);\n    const lv_style_t * scrl_style = lv_page_get_style(page, LV_PAGE_STYLE_SCRL);\n\n    return lv_obj_get_height(page) - bg_style->body.padding.top - bg_style->body.padding.bottom -\n           scrl_style->body.padding.top - scrl_style->body.padding.bottom;\n}\n\n/**\n * Get a style of a page\n * @param page pointer to page object\n * @param type which style should be get\n * @return style pointer to a style\n *  */\nconst lv_style_t * lv_page_get_style(const lv_obj_t * page, lv_page_style_t type)\n{\n    const lv_style_t * style = NULL;\n    lv_page_ext_t * ext      = lv_obj_get_ext_attr(page);\n\n    switch(type) {\n        case LV_PAGE_STYLE_BG: style = lv_obj_get_style(page); break;\n        case LV_PAGE_STYLE_SCRL: style = lv_obj_get_style(ext->scrl); break;\n        case LV_PAGE_STYLE_SB: style = ext->sb.style; break;\n#if LV_USE_ANIMATION\n        case LV_PAGE_STYLE_EDGE_FLASH: style = ext->edge_flash.style; break;\n#endif\n        default: style = NULL; break;\n    }\n\n    return style;\n}\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Find whether the page has been scrolled to a certain edge.\n * @param page Page object\n * @param edge Edge to check\n * @return true if the page is on the specified edge\n */\nbool lv_page_on_edge(lv_obj_t * page, lv_page_edge_t edge)\n{\n    const lv_style_t * page_style = lv_obj_get_style(page);\n    lv_obj_t * scrl               = lv_page_get_scrl(page);\n    lv_area_t page_coords;\n    lv_area_t scrl_coords;\n\n    lv_obj_get_coords(scrl, &scrl_coords);\n    lv_obj_get_coords(page, &page_coords);\n\n    if((edge & LV_PAGE_EDGE_TOP) && scrl_coords.y1 == page_coords.y1 + page_style->body.padding.top) return true;\n    if((edge & LV_PAGE_EDGE_BOTTOM) && scrl_coords.y2 == page_coords.y2 - page_style->body.padding.bottom) return true;\n    if((edge & LV_PAGE_EDGE_LEFT) && scrl_coords.x1 == page_coords.x1 + page_style->body.padding.left) return true;\n    if((edge & LV_PAGE_EDGE_RIGHT) && scrl_coords.x2 == page_coords.x2 - page_style->body.padding.right) return true;\n\n    return false;\n}\n\n/**\n * Glue the object to the page. After it the page can be moved (dragged) with this object too.\n * @param obj pointer to an object on a page\n * @param glue true: enable glue, false: disable glue\n */\nvoid lv_page_glue_obj(lv_obj_t * obj, bool glue)\n{\n    lv_obj_set_drag_parent(obj, glue);\n    lv_obj_set_drag(obj, glue);\n}\n\n/**\n * Focus on an object. It ensures that the object will be visible on the page.\n * @param page pointer to a page object\n * @param obj pointer to an object to focus (must be on the page)\n * @param anim_en LV_ANIM_ON to focus with animation; LV_ANIM_OFF to focus without animation\n */\nvoid lv_page_focus(lv_obj_t * page, const lv_obj_t * obj, lv_anim_enable_t anim_en)\n{\n    lv_page_ext_t * ext = lv_obj_get_ext_attr(page);\n\n#if LV_USE_ANIMATION\n    /* Be sure there is no position changing animation in progress\n     * because it can overide the current changes*/\n    lv_anim_del(page, (lv_anim_exec_xcb_t)lv_obj_set_x);\n    lv_anim_del(page, (lv_anim_exec_xcb_t)lv_obj_set_y);\n    lv_anim_del(ext->scrl, (lv_anim_exec_xcb_t)lv_obj_set_x);\n    lv_anim_del(ext->scrl, (lv_anim_exec_xcb_t)lv_obj_set_y);\n#endif\n\n    const lv_style_t * style      = lv_page_get_style(page, LV_PAGE_STYLE_BG);\n    const lv_style_t * style_scrl = lv_page_get_style(page, LV_PAGE_STYLE_SCRL);\n\n    /*If obj is higher then the page focus where the \"error\" is smaller*/\n    lv_coord_t obj_y      = obj->coords.y1 - ext->scrl->coords.y1;\n    lv_coord_t obj_h      = lv_obj_get_height(obj);\n    lv_coord_t scrlable_y = lv_obj_get_y(ext->scrl);\n    lv_coord_t page_h     = lv_obj_get_height(page);\n\n    lv_coord_t top_err = -(scrlable_y + obj_y);\n    lv_coord_t bot_err = scrlable_y + obj_y + obj_h - page_h;\n\n    /*Out of the page on the top*/\n    if((obj_h <= page_h && top_err > 0) || (obj_h > page_h && top_err < bot_err)) {\n        /*Calculate a new position and let some space above*/\n        scrlable_y = -(obj_y - style_scrl->body.padding.top - style->body.padding.top);\n        scrlable_y += style_scrl->body.padding.top;\n    }\n    /*Out of the page on the bottom*/\n    else if((obj_h <= page_h && bot_err > 0) || (obj_h > page_h && top_err >= bot_err)) {\n        /*Calculate a new position and let some space below*/\n        scrlable_y = -(obj_y + style_scrl->body.padding.bottom + style->body.padding.bottom);\n        scrlable_y -= style_scrl->body.padding.bottom;\n        scrlable_y += page_h - obj_h;\n    }\n\n    /*If obj is wider then the page focus where the \"error\" is smaller*/\n    lv_coord_t obj_x      = obj->coords.x1 - ext->scrl->coords.x1;\n    lv_coord_t obj_w      = lv_obj_get_width(obj);\n    lv_coord_t scrlable_x = lv_obj_get_x(ext->scrl);\n    lv_coord_t page_w     = lv_obj_get_width(page);\n\n    lv_coord_t left_err  = -(scrlable_x + obj_x);\n    lv_coord_t right_err = scrlable_x + obj_x + obj_w - page_w;\n\n    /*Out of the page on the left*/\n    if((obj_w <= page_w && left_err > 0) || (obj_w > page_w && left_err < right_err)) {\n        /*Calculate a new position and let some space above*/\n        scrlable_x = -(obj_x - style_scrl->body.padding.left - style->body.padding.left);\n        scrlable_x += style_scrl->body.padding.left;\n    }\n    /*Out of the page on the rigth*/\n    else if((obj_w <= page_w && right_err > 0) || (obj_w > page_w && left_err >= right_err)) {\n        /*Calculate a new position and let some space below*/\n        scrlable_x = -(obj_x + style_scrl->body.padding.right + style->body.padding.right);\n        scrlable_x -= style_scrl->body.padding.right;\n        scrlable_x += page_w - obj_w;\n    }\n\n    if(anim_en == LV_ANIM_OFF || lv_page_get_anim_time(page) == 0) {\n        lv_obj_set_y(ext->scrl, scrlable_y);\n        lv_obj_set_x(ext->scrl, scrlable_x);\n    } else {\n#if LV_USE_ANIMATION\n        lv_anim_t a;\n        a.act_time = 0;\n        a.start    = lv_obj_get_y(ext->scrl);\n        a.end      = scrlable_y;\n        a.time     = lv_page_get_anim_time(page);\n        a.ready_cb = NULL;\n        a.playback = 0;\n        a.repeat   = 0;\n        a.var      = ext->scrl;\n        a.path_cb  = lv_anim_path_linear;\n        a.exec_cb  = (lv_anim_exec_xcb_t)lv_obj_set_y;\n        lv_anim_create(&a);\n\n        a.start   = lv_obj_get_x(ext->scrl);\n        a.end     = scrlable_x;\n        a.exec_cb = (lv_anim_exec_xcb_t)lv_obj_set_x;\n        lv_anim_create(&a);\n#endif\n    }\n}\n\n/**\n * Scroll the page horizontally\n * @param page pointer to a page object\n * @param dist the distance to scroll (< 0: scroll right; > 0 scroll left)\n */\nvoid lv_page_scroll_hor(lv_obj_t * page, lv_coord_t dist)\n{\n    lv_obj_t * scrl = lv_page_get_scrl(page);\n\n#if LV_USE_ANIMATION\n    lv_anim_t a;\n    a.var            = scrl;\n    a.start          = lv_obj_get_x(scrl);\n    a.end            = a.start + dist;\n    a.exec_cb        = (lv_anim_exec_xcb_t)lv_obj_set_x;\n    a.path_cb        = lv_anim_path_linear;\n    a.ready_cb       = NULL;\n    a.act_time       = 0;\n    a.time           = LV_PAGE_SCROLL_ANIM_TIME;\n    a.playback       = 0;\n    a.playback_pause = 0;\n    a.repeat         = 0;\n    a.repeat_pause   = 0;\n    lv_anim_create(&a);\n#else\n    lv_obj_set_x(scrl, lv_obj_get_x(scrl) + dist);\n#endif\n}\n\n/**\n * Scroll the page vertically\n * @param page pointer to a page object\n * @param dist the distance to scroll (< 0: scroll down; > 0 scroll up)\n */\nvoid lv_page_scroll_ver(lv_obj_t * page, lv_coord_t dist)\n{\n    lv_obj_t * scrl = lv_page_get_scrl(page);\n\n#if LV_USE_ANIMATION\n    lv_anim_t a;\n    a.var            = scrl;\n    a.start          = lv_obj_get_y(scrl);\n    a.end            = a.start + dist;\n    a.exec_cb        = (lv_anim_exec_xcb_t)lv_obj_set_y;\n    a.path_cb        = lv_anim_path_linear;\n    a.ready_cb       = NULL;\n    a.act_time       = 0;\n    a.time           = LV_PAGE_SCROLL_ANIM_TIME;\n    a.playback       = 0;\n    a.playback_pause = 0;\n    a.repeat         = 0;\n    a.repeat_pause   = 0;\n    lv_anim_create(&a);\n#else\n    lv_obj_set_y(scrl, lv_obj_get_y(scrl) + dist);\n#endif\n}\n\n/**\n * Not intended to use directly by the user but by other object types internally.\n * Start an edge flash animation. Exactly one `ext->edge_flash.xxx_ip` should be set\n * @param page\n */\nvoid lv_page_start_edge_flash(lv_obj_t * page)\n{\n#if LV_USE_ANIMATION\n    lv_page_ext_t * ext = lv_obj_get_ext_attr(page);\n    if(ext->edge_flash.enabled) {\n        lv_anim_t a;\n        a.var            = page;\n        a.start          = 0;\n        a.end            = LV_PAGE_END_FLASH_SIZE;\n        a.exec_cb        = (lv_anim_exec_xcb_t)edge_flash_anim;\n        a.path_cb        = lv_anim_path_linear;\n        a.ready_cb       = edge_flash_anim_end;\n        a.act_time       = 0;\n        a.time           = LV_PAGE_END_ANIM_TIME;\n        a.playback       = 1;\n        a.playback_pause = LV_PAGE_END_ANIM_WAIT_TIME;\n        a.repeat         = 0;\n        a.repeat_pause   = 0;\n        lv_anim_create(&a);\n    }\n#else\n    (void)page; /*Unused*/\n#endif\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the pages\n * @param page pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_page_design(lv_obj_t * page, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    if(mode == LV_DESIGN_COVER_CHK) {\n        return ancestor_design(page, mask, mode);\n    }\n    /*Cache page bg style for temporary modification*/\n    const lv_style_t * style = lv_page_get_style(page, LV_PAGE_STYLE_BG);\n    lv_style_t style_tmp;\n    lv_style_copy(&style_tmp, style);\n\n    if(mode == LV_DESIGN_DRAW_MAIN) {\n        /*Draw without border*/\n        style_tmp.body.border.width = 0;\n        lv_draw_rect(&page->coords, mask, &style_tmp, lv_obj_get_opa_scale(page));\n\n    } else if(mode == LV_DESIGN_DRAW_POST) {\n        /*Draw only a border*/\n        style_tmp.body.shadow.width = 0;\n        style_tmp.body.opa          = LV_OPA_TRANSP;\n        lv_draw_rect(&page->coords, mask, &style_tmp, lv_obj_get_opa_scale(page));\n\n        lv_page_ext_t * ext = lv_obj_get_ext_attr(page);\n\n        /*Draw the scrollbars*/\n        lv_area_t sb_area;\n        if(ext->sb.hor_draw && (ext->sb.mode & LV_SB_MODE_HIDE) == 0) {\n            /*Convert the relative coordinates to absolute*/\n            lv_area_copy(&sb_area, &ext->sb.hor_area);\n            sb_area.x1 += page->coords.x1;\n            sb_area.y1 += page->coords.y1;\n            sb_area.x2 += page->coords.x1;\n            sb_area.y2 += page->coords.y1;\n            lv_draw_rect(&sb_area, mask, ext->sb.style, lv_obj_get_opa_scale(page));\n        }\n\n        if(ext->sb.ver_draw && (ext->sb.mode & LV_SB_MODE_HIDE) == 0) {\n            /*Convert the relative coordinates to absolute*/\n            lv_area_copy(&sb_area, &ext->sb.ver_area);\n            sb_area.x1 += page->coords.x1;\n            sb_area.y1 += page->coords.y1;\n            sb_area.x2 += page->coords.x1;\n            sb_area.y2 += page->coords.y1;\n            lv_draw_rect(&sb_area, mask, ext->sb.style, lv_obj_get_opa_scale(page));\n        }\n\n#if LV_USE_ANIMATION\n        {\n            lv_coord_t page_w = lv_obj_get_width(page);\n            lv_coord_t page_h = lv_obj_get_height(page);\n\n            lv_area_t flash_area;\n\n            if(ext->edge_flash.top_ip) {\n                flash_area.x1 = page->coords.x1 - page_w;\n                flash_area.x2 = page->coords.x2 + page_w;\n                flash_area.y1 = page->coords.y1 - 3 * page_w + ext->edge_flash.state;\n                flash_area.y2 = page->coords.y1 + ext->edge_flash.state;\n            } else if(ext->edge_flash.bottom_ip) {\n                flash_area.x1 = page->coords.x1 - page_w;\n                flash_area.x2 = page->coords.x2 + page_w;\n                flash_area.y1 = page->coords.y2 - ext->edge_flash.state;\n                flash_area.y2 = page->coords.y2 + 3 * page_w - ext->edge_flash.state;\n            } else if(ext->edge_flash.right_ip) {\n                flash_area.x1 = page->coords.x2 - ext->edge_flash.state;\n                flash_area.x2 = page->coords.x2 + 3 * page_h - ext->edge_flash.state;\n                flash_area.y1 = page->coords.y1 - page_h;\n                flash_area.y2 = page->coords.y2 + page_h;\n            } else if(ext->edge_flash.left_ip) {\n                flash_area.x1 = page->coords.x1 - 3 * page_h + ext->edge_flash.state;\n                flash_area.x2 = page->coords.x1 + ext->edge_flash.state;\n                flash_area.y1 = page->coords.y1 - page_h;\n                flash_area.y2 = page->coords.y2 + page_h;\n            }\n\n            if(ext->edge_flash.left_ip || ext->edge_flash.right_ip || ext->edge_flash.top_ip ||\n               ext->edge_flash.bottom_ip) {\n                lv_style_t flash_style;\n                lv_style_copy(&flash_style, ext->edge_flash.style);\n                flash_style.body.radius = LV_RADIUS_CIRCLE;\n                uint32_t opa            = (flash_style.body.opa * ext->edge_flash.state) / LV_PAGE_END_FLASH_SIZE;\n                flash_style.body.opa    = opa;\n                lv_draw_rect(&flash_area, mask, &flash_style, lv_obj_get_opa_scale(page));\n            }\n        }\n#endif\n    }\n\n    return true;\n}\n\n/**\n * Handle the drawing related tasks of the scrollable object\n * @param scrl pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_scrl_design(lv_obj_t * scrl, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    if(mode == LV_DESIGN_COVER_CHK) {\n        return ancestor_design(scrl, mask, mode);\n    } else if(mode == LV_DESIGN_DRAW_MAIN) {\n#if LV_USE_GROUP\n        /* If the page is focused in a group and\n         * the background object is not visible (transparent)\n         * then \"activate\" the style of the scrollable*/\n        const lv_style_t * style_scrl_ori = lv_obj_get_style(scrl);\n        lv_obj_t * page                   = lv_obj_get_parent(scrl);\n        const lv_style_t * style_page     = lv_obj_get_style(page);\n        lv_group_t * g                    = lv_obj_get_group(page);\n        if((style_page->body.opa == LV_OPA_TRANSP) &&\n           style_page->body.border.width == 0) { /*Is the background visible?*/\n            if(lv_group_get_focused(g) == page) {\n                lv_style_t * style_mod;\n                style_mod = lv_group_mod_style(g, style_scrl_ori);\n                /*If still not visible modify the style a littel bit*/\n                if((style_mod->body.opa == LV_OPA_TRANSP) && style_mod->body.border.width == 0) {\n                    style_mod->body.opa          = LV_OPA_50;\n                    style_mod->body.border.width = 1;\n                    style_mod                    = lv_group_mod_style(g, style_mod);\n                }\n\n                scrl->style_p = style_mod; /*Temporally change the style to the activated */\n            }\n        }\n#endif\n        ancestor_design(scrl, mask, mode);\n\n#if LV_USE_GROUP\n        scrl->style_p = style_scrl_ori; /*Revert the style*/\n#endif\n    } else if(mode == LV_DESIGN_DRAW_POST) {\n        ancestor_design(scrl, mask, mode);\n    }\n\n    return true;\n}\n\n/**\n * Signal function of the page\n * @param page pointer to a page object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(page, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_page_ext_t * ext = lv_obj_get_ext_attr(page);\n    lv_obj_t * child;\n    if(sign == LV_SIGNAL_CHILD_CHG) { /*Automatically move children to the scrollable object*/\n        const lv_style_t * style = lv_page_get_style(page, LV_PAGE_STYLE_SCRL);\n        lv_fit_t fit_left        = lv_page_get_scrl_fit_left(page);\n        lv_fit_t fit_top         = lv_page_get_scrl_fit_top(page);\n        child                    = lv_obj_get_child(page, NULL);\n        while(child != NULL) {\n            if(lv_obj_is_protected(child, LV_PROTECT_PARENT) == false) {\n                lv_obj_t * tmp = child;\n                child          = lv_obj_get_child(page, child); /*Get the next child before move this*/\n\n                /* Reposition the child to take padding into account (Only if it's on (0;0) now)\n                 * It's required to keep new the object on the same coordinate if FIT is enabled.*/\n                if((tmp->coords.x1 == page->coords.x1) && (fit_left == LV_FIT_TIGHT || fit_left == LV_FIT_FILL)) {\n                    tmp->coords.x1 += style->body.padding.left;\n                    tmp->coords.x2 += style->body.padding.left;\n                }\n                if((tmp->coords.y1 == page->coords.y1) && (fit_top == LV_FIT_TIGHT || fit_top == LV_FIT_FILL)) {\n                    tmp->coords.y1 += style->body.padding.top;\n                    tmp->coords.y2 += style->body.padding.top;\n                }\n                lv_obj_set_parent(tmp, ext->scrl);\n            } else {\n                child = lv_obj_get_child(page, child);\n            }\n        }\n    } else if(sign == LV_SIGNAL_STYLE_CHG) {\n        ext->scrl->signal_cb(ext->scrl, LV_SIGNAL_CORD_CHG, &ext->scrl->coords);\n\n        /*The scrollbars are important only if they are visible now*/\n        if(ext->sb.hor_draw || ext->sb.ver_draw) lv_page_sb_refresh(page);\n\n        /*Refresh the ext. size because the scrollbars might be positioned out of the page*/\n        lv_obj_refresh_ext_draw_pad(page);\n    } else if(sign == LV_SIGNAL_CORD_CHG) {\n        /*Refresh the scrollbar and notify the scrl if the size is changed*/\n        if(ext->scrl != NULL && (lv_obj_get_width(page) != lv_area_get_width(param) ||\n                                 lv_obj_get_height(page) != lv_area_get_height(param))) {\n            /*If no hor_fit enabled set the scrollable's width to the page's width*/\n            ext->scrl->signal_cb(ext->scrl, LV_SIGNAL_CORD_CHG, &ext->scrl->coords);\n\n            /*The scrollbars are important only if they are visible now*/\n            if(ext->sb.hor_draw || ext->sb.ver_draw) lv_page_sb_refresh(page);\n        }\n    } else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {\n        /*Ensure ext. size for the scrollbars if they are out of the page*/\n        if(page->ext_draw_pad < (-ext->sb.style->body.padding.right))\n            page->ext_draw_pad = -ext->sb.style->body.padding.right;\n        if(page->ext_draw_pad < (-ext->sb.style->body.padding.bottom))\n            page->ext_draw_pad = -ext->sb.style->body.padding.bottom;\n    } else if(sign == LV_SIGNAL_CONTROL) {\n        uint32_t c = *((uint32_t *)param);\n\n        if(c == LV_KEY_DOWN) {\n            lv_page_scroll_ver(page, -lv_obj_get_height(page) / 4);\n        } else if(c == LV_KEY_UP) {\n            lv_page_scroll_ver(page, lv_obj_get_height(page) / 4);\n        } else if(c == LV_KEY_RIGHT) {\n            /*If the page can't be scrolled horizontally because it's not wide enough then scroll it\n             * vertically*/\n            if(lv_page_get_scrl_width(page) <= lv_obj_get_width(page))\n                lv_page_scroll_ver(page, -lv_obj_get_height(page) / 4);\n            else\n                lv_page_scroll_hor(page, -lv_obj_get_width(page) / 4);\n        } else if(c == LV_KEY_LEFT) {\n            /*If the page can't be scrolled horizontally because it's not wide enough then scroll it\n             * vertically*/\n            if(lv_page_get_scrl_width(page) <= lv_obj_get_width(page))\n                lv_page_scroll_ver(page, lv_obj_get_height(page) / 4);\n            else\n                lv_page_scroll_hor(page, lv_obj_get_width(page) / 4);\n        }\n    } else if(sign == LV_SIGNAL_GET_EDITABLE) {\n        bool * editable = (bool *)param;\n        *editable       = true;\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_page\";\n    }\n\n    return res;\n}\n\n/**\n * Signal function of the scrollable part of a page\n * @param scrl pointer to the scrollable object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(scrl, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_obj_t * page               = lv_obj_get_parent(scrl);\n    const lv_style_t * page_style = lv_obj_get_style(page);\n    lv_page_ext_t * page_ext      = lv_obj_get_ext_attr(page);\n\n    if(sign == LV_SIGNAL_CORD_CHG) {\n        /*Limit the position of the scrollable object to be always visible\n         * (Do not let its edge inner then its parent respective edge)*/\n        lv_coord_t new_x = lv_obj_get_x(scrl);\n        lv_coord_t new_y = lv_obj_get_y(scrl);\n        bool refr_x      = false;\n        bool refr_y      = false;\n        lv_area_t page_coords;\n        lv_area_t scrl_coords;\n        lv_obj_get_coords(scrl, &scrl_coords);\n        lv_obj_get_coords(page, &page_coords);\n\n        lv_area_t * ori_coords = (lv_area_t *)param;\n        lv_coord_t diff_x      = scrl->coords.x1 - ori_coords->x1;\n        lv_coord_t diff_y      = scrl->coords.y1 - ori_coords->y1;\n        lv_coord_t hpad        = page_style->body.padding.left + page_style->body.padding.right;\n        lv_coord_t vpad        = page_style->body.padding.top + page_style->body.padding.bottom;\n        lv_obj_t * page_parent = lv_obj_get_parent(page);\n\n        lv_indev_t * indev = lv_indev_get_act();\n        lv_point_t drag_vect;\n        lv_indev_get_vect(indev, &drag_vect);\n\n        /* Start the scroll propagation if there is drag vector on the indev, but the drag is not\n         * started yet and the scrollable is in a corner. It will enable the scroll propagation only\n         * when a new scroll begins and not when the scrollable is already being scrolled.*/\n        if(page_ext->scroll_prop && page_ext->scroll_prop_ip == 0 && lv_indev_is_dragging(indev) == false) {\n            if(((drag_vect.y > 0 && scrl_coords.y1 == page_coords.y1 + page_style->body.padding.top) ||\n                (drag_vect.y < 0 && scrl_coords.y2 == page_coords.y2 - page_style->body.padding.bottom)) &&\n               ((drag_vect.x > 0 && scrl_coords.x1 == page_coords.x1 + page_style->body.padding.left) ||\n                (drag_vect.x < 0 && scrl_coords.x2 == page_coords.x2 - page_style->body.padding.right))) {\n\n                if(lv_obj_get_parent(page_parent) != NULL) { /*Do not propagate the scroll to a screen*/\n                    page_ext->scroll_prop_ip = 1;\n                }\n            }\n        }\n\n        /*scrollable width smaller then page width? -> align to left*/\n        if(lv_area_get_width(&scrl_coords) + hpad <= lv_area_get_width(&page_coords)) {\n            if(scrl_coords.x1 != page_coords.x1 + page_style->body.padding.left) {\n                new_x  = page_style->body.padding.left;\n                refr_x = true;\n            }\n        } else {\n            /*If the scroll propagation is in progress revert the original coordinates (don't let\n             * the page scroll)*/\n            if(page_ext->scroll_prop_ip) {\n                if(drag_vect.x == diff_x) { /*`scrl` is bouncing: drag pos. it somewhere and here it\n                                               is reverted. Handle only the pos. because of drag*/\n                    new_x  = ori_coords->x1 - page_coords.x1;\n                    refr_x = true;\n                }\n            }\n            /*The edges of the scrollable can not be in the page (minus hpad) */\n            else if(scrl_coords.x2 < page_coords.x2 - page_style->body.padding.right) {\n                new_x = lv_area_get_width(&page_coords) - lv_area_get_width(&scrl_coords) -\n                        page_style->body.padding.right; /* Right align */\n                refr_x = true;\n#if LV_USE_ANIMATION\n                if(page_ext->edge_flash.enabled && page_ext->edge_flash.left_ip == 0 &&\n                   page_ext->edge_flash.right_ip == 0 && page_ext->edge_flash.top_ip == 0 &&\n                   page_ext->edge_flash.bottom_ip == 0) {\n                    lv_page_start_edge_flash(page);\n                    page_ext->edge_flash.right_ip = 1;\n                }\n#endif\n            } else if(scrl_coords.x1 > page_coords.x1 + page_style->body.padding.left) {\n                new_x  = page_style->body.padding.left; /*Left align*/\n                refr_x = true;\n#if LV_USE_ANIMATION\n                if(page_ext->edge_flash.enabled && page_ext->edge_flash.left_ip == 0 &&\n                   page_ext->edge_flash.right_ip == 0 && page_ext->edge_flash.top_ip == 0 &&\n                   page_ext->edge_flash.bottom_ip == 0) {\n                    lv_page_start_edge_flash(page);\n                    page_ext->edge_flash.left_ip = 1;\n                }\n#endif\n            }\n        }\n\n        /*scrollable height smaller then page height? -> align to top*/\n        if(lv_area_get_height(&scrl_coords) + vpad <= lv_area_get_height(&page_coords)) {\n            if(scrl_coords.y1 != page_coords.y1 + page_style->body.padding.top) {\n                new_y  = page_style->body.padding.top;\n                refr_y = true;\n            }\n        } else {\n            /*If the scroll propagation is in progress revert the original coordinates (don't let\n             * the page scroll)*/\n            if(page_ext->scroll_prop_ip) {\n                if(drag_vect.y == diff_y) { /*`scrl` is bouncing: drag pos. it somewhere and here it\n                                               is reverted. Handle only the pos. because of drag*/\n                    new_y  = ori_coords->y1 - page_coords.y1;\n                    refr_y = true;\n                }\n            }\n            /*The edges of the scrollable can not be in the page (minus vpad) */\n            else if(scrl_coords.y2 < page_coords.y2 - page_style->body.padding.bottom) {\n                new_y = lv_area_get_height(&page_coords) - lv_area_get_height(&scrl_coords) -\n                        page_style->body.padding.bottom; /* Bottom align */\n                refr_y = true;\n#if LV_USE_ANIMATION\n                if(page_ext->edge_flash.enabled && page_ext->edge_flash.left_ip == 0 &&\n                   page_ext->edge_flash.right_ip == 0 && page_ext->edge_flash.top_ip == 0 &&\n                   page_ext->edge_flash.bottom_ip == 0) {\n                    lv_page_start_edge_flash(page);\n                    page_ext->edge_flash.bottom_ip = 1;\n                }\n#endif\n            } else if(scrl_coords.y1 > page_coords.y1 + page_style->body.padding.top) {\n                new_y  = page_style->body.padding.top; /*Top align*/\n                refr_y = true;\n#if LV_USE_ANIMATION\n                if(page_ext->edge_flash.enabled && page_ext->edge_flash.left_ip == 0 &&\n                   page_ext->edge_flash.right_ip == 0 && page_ext->edge_flash.top_ip == 0 &&\n                   page_ext->edge_flash.bottom_ip == 0) {\n                    lv_page_start_edge_flash(page);\n                    page_ext->edge_flash.top_ip = 1;\n                }\n#endif\n            }\n        }\n\n        if(refr_x || refr_y) {\n            lv_obj_set_pos(scrl, new_x, new_y);\n\n            if(page_ext->scroll_prop_ip) {\n                if(refr_y) lv_obj_set_y(page_parent, lv_obj_get_y(page_parent) + diff_y);\n                if(refr_x) lv_obj_set_x(page_parent, lv_obj_get_x(page_parent) + diff_x);\n            }\n        }\n\n        lv_page_sb_refresh(page);\n    } else if(sign == LV_SIGNAL_DRAG_END) {\n\n        /*Scroll propagation is finished on drag end*/\n        page_ext->scroll_prop_ip = 0;\n\n        /*Hide scrollbars if required*/\n        if(page_ext->sb.mode == LV_SB_MODE_DRAG) {\n            lv_disp_t * disp = lv_obj_get_disp(page);\n            lv_area_t sb_area_tmp;\n            if(page_ext->sb.hor_draw) {\n                lv_area_copy(&sb_area_tmp, &page_ext->sb.hor_area);\n                sb_area_tmp.x1 += page->coords.x1;\n                sb_area_tmp.y1 += page->coords.y1;\n                sb_area_tmp.x2 += page->coords.x1;\n                sb_area_tmp.y2 += page->coords.y1;\n                lv_inv_area(disp, &sb_area_tmp);\n                page_ext->sb.hor_draw = 0;\n            }\n            if(page_ext->sb.ver_draw) {\n                lv_area_copy(&sb_area_tmp, &page_ext->sb.ver_area);\n                sb_area_tmp.x1 += page->coords.x1;\n                sb_area_tmp.y1 += page->coords.y1;\n                sb_area_tmp.x2 += page->coords.x1;\n                sb_area_tmp.y2 += page->coords.y1;\n                lv_inv_area(disp, &sb_area_tmp);\n                page_ext->sb.ver_draw = 0;\n            }\n        }\n    }\n\n    return res;\n}\n\n/**\n * Propagate the input device related event of the scrollable to the parent page background\n * It is used by default if the scrollable's event is not specified\n * @param scrl pointer to the page's scrollable object\n * @param event type of the event\n * @param data data of the event\n */\nstatic void scrl_def_event_cb(lv_obj_t * scrl, lv_event_t event)\n{\n    lv_obj_t * page = lv_obj_get_parent(scrl);\n\n    /*clang-format off*/\n    if(event == LV_EVENT_PRESSED || event == LV_EVENT_PRESSING || event == LV_EVENT_PRESS_LOST ||\n       event == LV_EVENT_RELEASED || event == LV_EVENT_SHORT_CLICKED || event == LV_EVENT_CLICKED ||\n       event == LV_EVENT_LONG_PRESSED || event == LV_EVENT_LONG_PRESSED_REPEAT ||\n       event == LV_EVENT_DRAG_BEGIN || event == LV_EVENT_DRAG_END || event == LV_EVENT_DRAG_THROW_BEGIN) {\n        lv_event_send(page, event, lv_event_get_data());\n    }\n    /*clang-format on*/\n}\n\n/**\n * Refresh the position and size of the scroll bars.\n * @param page pointer to a page object\n */\nstatic void lv_page_sb_refresh(lv_obj_t * page)\n{\n    lv_page_ext_t * ext      = lv_obj_get_ext_attr(page);\n    const lv_style_t * style = lv_obj_get_style(page);\n    lv_obj_t * scrl          = ext->scrl;\n    lv_coord_t size_tmp;\n    lv_coord_t scrl_w = lv_obj_get_width(scrl);\n    lv_coord_t scrl_h = lv_obj_get_height(scrl);\n    lv_coord_t obj_w  = lv_obj_get_width(page);\n    lv_coord_t obj_h  = lv_obj_get_height(page);\n\n    /*Always let 'scrollbar width' padding above, under, left and right to the scrollbars\n     * else:\n     * - horizontal and vertical scrollbars can overlap on the corners\n     * - if the page has radius the scrollbar can be out of the radius  */\n    lv_coord_t sb_hor_pad = LV_MATH_MAX(ext->sb.style->body.padding.inner, style->body.padding.right);\n    lv_coord_t sb_ver_pad = LV_MATH_MAX(ext->sb.style->body.padding.inner, style->body.padding.bottom);\n\n    if(ext->sb.mode == LV_SB_MODE_OFF) return;\n\n    if(ext->sb.mode == LV_SB_MODE_ON) {\n        ext->sb.hor_draw = 1;\n        ext->sb.ver_draw = 1;\n    }\n\n    /*Invalidate the current (old) scrollbar areas*/\n    lv_disp_t * disp = lv_obj_get_disp(page);\n    lv_area_t sb_area_tmp;\n    if(ext->sb.hor_draw != 0) {\n        lv_area_copy(&sb_area_tmp, &ext->sb.hor_area);\n        sb_area_tmp.x1 += page->coords.x1;\n        sb_area_tmp.y1 += page->coords.y1;\n        sb_area_tmp.x2 += page->coords.x1;\n        sb_area_tmp.y2 += page->coords.y1;\n        lv_inv_area(disp, &sb_area_tmp);\n    }\n    if(ext->sb.ver_draw != 0) {\n        lv_area_copy(&sb_area_tmp, &ext->sb.ver_area);\n        sb_area_tmp.x1 += page->coords.x1;\n        sb_area_tmp.y1 += page->coords.y1;\n        sb_area_tmp.x2 += page->coords.x1;\n        sb_area_tmp.y2 += page->coords.y1;\n        lv_inv_area(disp, &sb_area_tmp);\n    }\n\n    if(ext->sb.mode == LV_SB_MODE_DRAG && lv_indev_is_dragging(lv_indev_get_act()) == false) {\n        ext->sb.hor_draw = 0;\n        ext->sb.ver_draw = 0;\n        return;\n    }\n\n    /*Full sized horizontal scrollbar*/\n    if(scrl_w <= obj_w - style->body.padding.left - style->body.padding.right) {\n        lv_area_set_width(&ext->sb.hor_area, obj_w - 2 * sb_hor_pad);\n        lv_area_set_pos(&ext->sb.hor_area, sb_hor_pad,\n                        obj_h - ext->sb.style->body.padding.inner - ext->sb.style->body.padding.bottom);\n        if(ext->sb.mode == LV_SB_MODE_AUTO || ext->sb.mode == LV_SB_MODE_DRAG) ext->sb.hor_draw = 0;\n    }\n    /*Smaller horizontal scrollbar*/\n    else {\n        size_tmp =\n            (obj_w * (obj_w - (2 * sb_hor_pad))) / (scrl_w + style->body.padding.left + style->body.padding.right);\n        if(size_tmp < LV_PAGE_SB_MIN_SIZE) size_tmp = LV_PAGE_SB_MIN_SIZE;\n        lv_area_set_width(&ext->sb.hor_area, size_tmp);\n\n        lv_area_set_pos(&ext->sb.hor_area,\n                        sb_hor_pad +\n                            (-(lv_obj_get_x(scrl) - style->body.padding.left) * (obj_w - size_tmp - 2 * sb_hor_pad)) /\n                                (scrl_w + style->body.padding.left + style->body.padding.right - obj_w),\n                        obj_h - ext->sb.style->body.padding.inner - ext->sb.style->body.padding.bottom);\n\n        if(ext->sb.mode == LV_SB_MODE_AUTO || ext->sb.mode == LV_SB_MODE_DRAG) ext->sb.hor_draw = 1;\n    }\n\n    /*Full sized vertical scroll bar*/\n    if(scrl_h <= obj_h - style->body.padding.top - style->body.padding.bottom) {\n        lv_area_set_height(&ext->sb.ver_area, obj_h - 2 * sb_ver_pad);\n        lv_area_set_pos(&ext->sb.ver_area,\n                        obj_w - ext->sb.style->body.padding.inner - ext->sb.style->body.padding.right, sb_ver_pad);\n        if(ext->sb.mode == LV_SB_MODE_AUTO || ext->sb.mode == LV_SB_MODE_DRAG) ext->sb.ver_draw = 0;\n    }\n    /*Smaller vertical scroll bar*/\n    else {\n        size_tmp =\n            (obj_h * (obj_h - (2 * sb_ver_pad))) / (scrl_h + style->body.padding.top + style->body.padding.bottom);\n        if(size_tmp < LV_PAGE_SB_MIN_SIZE) size_tmp = LV_PAGE_SB_MIN_SIZE;\n        lv_area_set_height(&ext->sb.ver_area, size_tmp);\n\n        lv_area_set_pos(&ext->sb.ver_area,\n                        obj_w - ext->sb.style->body.padding.inner - ext->sb.style->body.padding.right,\n                        sb_ver_pad + (-(lv_obj_get_y(scrl) - ext->sb.style->body.padding.bottom) *\n                                      (obj_h - size_tmp - 2 * sb_ver_pad)) /\n                                         (scrl_h + style->body.padding.top + style->body.padding.bottom - obj_h));\n\n        if(ext->sb.mode == LV_SB_MODE_AUTO || ext->sb.mode == LV_SB_MODE_DRAG) ext->sb.ver_draw = 1;\n    }\n\n    /*Invalidate the new scrollbar areas*/\n    if(ext->sb.hor_draw != 0) {\n        lv_area_copy(&sb_area_tmp, &ext->sb.hor_area);\n        sb_area_tmp.x1 += page->coords.x1;\n        sb_area_tmp.y1 += page->coords.y1;\n        sb_area_tmp.x2 += page->coords.x1;\n        sb_area_tmp.y2 += page->coords.y1;\n        lv_inv_area(disp, &sb_area_tmp);\n    }\n    if(ext->sb.ver_draw != 0) {\n        lv_area_copy(&sb_area_tmp, &ext->sb.ver_area);\n        sb_area_tmp.x1 += page->coords.x1;\n        sb_area_tmp.y1 += page->coords.y1;\n        sb_area_tmp.x2 += page->coords.x1;\n        sb_area_tmp.y2 += page->coords.y1;\n        lv_inv_area(disp, &sb_area_tmp);\n    }\n}\n\n#if LV_USE_ANIMATION\nstatic void edge_flash_anim(void * page, lv_anim_value_t v)\n{\n    lv_page_ext_t * ext   = lv_obj_get_ext_attr(page);\n    ext->edge_flash.state = v;\n    lv_obj_invalidate(page);\n}\n\nstatic void edge_flash_anim_end(lv_anim_t * a)\n{\n    lv_page_ext_t * ext       = lv_obj_get_ext_attr(a->var);\n    ext->edge_flash.top_ip    = 0;\n    ext->edge_flash.bottom_ip = 0;\n    ext->edge_flash.left_ip   = 0;\n    ext->edge_flash.right_ip  = 0;\n    lv_obj_invalidate(a->var);\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_preload.c",
    "content": "/**\n * @file lv_preload.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_preload.h\"\n#if LV_USE_PRELOAD != 0\n\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n#include \"libs/lvgl/lv_draw/lv_draw_rect.h\"\n#include \"libs/lvgl/lv_draw/lv_draw_arc.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#ifndef LV_PRELOAD_DEF_ARC_LENGTH\n#define LV_PRELOAD_DEF_ARC_LENGTH 60 /*[deg]*/\n#endif\n\n#ifndef LV_PRELOAD_DEF_SPIN_TIME\n#define LV_PRELOAD_DEF_SPIN_TIME 1000 /*[ms]*/\n#endif\n\n#ifndef LV_PRELOAD_DEF_ANIM\n#define LV_PRELOAD_DEF_ANIM LV_PRELOAD_TYPE_SPINNING_ARC /*animation type*/\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_preload_design(lv_obj_t * preload, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_preload_signal(lv_obj_t * preload, lv_signal_t sign, void * param);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\nstatic lv_design_cb_t ancestor_design;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a pre loader object\n * @param par pointer to an object, it will be the parent of the new pre loader\n * @param copy pointer to a pre loader object, if not NULL then the new object will be copied from\n * it\n * @return pointer to the created pre loader\n */\nlv_obj_t * lv_preload_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"preload create started\");\n\n    /*Create the ancestor of pre loader*/\n    lv_obj_t * new_preload = lv_arc_create(par, copy);\n    lv_mem_assert(new_preload);\n    if(new_preload == NULL) return NULL;\n\n    /*Allocate the pre loader type specific extended data*/\n    lv_preload_ext_t * ext = lv_obj_allocate_ext_attr(new_preload, sizeof(lv_preload_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_preload);\n    if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_preload);\n\n    /*Initialize the allocated 'ext' */\n    ext->arc_length = LV_PRELOAD_DEF_ARC_LENGTH;\n    ext->anim_type  = LV_PRELOAD_DEF_ANIM;\n    ext->anim_dir   = LV_PRELOAD_DIR_FORWARD;\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_cb(new_preload, lv_preload_signal);\n    lv_obj_set_design_cb(new_preload, lv_preload_design);\n\n    /*Init the new pre loader pre loader*/\n    if(copy == NULL) {\n        lv_obj_set_size(new_preload, LV_DPI / 2, LV_DPI / 2);\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_preload_set_style(new_preload, LV_PRELOAD_STYLE_MAIN, th->style.preload);\n        } else {\n            lv_obj_set_style(new_preload, &lv_style_pretty_color);\n        }\n\n        ext->time = LV_PRELOAD_DEF_SPIN_TIME;\n\n    }\n    /*Copy an existing pre loader*/\n    else {\n        lv_preload_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->arc_length             = copy_ext->arc_length;\n        ext->time                   = copy_ext->time;\n        ext->anim_dir               = copy_ext->anim_dir;\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_preload);\n    }\n\n    lv_preload_set_type(new_preload, ext->anim_type);\n\n    LV_LOG_INFO(\"preload created\");\n\n    return new_preload;\n}\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/**\n * Set the length of the spinning  arc in degrees\n * @param preload pointer to a preload object\n * @param deg length of the arc\n */\nvoid lv_preload_set_arc_length(lv_obj_t * preload, lv_anim_value_t deg)\n{\n    lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload);\n\n    ext->arc_length = deg;\n}\n\n/**\n * Set the spin time of the arc\n * @param preload pointer to a preload object\n * @param time time of one round in milliseconds\n */\nvoid lv_preload_set_spin_time(lv_obj_t * preload, uint16_t time)\n{\n    lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload);\n\n    ext->time = time;\n    lv_preload_set_type(preload, ext->anim_type);\n}\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a style of a pre loader.\n * @param preload pointer to pre loader object\n * @param type which style should be set\n * @param style pointer to a style\n *  */\nvoid lv_preload_set_style(lv_obj_t * preload, lv_preload_style_t type, const lv_style_t * style)\n{\n    switch(type) {\n        case LV_PRELOAD_STYLE_MAIN: lv_arc_set_style(preload, LV_ARC_STYLE_MAIN, style); break;\n    }\n}\n\n/**\n * Set the animation type of a preloadeer.\n * @param preload pointer to pre loader object\n * @param type animation type of the preload\n *  */\nvoid lv_preload_set_type(lv_obj_t * preload, lv_preload_type_t type)\n{\n    lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload);\n\n    /*delete previous animation*/\n    lv_anim_del(preload, NULL);\n    switch(type) {\n        case LV_PRELOAD_TYPE_FILLSPIN_ARC: {\n            ext->anim_type = LV_PRELOAD_TYPE_FILLSPIN_ARC;\n            lv_anim_t a;\n            a.var = preload;\n            if(ext->anim_dir == LV_PRELOAD_DIR_FORWARD) {\n                /* Clockwise */\n                a.start = 360;\n                a.end   = 0;\n            } else {\n                a.start = 0;\n                a.end   = 360;\n            }\n            a.exec_cb        = (lv_anim_exec_xcb_t)lv_preload_spinner_anim;\n            a.path_cb        = lv_anim_path_ease_in_out;\n            a.ready_cb       = NULL;\n            a.act_time       = 0;\n            a.time           = ext->time;\n            a.playback       = 0;\n            a.playback_pause = 0;\n            a.repeat         = 1;\n            a.repeat_pause   = 0;\n            lv_anim_create(&a);\n\n            lv_anim_t b;\n            b.var = preload;\n            if(ext->anim_dir == LV_PRELOAD_DIR_FORWARD) {\n                /* Clockwise */\n                b.start = 360 - ext->arc_length;\n                b.end   = ext->arc_length;\n            } else {\n                b.start = ext->arc_length;\n                b.end   = 360 - ext->arc_length;\n            }\n            b.exec_cb        = (lv_anim_exec_xcb_t)lv_preload_set_arc_length;\n            b.path_cb        = lv_anim_path_ease_in_out;\n            b.ready_cb       = NULL;\n            b.act_time       = 0;\n            b.time           = ext->time;\n            b.playback       = 1;\n            b.playback_pause = 0;\n            b.repeat         = 1;\n            b.repeat_pause   = 0;\n            lv_anim_create(&b);\n            break;\n        }\n        case LV_PRELOAD_TYPE_SPINNING_ARC:\n        default: {\n            ext->anim_type = LV_PRELOAD_TYPE_SPINNING_ARC;\n            lv_anim_t a;\n            a.var = preload;\n            if(ext->anim_dir == LV_PRELOAD_DIR_FORWARD) {\n                /* Clockwise */\n                a.start = 360;\n                a.end   = 0;\n            } else {\n                a.start = 0;\n                a.end   = 360;\n            }\n            a.exec_cb        = (lv_anim_exec_xcb_t)lv_preload_spinner_anim;\n            a.path_cb        = lv_anim_path_ease_in_out;\n            a.ready_cb       = NULL;\n            a.act_time       = 0;\n            a.time           = ext->time;\n            a.playback       = 0;\n            a.playback_pause = 0;\n            a.repeat         = 1;\n            a.repeat_pause   = 0;\n            lv_anim_create(&a);\n            break;\n        }\n    }\n}\n\nvoid lv_preload_set_dir(lv_obj_t * preload, lv_preload_dir_t dir)\n{\n    lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload);\n\n    ext->anim_dir = dir;\n    lv_preload_set_type(preload, ext->anim_type);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the arc length [degree] of the a pre loader\n * @param preload pointer to a pre loader object\n */\nlv_anim_value_t lv_preload_get_arc_length(const lv_obj_t * preload)\n{\n    lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload);\n    return ext->arc_length;\n}\n\n/**\n * Get the spin time of the arc\n * @param preload pointer to a pre loader object [milliseconds]\n */\nuint16_t lv_preload_get_spin_time(const lv_obj_t * preload)\n{\n    lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload);\n    return ext->time;\n}\n\n/**\n * Get style of a pre loader.\n * @param preload pointer to pre loader object\n * @param type which style should be get\n * @return style pointer to the style\n *  */\nconst lv_style_t * lv_preload_get_style(const lv_obj_t * preload, lv_preload_style_t type)\n{\n    const lv_style_t * style = NULL;\n\n    switch(type) {\n        case LV_PRELOAD_STYLE_MAIN: style = lv_arc_get_style(preload, LV_ARC_STYLE_MAIN); break;\n        default: style = NULL; break;\n    }\n\n    return style;\n}\n\n/**\n * Get the animation type of a preloadeer.\n * @param preload pointer to pre loader object\n * @return animation type\n *  */\nlv_preload_type_t lv_preload_get_type(lv_obj_t * preload)\n{\n    lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload);\n    return ext->anim_type;\n}\n\nlv_preload_dir_t lv_preload_get_dir(lv_obj_t * preload)\n{\n    lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload);\n    return ext->anim_dir;\n}\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Animator function  (exec_cb) to rotate the arc of spinner.\n * @param ptr pointer to preloader\n * @param val the current desired value [0..360]\n */\nvoid lv_preload_spinner_anim(void * ptr, lv_anim_value_t val)\n{\n    lv_obj_t * preload     = ptr;\n    lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload);\n\n    int16_t angle_start = val - ext->arc_length / 2 + 180;\n    int16_t angle_end   = angle_start + ext->arc_length;\n\n    angle_start = angle_start % 360;\n    angle_end   = angle_end % 360;\n\n    lv_arc_set_angles(preload, angle_start, angle_end);\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the pre loaders\n * @param preload pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_preload_design(lv_obj_t * preload, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    /*Return false if the object is not covers the mask_p area*/\n    if(mode == LV_DESIGN_COVER_CHK) {\n        return false;\n    }\n    /*Draw the object*/\n    else if(mode == LV_DESIGN_DRAW_MAIN) {\n\n        /*Draw a circle as background*/\n        const lv_style_t * style = lv_arc_get_style(preload, LV_ARC_STYLE_MAIN);\n        if(style->body.border.width > 0) {\n            lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(preload), lv_obj_get_height(preload))) / 2;\n            r -= LV_MATH_MIN(style->body.padding.left, style->body.padding.top);\n\n            lv_coord_t x = preload->coords.x1 + lv_obj_get_width(preload) / 2;\n            lv_coord_t y = preload->coords.y1 + lv_obj_get_height(preload) / 2;\n\n            lv_style_t bg_style;\n            lv_style_copy(&bg_style, &lv_style_plain);\n            bg_style.body.opa          = LV_OPA_TRANSP;\n            bg_style.body.radius       = LV_RADIUS_CIRCLE;\n            bg_style.body.border.color = style->body.border.color;\n            bg_style.body.border.width = style->body.border.width;\n\n            lv_area_t bg_area;\n            bg_area.x1 = x - r;\n            bg_area.y1 = y - r;\n            bg_area.x2 = x + r;\n            bg_area.y2 = y + r;\n\n            lv_draw_rect(&bg_area, mask, &bg_style, lv_obj_get_opa_scale(preload));\n        }\n        /*Draw the arc above the background circle */\n        ancestor_design(preload, mask, mode);\n    }\n    /*Post draw when the children are drawn*/\n    else if(mode == LV_DESIGN_DRAW_POST) {\n    }\n\n    return true;\n}\n\n/**\n * Signal function of the pre loader\n * @param preload pointer to a pre loader object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_preload_signal(lv_obj_t * preload, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(preload, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    if(sign == LV_SIGNAL_CLEANUP) {\n        /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_preload\";\n    }\n\n    return res;\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_roller.c",
    "content": "/**\n * @file lv_roller.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_roller.h\"\n#if LV_USE_ROLLER != 0\n\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_core/lv_group.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#if LV_USE_ANIMATION == 0\n#undef LV_ROLLER_DEF_ANIM_TIME\n#define LV_ROLLER_DEF_ANIM_TIME 0 /*No animation*/\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_roller_design(lv_obj_t * roller, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_roller_scrl_signal(lv_obj_t * roller_scrl, lv_signal_t sign, void * param);\nstatic lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * param);\nstatic void refr_position(lv_obj_t * roller, lv_anim_enable_t animen);\nstatic void refr_height(lv_obj_t * roller);\nstatic void inf_normalize(void * roller_scrl);\n#if LV_USE_ANIMATION\nstatic void scroll_anim_ready_cb(lv_anim_t * a);\n#endif\nstatic void draw_bg(lv_obj_t * roller, const lv_area_t * mask);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\nstatic lv_signal_cb_t ancestor_scrl_signal;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a roller object\n * @param par pointer to an object, it will be the parent of the new roller\n * @param copy pointer to a roller object, if not NULL then the new object will be copied from it\n * @return pointer to the created roller\n */\nlv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"roller create started\");\n\n    /*Create the ancestor of roller*/\n    lv_obj_t * new_roller = lv_ddlist_create(par, copy);\n    lv_mem_assert(new_roller);\n    if(new_roller == NULL) return NULL;\n\n    if(ancestor_scrl_signal == NULL) ancestor_scrl_signal = lv_obj_get_signal_cb(lv_page_get_scrl(new_roller));\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_roller);\n\n    /*Allocate the roller type specific extended data*/\n    lv_roller_ext_t * ext = lv_obj_allocate_ext_attr(new_roller, sizeof(lv_roller_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n    ext->ddlist.draw_arrow = 0; /*Do not draw arrow by default*/\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_cb(new_roller, lv_roller_signal);\n    lv_obj_set_design_cb(new_roller, lv_roller_design);\n\n    /*Init the new roller roller*/\n    if(copy == NULL) {\n        lv_obj_t * scrl = lv_page_get_scrl(new_roller);\n        lv_obj_set_drag(scrl, true);                                  /*In ddlist it might be disabled*/\n        lv_page_set_scrl_fit2(new_roller, LV_FIT_TIGHT, LV_FIT_NONE); /*Height is specified directly*/\n        lv_ddlist_open(new_roller, false);\n        lv_ddlist_set_anim_time(new_roller, LV_ROLLER_DEF_ANIM_TIME);\n        lv_ddlist_set_stay_open(new_roller, true);\n        lv_roller_set_visible_row_count(new_roller, 3);\n        lv_label_set_align(ext->ddlist.label, LV_LABEL_ALIGN_CENTER);\n\n        lv_obj_set_signal_cb(scrl, lv_roller_scrl_signal);\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_roller_set_style(new_roller, LV_ROLLER_STYLE_BG, th->style.roller.bg);\n            lv_roller_set_style(new_roller, LV_ROLLER_STYLE_SEL, th->style.roller.sel);\n        } else {\n            /*Refresh the roller's style*/\n            lv_obj_refresh_style(new_roller); /*To set scrollable size automatically*/\n        }\n    }\n    /*Copy an existing roller*/\n    else {\n        lv_roller_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->mode                  = copy_ext->mode;\n\n        lv_obj_t * scrl = lv_page_get_scrl(new_roller);\n        lv_ddlist_open(new_roller, false);\n        lv_obj_set_signal_cb(scrl, lv_roller_scrl_signal);\n\n        /*Refresh the roller's style*/\n        lv_obj_refresh_style(new_roller); /*Refresh the style with new signal function*/\n    }\n\n    LV_LOG_INFO(\"roller created\");\n\n    return new_roller;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the options on a roller\n * @param roller pointer to roller object\n * @param options a string with '\\n' separated options. E.g. \"One\\nTwo\\nThree\"\n * @param mode `LV_ROLLER_MODE_NORMAL` or `LV_ROLLER_MODE_INFINITE`\n */\nvoid lv_roller_set_options(lv_obj_t * roller, const char * options, lv_roller_mode_t mode)\n{\n    lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);\n\n    if(mode == LV_ROLLER_MODE_NORMAL) {\n        ext->mode = LV_ROLLER_MODE_NORMAL;\n        lv_ddlist_set_options(roller, options);\n\n        /* Make sure the roller's height and the scrollable's height is refreshed.\n         * They are refreshed in `LV_SIGNAL_COORD_CHG` but if the new options has the same width\n         * that signal won't be called. (It called because LV_FIT_TIGHT hor fit)*/\n        refr_height(roller);\n    } else {\n        ext->mode = LV_ROLLER_MODE_INIFINITE;\n\n        uint32_t opt_len = strlen(options) + 1; /*+1 to add '\\n' after option lists*/\n        char * opt_extra = lv_mem_alloc(opt_len * LV_ROLLER_INF_PAGES);\n        uint8_t i;\n        for(i = 0; i < LV_ROLLER_INF_PAGES; i++) {\n            strcpy(&opt_extra[opt_len * i], options);\n            opt_extra[opt_len * (i + 1) - 1] = '\\n';\n        }\n        opt_extra[opt_len * LV_ROLLER_INF_PAGES - 1] = '\\0';\n        lv_ddlist_set_options(roller, opt_extra);\n        lv_mem_free(opt_extra);\n\n        /* Make sure the roller's height and the scrollable's height is refreshed.\n         * They are refreshed in `LV_SIGNAL_COORD_CHG` but if the new options has the same width\n         * that signal won't be called. (It called because LV_FIT_TIGHT hor fit)*/\n        refr_height(roller);\n\n        uint16_t real_id_cnt = ext->ddlist.option_cnt / LV_ROLLER_INF_PAGES;\n        lv_roller_set_selected(roller, ((LV_ROLLER_INF_PAGES / 2) + 1) * real_id_cnt, false); /*Select the middle page*/\n    }\n}\n\n/**\n * Set the align of the roller's options (left or center)\n * @param roller - pointer to a roller object\n * @param align - one of lv_label_align_t values (left, right, center)\n */\nvoid lv_roller_set_align(lv_obj_t * roller, lv_label_align_t align)\n{\n    lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);\n    lv_mem_assert(ext);\n    if(ext->ddlist.label == NULL) return; /*Probably the roller is being deleted if the label is NULL.*/\n    lv_label_set_align(ext->ddlist.label, align);\n}\n\n/**\n * Set the selected option\n * @param roller pointer to a roller object\n * @param sel_opt id of the selected option (0 ... number of option - 1);\n * @param anim_en LV_ANIM_ON: set with animation; LV_ANOM_OFF set immediately\n */\nvoid lv_roller_set_selected(lv_obj_t * roller, uint16_t sel_opt, lv_anim_enable_t anim)\n{\n#if LV_USE_ANIMATION == 0\n    anim = LV_ANIM_OFF;\n#endif\n\n    if(lv_roller_get_selected(roller) == sel_opt) return;\n\n    lv_ddlist_set_selected(roller, sel_opt);\n    refr_position(roller, anim);\n}\n\n/**\n * Set the height to show the given number of rows (options)\n * @param roller pointer to a roller object\n * @param row_cnt number of desired visible rows\n */\nvoid lv_roller_set_visible_row_count(lv_obj_t * roller, uint8_t row_cnt)\n{\n    lv_roller_ext_t * ext          = lv_obj_get_ext_attr(roller);\n    const lv_style_t * style_label = lv_obj_get_style(ext->ddlist.label);\n    uint8_t n_line_space           = (row_cnt > 1) ? row_cnt - 1 : 1;\n    lv_ddlist_set_fix_height(roller, lv_font_get_line_height(style_label->text.font) * row_cnt +\n                                         style_label->text.line_space * n_line_space);\n}\n\n/**\n * Set a style of a roller\n * @param roller pointer to a roller object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_roller_set_style(lv_obj_t * roller, lv_roller_style_t type, const lv_style_t * style)\n{\n    switch(type) {\n        case LV_ROLLER_STYLE_BG: lv_obj_set_style(roller, style); break;\n        case LV_ROLLER_STYLE_SEL: lv_ddlist_set_style(roller, LV_DDLIST_STYLE_SEL, style); break;\n    }\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the id of the selected option\n * @param roller pointer to a roller object\n * @return id of the selected option (0 ... number of option - 1);\n */\nuint16_t lv_roller_get_selected(const lv_obj_t * roller)\n{\n    lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);\n    if(ext->mode == LV_ROLLER_MODE_INIFINITE) {\n        uint16_t real_id_cnt = ext->ddlist.option_cnt / LV_ROLLER_INF_PAGES;\n        return lv_ddlist_get_selected(roller) % real_id_cnt;\n    } else {\n        return lv_ddlist_get_selected(roller);\n    }\n}\n\n/**\n * Get the align attribute. Default alignment after _create is LV_LABEL_ALIGN_CENTER\n * @param roller pointer to a roller object\n * @return LV_LABEL_ALIGN_LEFT, LV_LABEL_ALIGN_RIGHT or LV_LABEL_ALIGN_CENTER\n */\nlv_label_align_t lv_roller_get_align(const lv_obj_t * roller)\n{\n    lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);\n    lv_mem_assert(ext);\n    lv_mem_assert(ext->ddlist.label);\n    return lv_label_get_align(ext->ddlist.label);\n}\n\n/**\n * Get the auto width set attribute\n * @param roller pointer to a roller object\n * @return true: auto size enabled; false: manual width settings enabled\n */\nbool lv_roller_get_hor_fit(const lv_obj_t * roller)\n{\n    return lv_page_get_scrl_fit_left(roller);\n}\n\n/**\n * Get a style of a roller\n * @param roller pointer to a roller object\n * @param type which style should be get\n * @return style pointer to a style\n *  */\nconst lv_style_t * lv_roller_get_style(const lv_obj_t * roller, lv_roller_style_t type)\n{\n    switch(type) {\n        case LV_ROLLER_STYLE_BG: return lv_obj_get_style(roller);\n        case LV_ROLLER_STYLE_SEL: return lv_ddlist_get_style(roller, LV_DDLIST_STYLE_SEL);\n        default: return NULL;\n    }\n\n    /*To avoid warning*/\n    return NULL;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the rollers\n * @param roller pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_roller_design(lv_obj_t * roller, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    /*Return false if the object is not covers the mask_p area*/\n    if(mode == LV_DESIGN_COVER_CHK) {\n        return false;\n    }\n    /*Draw the object*/\n    else if(mode == LV_DESIGN_DRAW_MAIN) {\n        draw_bg(roller, mask);\n\n        const lv_style_t * style = lv_roller_get_style(roller, LV_ROLLER_STYLE_BG);\n        lv_opa_t opa_scale       = lv_obj_get_opa_scale(roller);\n        const lv_font_t * font   = style->text.font;\n        lv_roller_ext_t * ext    = lv_obj_get_ext_attr(roller);\n        lv_coord_t font_h        = lv_font_get_line_height(font);\n        lv_area_t rect_area;\n        rect_area.y1 = roller->coords.y1 + lv_obj_get_height(roller) / 2 - font_h / 2 - style->text.line_space / 2;\n        if((font_h & 0x1) && (style->text.line_space & 0x1)) rect_area.y1--; /*Compensate the two rounding error*/\n        rect_area.y2 = rect_area.y1 + font_h + style->text.line_space - 1;\n        lv_area_t roller_coords;\n        lv_obj_get_coords(roller, &roller_coords);\n        lv_obj_get_inner_coords(roller, &roller_coords);\n\n        rect_area.x1 = roller_coords.x1;\n        rect_area.x2 = roller_coords.x2;\n\n        lv_draw_rect(&rect_area, mask, ext->ddlist.sel_style, opa_scale);\n    }\n    /*Post draw when the children are drawn*/\n    else if(mode == LV_DESIGN_DRAW_POST) {\n        const lv_style_t * style = lv_roller_get_style(roller, LV_ROLLER_STYLE_BG);\n        lv_roller_ext_t * ext    = lv_obj_get_ext_attr(roller);\n        const lv_font_t * font   = style->text.font;\n        lv_coord_t font_h        = lv_font_get_line_height(font);\n        lv_opa_t opa_scale       = lv_obj_get_opa_scale(roller);\n\n        /*Redraw the text on the selected area with a different color*/\n        lv_area_t rect_area;\n        rect_area.y1 = roller->coords.y1 + lv_obj_get_height(roller) / 2 - font_h / 2 - style->text.line_space / 2;\n        if((font_h & 0x1) && (style->text.line_space & 0x1)) rect_area.y1--; /*Compensate the two rounding error*/\n        rect_area.y2 = rect_area.y1 + font_h + style->text.line_space - 1;\n        rect_area.x1 = roller->coords.x1;\n        rect_area.x2 = roller->coords.x2;\n        lv_area_t mask_sel;\n        bool area_ok;\n        area_ok = lv_area_intersect(&mask_sel, mask, &rect_area);\n        if(area_ok) {\n            const lv_style_t * sel_style = lv_roller_get_style(roller, LV_ROLLER_STYLE_SEL);\n            lv_style_t new_style;\n            lv_txt_flag_t txt_align = LV_TXT_FLAG_NONE;\n\n            {\n                lv_label_align_t label_align = lv_label_get_align(ext->ddlist.label);\n\n                if(LV_LABEL_ALIGN_CENTER == label_align) {\n                    txt_align |= LV_TXT_FLAG_CENTER;\n                } else if(LV_LABEL_ALIGN_RIGHT == label_align) {\n                    txt_align |= LV_TXT_FLAG_RIGHT;\n                }\n            }\n\n            lv_style_copy(&new_style, style);\n            new_style.text.color = sel_style->text.color;\n            new_style.text.opa   = sel_style->text.opa;\n            lv_draw_label(&ext->ddlist.label->coords, &mask_sel, &new_style, opa_scale,\n                          lv_label_get_text(ext->ddlist.label), txt_align, NULL, -1, -1, NULL);\n        }\n    }\n\n    return true;\n}\n\n/**\n * Signal function of the roller\n * @param roller pointer to a roller object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * param)\n{\n    lv_res_t res = LV_RES_OK;\n\n    /*Don't let the drop down list to handle the control signals. It works differently*/\n    if(sign != LV_SIGNAL_CONTROL && sign != LV_SIGNAL_FOCUS && sign != LV_SIGNAL_DEFOCUS) {\n        /* Include the ancient signal function */\n        res = ancestor_signal(roller, sign, param);\n        if(res != LV_RES_OK) return res;\n    }\n\n    lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);\n\n    if(sign == LV_SIGNAL_STYLE_CHG) {\n        refr_height(roller);\n\n        refr_position(roller, false);\n    } else if(sign == LV_SIGNAL_CORD_CHG) {\n\n        if(lv_obj_get_width(roller) != lv_area_get_width(param) ||\n           lv_obj_get_height(roller) != lv_area_get_height(param)) {\n\n            refr_height(roller);\n#if LV_USE_ANIMATION\n            lv_anim_del(lv_page_get_scrl(roller), (lv_anim_exec_xcb_t)lv_obj_set_y);\n#endif\n            lv_ddlist_set_selected(roller, ext->ddlist.sel_opt_id);\n            refr_position(roller, false);\n        }\n    } else if(sign == LV_SIGNAL_FOCUS) {\n#if LV_USE_GROUP\n        lv_group_t * g             = lv_obj_get_group(roller);\n        bool editing               = lv_group_get_editing(g);\n        lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());\n\n        /*Encoders need special handling*/\n        if(indev_type == LV_INDEV_TYPE_ENCODER) {\n            /*In navigate mode revert the original value*/\n            if(!editing) {\n                if(ext->ddlist.sel_opt_id != ext->ddlist.sel_opt_id_ori) {\n                    ext->ddlist.sel_opt_id = ext->ddlist.sel_opt_id_ori;\n                    refr_position(roller, true);\n                }\n            }\n            /*Save the current state when entered to edit mode*/\n            else {\n                ext->ddlist.sel_opt_id_ori = ext->ddlist.sel_opt_id;\n            }\n        } else {\n            ext->ddlist.sel_opt_id_ori = ext->ddlist.sel_opt_id; /*Save the current value. Used to revert this state if\n                                                                    ENER wont't be pressed*/\n        }\n#endif\n    } else if(sign == LV_SIGNAL_DEFOCUS) {\n#if LV_USE_GROUP\n        /*Revert the original state*/\n        if(ext->ddlist.sel_opt_id != ext->ddlist.sel_opt_id_ori) {\n            ext->ddlist.sel_opt_id = ext->ddlist.sel_opt_id_ori;\n            refr_position(roller, true);\n        }\n#endif\n    } else if(sign == LV_SIGNAL_CONTROL) {\n        char c = *((char *)param);\n        if(c == LV_KEY_RIGHT || c == LV_KEY_DOWN) {\n            if(ext->ddlist.sel_opt_id + 1 < ext->ddlist.option_cnt) {\n                uint16_t ori_id = ext->ddlist.sel_opt_id_ori; /*lv_roller_set_selceted will overwrite this*/\n                lv_roller_set_selected(roller, ext->ddlist.sel_opt_id + 1, true);\n                ext->ddlist.sel_opt_id_ori = ori_id;\n            }\n        } else if(c == LV_KEY_LEFT || c == LV_KEY_UP) {\n            if(ext->ddlist.sel_opt_id > 0) {\n                uint16_t ori_id = ext->ddlist.sel_opt_id_ori; /*lv_roller_set_selceted will overwrite this*/\n                lv_roller_set_selected(roller, ext->ddlist.sel_opt_id - 1, true);\n                ext->ddlist.sel_opt_id_ori = ori_id;\n            }\n        }\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_roller\";\n    }\n\n    return res;\n}\n\n/**\n * Signal function of the scrollable part of the roller.\n * @param roller_scrl ointer to the scrollable part of roller (page)\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_roller_scrl_signal(lv_obj_t * roller_scrl, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_scrl_signal(roller_scrl, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_indev_t * indev    = lv_indev_get_act();\n    int32_t id            = -1;\n    lv_obj_t * roller     = lv_obj_get_parent(roller_scrl);\n    lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);\n\n    if(ext->ddlist.label == NULL)\n        return LV_RES_INV; /*On delete the ddlist signal deletes the label so nothing left to do\n                              here*/\n\n    const lv_style_t * style_label = lv_obj_get_style(ext->ddlist.label);\n    const lv_font_t * font         = style_label->text.font;\n    lv_coord_t font_h              = lv_font_get_line_height(font);\n\n    if(sign == LV_SIGNAL_DRAG_END) {\n        /*If dragged then align the list to there be an element in the middle*/\n        lv_coord_t label_y1   = ext->ddlist.label->coords.y1 - roller->coords.y1;\n        lv_coord_t label_unit = font_h + style_label->text.line_space;\n        lv_coord_t mid        = (roller->coords.y2 - roller->coords.y1) / 2;\n\n        id = (mid - label_y1 + style_label->text.line_space / 2) / label_unit;\n\n        if(id < 0) id = 0;\n        if(id >= ext->ddlist.option_cnt) id = ext->ddlist.option_cnt - 1;\n\n        ext->ddlist.sel_opt_id     = id;\n        ext->ddlist.sel_opt_id_ori = id;\n        res                        = lv_event_send(roller, LV_EVENT_VALUE_CHANGED, &id);\n        if(res != LV_RES_OK) return res;\n    }\n    /*If picked an option by clicking then set it*/\n    else if(sign == LV_SIGNAL_RELEASED) {\n        if(!lv_indev_is_dragging(indev)) {\n            id = ext->ddlist.sel_opt_id;\n#if LV_USE_GROUP\n            /*In edit mode go to navigate mode if an option is selected*/\n            lv_group_t * g = lv_obj_get_group(roller);\n            bool editing   = lv_group_get_editing(g);\n            if(editing) lv_group_set_editing(g, false);\n#endif\n        }\n    } else if(sign == LV_SIGNAL_PRESSED) {\n#if LV_USE_ANIMATION\n        lv_anim_del(roller_scrl, (lv_anim_exec_xcb_t)lv_obj_set_y);\n#endif\n    }\n\n    /*Position the scrollable according to the new selected option*/\n    if(id != -1) {\n        refr_position(roller, true);\n    }\n\n    return res;\n}\n\n/**\n * Draw a rectangle which has gradient on its top and bottom\n * @param roller pointer to a roller object\n * @param mask pointer to the current mask (from the design function)\n */\nstatic void draw_bg(lv_obj_t * roller, const lv_area_t * mask)\n{\n    const lv_style_t * style = lv_roller_get_style(roller, LV_ROLLER_STYLE_BG);\n    lv_area_t half_mask;\n    lv_area_t half_roller;\n    lv_coord_t h = lv_obj_get_height(roller);\n    bool union_ok;\n    lv_area_copy(&half_roller, &roller->coords);\n\n    half_roller.x1 -= roller->ext_draw_pad; /*Add ext size too (e.g. because of shadow draw) */\n    half_roller.x2 += roller->ext_draw_pad;\n    half_roller.y1 -= roller->ext_draw_pad;\n    half_roller.y2 = roller->coords.y1 + h / 2;\n\n    union_ok = lv_area_intersect(&half_mask, &half_roller, mask);\n\n    half_roller.x1 += roller->ext_draw_pad; /*Revert ext. size adding*/\n    half_roller.x2 -= roller->ext_draw_pad;\n    half_roller.y1 += roller->ext_draw_pad;\n    half_roller.y2 += style->body.radius;\n\n    if(union_ok) {\n        lv_draw_rect(&half_roller, &half_mask, style, lv_obj_get_opa_scale(roller));\n    }\n\n    half_roller.x1 -= roller->ext_draw_pad; /*Add ext size too (e.g. because of shadow draw) */\n    half_roller.x2 += roller->ext_draw_pad;\n    half_roller.y2 = roller->coords.y2 + roller->ext_draw_pad;\n    half_roller.y1 = roller->coords.y1 + h / 2;\n    if((h & 0x1) == 0) half_roller.y1++; /*With even height the pixels in the middle would be drawn twice*/\n\n    union_ok = lv_area_intersect(&half_mask, &half_roller, mask);\n\n    half_roller.x1 += roller->ext_draw_pad; /*Revert ext. size adding*/\n    half_roller.x2 -= roller->ext_draw_pad;\n    half_roller.y2 -= roller->ext_draw_pad;\n    half_roller.y1 -= style->body.radius;\n\n    if(union_ok) {\n        lv_style_t style_tmp;\n        memcpy(&style_tmp, style, sizeof(lv_style_t));\n        style_tmp.body.main_color = style->body.grad_color;\n        style_tmp.body.grad_color = style->body.main_color;\n        lv_draw_rect(&half_roller, &half_mask, &style_tmp, lv_obj_get_opa_scale(roller));\n    }\n}\n\n/**\n * Refresh the position of the roller. It uses the id stored in: ext->ddlist.selected_option_id\n * @param roller pointer to a roller object\n * @param anim_en LV_ANIM_ON: refresh with animation; LV_ANOM_OFF: without animation\n */\nstatic void refr_position(lv_obj_t * roller, lv_anim_enable_t anim_en)\n{\n#if LV_USE_ANIMATION == 0\n    anim_en = LV_ANIM_OFF;\n#endif\n\n    lv_obj_t * roller_scrl         = lv_page_get_scrl(roller);\n    lv_roller_ext_t * ext          = lv_obj_get_ext_attr(roller);\n    const lv_style_t * style_label = lv_obj_get_style(ext->ddlist.label);\n    const lv_font_t * font         = style_label->text.font;\n    lv_coord_t font_h              = lv_font_get_line_height(font);\n    lv_coord_t h                   = lv_obj_get_height(roller);\n    uint16_t anim_time             = lv_roller_get_anim_time(roller);\n\n    /* Normally the animtaion's `end_cb` sets correct position of the roller is infinite.\n     * But without animations do it manually*/\n    if(anim_en == LV_ANIM_OFF || anim_time == 0) {\n        inf_normalize(roller_scrl);\n    }\n\n    int32_t id = ext->ddlist.sel_opt_id;\n    lv_coord_t line_y1 =\n        id * (font_h + style_label->text.line_space) + ext->ddlist.label->coords.y1 - roller_scrl->coords.y1;\n    lv_coord_t new_y = -line_y1 + (h - font_h) / 2;\n\n    if(anim_en == LV_ANIM_OFF || anim_time == 0) {\n        lv_obj_set_y(roller_scrl, new_y);\n    } else {\n#if LV_USE_ANIMATION\n        lv_anim_t a;\n        a.var            = roller_scrl;\n        a.start          = lv_obj_get_y(roller_scrl);\n        a.end            = new_y;\n        a.exec_cb        = (lv_anim_exec_xcb_t)lv_obj_set_y;\n        a.path_cb        = lv_anim_path_linear;\n        a.ready_cb       = scroll_anim_ready_cb;\n        a.act_time       = 0;\n        a.time           = anim_time;\n        a.playback       = 0;\n        a.playback_pause = 0;\n        a.repeat         = 0;\n        a.repeat_pause   = 0;\n        lv_anim_create(&a);\n#endif\n    }\n}\n\n/**\n * Refresh the height of the roller and the scrolable\n * @param roller pointer to roller\n */\nstatic void refr_height(lv_obj_t * roller)\n{\n    lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);\n    lv_align_t obj_align  = LV_ALIGN_IN_LEFT_MID;\n    if(ext->ddlist.label) {\n        lv_label_align_t label_align = lv_label_get_align(ext->ddlist.label);\n        if(LV_LABEL_ALIGN_CENTER == label_align)\n            obj_align = LV_ALIGN_CENTER;\n        else if(LV_LABEL_ALIGN_RIGHT == label_align)\n            obj_align = LV_ALIGN_IN_RIGHT_MID;\n    }\n\n    lv_obj_set_height(lv_page_get_scrl(roller), lv_obj_get_height(ext->ddlist.label) + lv_obj_get_height(roller));\n    lv_obj_align(ext->ddlist.label, NULL, obj_align, 0, 0);\n#if LV_USE_ANIMATION\n    lv_anim_del(lv_page_get_scrl(roller), (lv_anim_exec_xcb_t)lv_obj_set_y);\n#endif\n    lv_ddlist_set_selected(roller, ext->ddlist.sel_opt_id);\n}\n\n/**\n * Set the middle page for the roller if inifinte is enabled\n * @param scrl pointer to the roller's scrollable (lv_obj_t *)\n */\nstatic void inf_normalize(void * scrl)\n{\n    lv_obj_t * roller_scrl = (lv_obj_t *)scrl;\n    lv_obj_t * roller      = lv_obj_get_parent(roller_scrl);\n    lv_roller_ext_t * ext  = lv_obj_get_ext_attr(roller);\n\n    if(ext->mode == LV_ROLLER_MODE_INIFINITE) {\n        uint16_t real_id_cnt = ext->ddlist.option_cnt / LV_ROLLER_INF_PAGES;\n\n        ext->ddlist.sel_opt_id = ext->ddlist.sel_opt_id % real_id_cnt;\n\n        ext->ddlist.sel_opt_id += (LV_ROLLER_INF_PAGES / 2) * real_id_cnt; /*Select the middle page*/\n\n        /*Move to the new id*/\n        const lv_style_t * style_label = lv_obj_get_style(ext->ddlist.label);\n        const lv_font_t * font         = style_label->text.font;\n        lv_coord_t font_h              = lv_font_get_line_height(font);\n        lv_coord_t h                   = lv_obj_get_height(roller);\n\n        lv_coord_t line_y1 = ext->ddlist.sel_opt_id * (font_h + style_label->text.line_space) +\n                             ext->ddlist.label->coords.y1 - roller_scrl->coords.y1;\n        lv_coord_t new_y = -line_y1 + (h - font_h) / 2;\n        lv_obj_set_y(roller_scrl, new_y);\n    }\n}\n\n#if LV_USE_ANIMATION\nstatic void scroll_anim_ready_cb(lv_anim_t * a)\n{\n    inf_normalize(a->var);\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_slider.c",
    "content": "\n/**\n * @file lv_slider.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_slider.h\"\n#if LV_USE_SLIDER != 0\n\n#include \"libs/lvgl/lv_core/lv_group.h\"\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#define LV_SLIDER_SIZE_MIN 4 /*hor. pad and ver. pad cannot make the bar or indicator smaller then this [px]*/\n#define LV_SLIDER_NOT_PRESSED INT16_MIN\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_design_cb_t ancestor_design_f;\nstatic lv_signal_cb_t ancestor_signal;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a slider objects\n * @param par pointer to an object, it will be the parent of the new slider\n * @param copy pointer to a slider object, if not NULL then the new object will be copied from it\n * @return pointer to the created slider\n */\nlv_obj_t * lv_slider_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"slider create started\");\n\n    /*Create the ancestor slider*/\n    lv_obj_t * new_slider = lv_bar_create(par, copy);\n    lv_mem_assert(new_slider);\n    if(new_slider == NULL) return NULL;\n\n    if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_cb(new_slider);\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_slider);\n\n    /*Allocate the slider type specific extended data*/\n    lv_slider_ext_t * ext = lv_obj_allocate_ext_attr(new_slider, sizeof(lv_slider_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    /*Initialize the allocated 'ext' */\n    ext->drag_value = LV_SLIDER_NOT_PRESSED;\n    ext->style_knob = &lv_style_pretty;\n    ext->knob_in    = 0;\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_cb(new_slider, lv_slider_signal);\n    lv_obj_set_design_cb(new_slider, lv_slider_design);\n\n    /*Init the new slider slider*/\n    if(copy == NULL) {\n        lv_obj_set_click(new_slider, true);\n        lv_obj_set_protect(new_slider, LV_PROTECT_PRESS_LOST);\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_slider_set_style(new_slider, LV_SLIDER_STYLE_BG, th->style.slider.bg);\n            lv_slider_set_style(new_slider, LV_SLIDER_STYLE_INDIC, th->style.slider.indic);\n            lv_slider_set_style(new_slider, LV_SLIDER_STYLE_KNOB, th->style.slider.knob);\n        } else {\n            lv_slider_set_style(new_slider, LV_SLIDER_STYLE_KNOB, ext->style_knob);\n        }\n    }\n    /*Copy an existing slider*/\n    else {\n        lv_slider_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->style_knob            = copy_ext->style_knob;\n        ext->knob_in               = copy_ext->knob_in;\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_slider);\n    }\n\n    LV_LOG_INFO(\"slider created\");\n\n    return new_slider;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the 'knob in' attribute of a slider\n * @param slider pointer to slider object\n * @param in true: the knob is drawn always in the slider;\n *           false: the knob can be out on the edges\n */\nvoid lv_slider_set_knob_in(lv_obj_t * slider, bool in)\n{\n    lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);\n    if(ext->knob_in == in) return;\n\n    ext->knob_in = in == false ? 0 : 1;\n    lv_obj_invalidate(slider);\n}\n\n/**\n * Set a style of a slider\n * @param slider pointer to a slider object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_slider_set_style(lv_obj_t * slider, lv_slider_style_t type, const lv_style_t * style)\n{\n    lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);\n\n    switch(type) {\n        case LV_SLIDER_STYLE_BG: lv_bar_set_style(slider, LV_BAR_STYLE_BG, style); break;\n        case LV_SLIDER_STYLE_INDIC: lv_bar_set_style(slider, LV_BAR_STYLE_INDIC, style); break;\n        case LV_SLIDER_STYLE_KNOB:\n            ext->style_knob = style;\n            lv_obj_refresh_ext_draw_pad(slider);\n            break;\n    }\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the value of a slider\n * @param slider pointer to a slider object\n * @return the value of the slider\n */\nint16_t lv_slider_get_value(const lv_obj_t * slider)\n{\n    lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);\n\n    if(ext->drag_value != LV_SLIDER_NOT_PRESSED)\n        return ext->drag_value;\n    else\n        return lv_bar_get_value(slider);\n}\n\n/**\n * Give the slider is being dragged or not\n * @param slider pointer to a slider object\n * @return true: drag in progress false: not dragged\n */\nbool lv_slider_is_dragged(const lv_obj_t * slider)\n{\n    lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);\n    return ext->drag_value == LV_SLIDER_NOT_PRESSED ? false : true;\n}\n\n/**\n * Get the 'knob in' attribute of a slider\n * @param slider pointer to slider object\n * @return true: the knob is drawn always in the slider;\n *         false: the knob can be out on the edges\n */\nbool lv_slider_get_knob_in(const lv_obj_t * slider)\n{\n    lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);\n    return ext->knob_in == 0 ? false : true;\n}\n\n/**\n * Get a style of a slider\n * @param slider pointer to a slider object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_slider_get_style(const lv_obj_t * slider, lv_slider_style_t type)\n{\n    const lv_style_t * style = NULL;\n    lv_slider_ext_t * ext    = lv_obj_get_ext_attr(slider);\n\n    switch(type) {\n        case LV_SLIDER_STYLE_BG: style = lv_bar_get_style(slider, LV_BAR_STYLE_BG); break;\n        case LV_SLIDER_STYLE_INDIC: style = lv_bar_get_style(slider, LV_BAR_STYLE_INDIC); break;\n        case LV_SLIDER_STYLE_KNOB: style = ext->style_knob; break;\n        default: style = NULL; break;\n    }\n\n    return style;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the sliders\n * @param slider pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    /*Return false if the object is not covers the mask_p area*/\n    if(mode == LV_DESIGN_COVER_CHK) {\n        return false;\n    }\n    /*Draw the object*/\n    else if(mode == LV_DESIGN_DRAW_MAIN) {\n        lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);\n\n        const lv_style_t * style_bg    = lv_slider_get_style(slider, LV_SLIDER_STYLE_BG);\n        const lv_style_t * style_knob  = lv_slider_get_style(slider, LV_SLIDER_STYLE_KNOB);\n        const lv_style_t * style_indic = lv_slider_get_style(slider, LV_SLIDER_STYLE_INDIC);\n\n        lv_opa_t opa_scale = lv_obj_get_opa_scale(slider);\n\n        lv_coord_t slider_w = lv_area_get_width(&slider->coords);\n        lv_coord_t slider_h = lv_area_get_height(&slider->coords);\n\n        /*Draw the bar*/\n        lv_area_t area_bg;\n        lv_area_copy(&area_bg, &slider->coords);\n\n        /*Be sure at least LV_SLIDER_SIZE_MIN  size will remain*/\n        lv_coord_t pad_top_bg    = style_bg->body.padding.top;\n        lv_coord_t pad_bottom_bg = style_bg->body.padding.bottom;\n        lv_coord_t pad_left_bg   = style_bg->body.padding.left;\n        lv_coord_t pad_right_bg  = style_bg->body.padding.right;\n        if(pad_top_bg + pad_bottom_bg + LV_SLIDER_SIZE_MIN > lv_area_get_height(&area_bg)) {\n            pad_top_bg    = (lv_area_get_height(&area_bg) - LV_SLIDER_SIZE_MIN) >> 1;\n            pad_bottom_bg = pad_top_bg;\n        }\n        if(pad_left_bg + pad_right_bg + LV_SLIDER_SIZE_MIN > lv_area_get_width(&area_bg)) {\n            pad_left_bg  = (lv_area_get_width(&area_bg) - LV_SLIDER_SIZE_MIN) >> 1;\n            pad_right_bg = (lv_area_get_width(&area_bg) - LV_SLIDER_SIZE_MIN) >> 1;\n        }\n\n        if(ext->knob_in) { /*Enable extra size if the knob is inside */\n            area_bg.x1 += pad_left_bg;\n            area_bg.x2 -= pad_right_bg;\n            area_bg.y1 += pad_top_bg;\n            area_bg.y2 -= pad_bottom_bg;\n        } else {                                                   /*Let space only in the perpendicular directions*/\n            area_bg.x1 += slider_w < slider_h ? pad_left_bg : 0;   /*Pad only for vertical slider*/\n            area_bg.x2 -= slider_w < slider_h ? pad_right_bg : 0;  /*Pad only for vertical slider*/\n            area_bg.y1 += slider_w > slider_h ? pad_top_bg : 0;    /*Pad only for horizontal slider*/\n            area_bg.y2 -= slider_w > slider_h ? pad_bottom_bg : 0; /*Pad only for horizontal slider*/\n        }\n\n#if LV_USE_GROUP == 0\n        lv_draw_rect(&area_bg, mask, style_bg, lv_obj_get_opa_scale(slider));\n#else\n        /* Draw the borders later if the slider is focused.\n         * At value = 100% the indicator can cover to whole background and the focused style won't\n         * be visible*/\n        if(lv_obj_is_focused(slider)) {\n            lv_style_t style_tmp;\n            lv_style_copy(&style_tmp, style_bg);\n            style_tmp.body.border.width = 0;\n            lv_draw_rect(&area_bg, mask, &style_tmp, opa_scale);\n        } else {\n            lv_draw_rect(&area_bg, mask, style_bg, opa_scale);\n        }\n#endif\n\n        /*Draw the indicator*/\n        lv_area_t area_indic;\n        lv_area_copy(&area_indic, &area_bg);\n\n        /*Be sure at least ver pad/hor pad width indicator will remain*/\n        lv_coord_t pad_top_indic    = style_indic->body.padding.top;\n        lv_coord_t pad_bottom_indic = style_indic->body.padding.bottom;\n        lv_coord_t pad_left_indic   = style_indic->body.padding.left;\n        lv_coord_t pad_right_indic  = style_indic->body.padding.right;\n        if(pad_top_indic + pad_bottom_indic + LV_SLIDER_SIZE_MIN > lv_area_get_height(&area_bg)) {\n            pad_top_indic    = (lv_area_get_height(&area_bg) - LV_SLIDER_SIZE_MIN) >> 1;\n            pad_bottom_indic = pad_top_indic;\n        }\n        if(pad_left_indic + pad_right_indic + LV_SLIDER_SIZE_MIN > lv_area_get_width(&area_bg)) {\n            pad_left_indic  = (lv_area_get_width(&area_bg) - LV_SLIDER_SIZE_MIN) >> 1;\n            pad_right_indic = pad_left_indic;\n        }\n\n        area_indic.x1 += pad_left_indic;\n        area_indic.x2 -= pad_right_indic;\n        area_indic.y1 += pad_top_indic;\n        area_indic.y2 -= pad_bottom_indic;\n\n        lv_coord_t cur_value = lv_slider_get_value(slider);\n        lv_coord_t min_value = lv_slider_get_min_value(slider);\n        lv_coord_t max_value = lv_slider_get_max_value(slider);\n\n        /*If dragged draw to the drag position*/\n        if(ext->drag_value != LV_SLIDER_NOT_PRESSED) cur_value = ext->drag_value;\n\n        if(slider_w >= slider_h) {\n            lv_coord_t indic_w = lv_area_get_width(&area_indic);\n#if LV_USE_ANIMATION\n            if(ext->bar.anim_state != LV_BAR_ANIM_STATE_INV) {\n                /*Calculate the coordinates of anim. start and end*/\n                lv_coord_t anim_start_x =\n                    (int32_t)((int32_t)indic_w * (ext->bar.anim_start - min_value)) / (max_value - min_value);\n                lv_coord_t anim_end_x =\n                    (int32_t)((int32_t)indic_w * (ext->bar.anim_end - min_value)) / (max_value - min_value);\n\n                /*Calculate the real position based on `anim_state` (between `anim_start` and\n                 * `anim_end`)*/\n                area_indic.x2 = anim_start_x + (((anim_end_x - anim_start_x) * ext->bar.anim_state) >> 8);\n            } else\n#endif\n            {\n                area_indic.x2 = (int32_t)((int32_t)indic_w * (cur_value - min_value)) / (max_value - min_value);\n            }\n            area_indic.x2 = area_indic.x1 + area_indic.x2 - 1;\n\n            /*Draw the indicator but don't draw an ugly 1px wide rectangle on the left on min.\n             * value*/\n            if(area_indic.x1 != area_indic.x2) lv_draw_rect(&area_indic, mask, style_indic, opa_scale);\n\n        } else {\n            lv_coord_t indic_h = lv_area_get_height(&area_indic);\n#if LV_USE_ANIMATION\n            if(ext->bar.anim_state != LV_BAR_ANIM_STATE_INV) {\n                /*Calculate the coordinates of anim. start and end*/\n                lv_coord_t anim_start_y =\n                    (int32_t)((int32_t)indic_h * (ext->bar.anim_start - min_value)) / (max_value - min_value);\n                lv_coord_t anim_end_y =\n                    (int32_t)((int32_t)indic_h * (ext->bar.anim_end - min_value)) / (max_value - min_value);\n\n                /*Calculate the real position based on `anim_state` (between `anim_start` and\n                 * `anim_end`)*/\n                area_indic.y1 = anim_start_y + (((anim_end_y - anim_start_y) * ext->bar.anim_state) >> 8);\n            } else\n#endif\n            {\n                area_indic.y1 = (int32_t)((int32_t)indic_h * (cur_value - min_value)) / (max_value - min_value);\n            }\n            area_indic.y1 = area_indic.y2 - area_indic.y1 + 1;\n\n            /*Draw the indicator but don't draw an ugly 1px height rectangle on the bottom on min.\n             * value*/\n            if(area_indic.x1 != area_indic.x2) lv_draw_rect(&area_indic, mask, style_indic, opa_scale);\n        }\n\n        /*Before the knob add the border if required*/\n#if LV_USE_GROUP\n        /* Draw the borders later if the bar is focused.\n         * At value = 100% the indicator can cover to whole background and the focused style won't\n         * be visible*/\n        if(lv_obj_is_focused(slider)) {\n            lv_style_t style_tmp;\n            lv_style_copy(&style_tmp, style_bg);\n            style_tmp.body.opa          = LV_OPA_TRANSP;\n            style_tmp.body.shadow.width = 0;\n            lv_draw_rect(&area_bg, mask, &style_tmp, opa_scale);\n        }\n#endif\n\n        /*Draw the knob*/\n        lv_area_t knob_area;\n        lv_area_copy(&knob_area, &slider->coords);\n\n        if(slider_w >= slider_h) {\n            if(ext->knob_in == 0) {\n                knob_area.x1 = area_indic.x2 - slider_h / 2;\n                knob_area.x2 = knob_area.x1 + slider_h - 1;\n            } else {\n#if LV_USE_ANIMATION\n                if(ext->bar.anim_state != LV_BAR_ANIM_STATE_INV) {\n                    lv_coord_t w = slider_w - slider_h - 1;\n                    lv_coord_t anim_start_x =\n                        (int32_t)((int32_t)w * (ext->bar.anim_start - min_value)) / (max_value - min_value);\n                    lv_coord_t anim_end_x =\n                        (int32_t)((int32_t)w * (ext->bar.anim_end - min_value)) / (max_value - min_value);\n\n                    /*Calculate the real position based on `anim_state` (between `anim_start` and\n                     * `anim_end`)*/\n                    knob_area.x1 = anim_start_x + (((anim_end_x - anim_start_x) * ext->bar.anim_state) >> 8);\n                } else\n#endif\n                {\n                    knob_area.x1 = (int32_t)((int32_t)(slider_w - slider_h - 1) * (cur_value - min_value)) /\n                                   (max_value - min_value);\n                }\n\n                knob_area.x1 += slider->coords.x1;\n                knob_area.x2 = knob_area.x1 + slider_h - 1;\n            }\n\n            knob_area.y1 = slider->coords.y1;\n            knob_area.y2 = slider->coords.y2;\n        } else {\n            if(ext->knob_in == 0) {\n                knob_area.y1 = area_indic.y1 - slider_w / 2;\n                knob_area.y2 = knob_area.y1 + slider_w - 1;\n            } else {\n#if LV_USE_ANIMATION\n                if(ext->bar.anim_state != LV_BAR_ANIM_STATE_INV) {\n                    lv_coord_t h = slider_h - slider_w - 1;\n                    lv_coord_t anim_start_x =\n                        (int32_t)((int32_t)h * (ext->bar.anim_start - min_value)) / (max_value - min_value);\n                    lv_coord_t anim_end_x =\n                        (int32_t)((int32_t)h * (ext->bar.anim_end - min_value)) / (max_value - min_value);\n\n                    /*Calculate the real position based on `anim_state` (between `anim_start` and\n                     * `anim_end`)*/\n                    knob_area.y2 = anim_start_x + (((anim_end_x - anim_start_x) * ext->bar.anim_state) >> 8);\n                } else\n#endif\n                {\n                    knob_area.y2 = (int32_t)((int32_t)(slider_h - slider_w - 1) * (cur_value - min_value)) /\n                                   (max_value - min_value);\n                }\n\n                knob_area.y2 = slider->coords.y2 - knob_area.y2;\n                knob_area.y1 = knob_area.y2 - slider_w - 1;\n            }\n            knob_area.x1 = slider->coords.x1;\n            knob_area.x2 = slider->coords.x2;\n        }\n        lv_draw_rect(&knob_area, mask, style_knob, opa_scale);\n    }\n    /*Post draw when the children are drawn*/\n    else if(mode == LV_DESIGN_DRAW_POST) {\n    }\n\n    return true;\n}\n\n/**\n * Signal function of the slider\n * @param slider pointer to a slider object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(slider, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);\n    lv_point_t p;\n    lv_coord_t w = lv_obj_get_width(slider);\n    lv_coord_t h = lv_obj_get_height(slider);\n\n    if(sign == LV_SIGNAL_PRESSED) {\n        ext->drag_value = lv_slider_get_value(slider);\n    } else if(sign == LV_SIGNAL_PRESSING) {\n        lv_indev_get_point(param, &p);\n        int16_t tmp = 0;\n        if(w > h) {\n            lv_coord_t knob_w = h;\n            p.x -=\n                slider->coords.x1 + h / 2; /*Modify the point to shift with half knob (important on the start and end)*/\n            tmp = (int32_t)((int32_t)p.x * (ext->bar.max_value - ext->bar.min_value + 1)) / (w - knob_w);\n            tmp += ext->bar.min_value;\n        } else {\n            lv_coord_t knob_h = w;\n            p.y -=\n                slider->coords.y1 + w / 2; /*Modify the point to shift with half knob (important on the start and end)*/\n            tmp = (int32_t)((int32_t)p.y * (ext->bar.max_value - ext->bar.min_value + 1)) / (h - knob_h);\n            tmp = ext->bar.max_value - tmp; /*Invert the value: smaller value means higher y*/\n        }\n\n        if(tmp < ext->bar.min_value)\n            tmp = ext->bar.min_value;\n        else if(tmp > ext->bar.max_value)\n            tmp = ext->bar.max_value;\n\n        if(tmp != ext->drag_value) {\n            ext->drag_value = tmp;\n            lv_obj_invalidate(slider);\n            res = lv_event_send(slider, LV_EVENT_VALUE_CHANGED, NULL);\n            if(res != LV_RES_OK) return res;\n        }\n    } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) {\n        if(ext->drag_value != LV_SLIDER_NOT_PRESSED) lv_slider_set_value(slider, ext->drag_value, false);\n        ext->drag_value = LV_SLIDER_NOT_PRESSED;\n\n#if LV_USE_GROUP\n        /*Leave edit mode if released. (No need to wait for LONG_PRESS) */\n        lv_group_t * g             = lv_obj_get_group(slider);\n        bool editing               = lv_group_get_editing(g);\n        lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());\n        if(indev_type == LV_INDEV_TYPE_ENCODER) {\n            if(editing) lv_group_set_editing(g, false);\n        }\n#endif\n\n    } else if(sign == LV_SIGNAL_CORD_CHG) {\n        /* The knob size depends on slider size.\n         * During the drawing method the ext. size is used by the knob so refresh the ext. size.*/\n        if(lv_obj_get_width(slider) != lv_area_get_width(param) ||\n           lv_obj_get_height(slider) != lv_area_get_height(param)) {\n            slider->signal_cb(slider, LV_SIGNAL_REFR_EXT_DRAW_PAD, NULL);\n        }\n    } else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {\n        const lv_style_t * style      = lv_slider_get_style(slider, LV_SLIDER_STYLE_BG);\n        const lv_style_t * knob_style = lv_slider_get_style(slider, LV_SLIDER_STYLE_KNOB);\n\n        lv_coord_t shadow_w = knob_style->body.shadow.width;\n        if(ext->knob_in == 0) {\n            /* The smaller size is the knob diameter*/\n            lv_coord_t x = LV_MATH_MIN(w / 2 + 1 + shadow_w, h / 2 + 1 + shadow_w);\n            if(slider->ext_draw_pad < x) slider->ext_draw_pad = x;\n        } else {\n            lv_coord_t pad = 0;\n            pad            = LV_MATH_MIN(pad, style->body.padding.top);\n            pad            = LV_MATH_MIN(pad, style->body.padding.bottom);\n            pad            = LV_MATH_MIN(pad, style->body.padding.left);\n            pad            = LV_MATH_MIN(pad, style->body.padding.right);\n            if(pad < 0) pad = -pad;\n            if(slider->ext_draw_pad < pad) slider->ext_draw_pad = pad;\n\n            if(slider->ext_draw_pad < shadow_w) slider->ext_draw_pad = shadow_w;\n        }\n    } else if(sign == LV_SIGNAL_CONTROL) {\n        char c = *((char *)param);\n\n        ext->drag_value = LV_SLIDER_NOT_PRESSED;\n\n        if(c == LV_KEY_RIGHT || c == LV_KEY_UP) {\n            lv_slider_set_value(slider, lv_slider_get_value(slider) + 1, true);\n            res = lv_event_send(slider, LV_EVENT_VALUE_CHANGED, NULL);\n            if(res != LV_RES_OK) return res;\n        } else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) {\n            lv_slider_set_value(slider, lv_slider_get_value(slider) - 1, true);\n            res = lv_event_send(slider, LV_EVENT_VALUE_CHANGED, NULL);\n            if(res != LV_RES_OK) return res;\n        }\n    } else if(sign == LV_SIGNAL_GET_EDITABLE) {\n        bool * editable = (bool *)param;\n        *editable       = true;\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_slider\";\n    }\n\n    return res;\n}\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_spinbox.c",
    "content": "/**\n * @file lv_spinbox.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_spinbox.h\"\n\n#if LV_USE_SPINBOX != 0\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n#include \"libs/lvgl/lv_misc/lv_utils.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic lv_res_t lv_spinbox_signal(lv_obj_t * spinbox, lv_signal_t sign, void * param);\nstatic void lv_spinbox_updatevalue(lv_obj_t * spinbox);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\nstatic lv_design_cb_t ancestor_design;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a spinbox object\n * @param par pointer to an object, it will be the parent of the new spinbox\n * @param copy pointer to a spinbox object, if not NULL then the new object will be copied from it\n * @return pointer to the created spinbox\n */\nlv_obj_t * lv_spinbox_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"spinbox create started\");\n\n    /*Create the ancestor of spinbox*/\n    lv_obj_t * new_spinbox = lv_ta_create(par, copy);\n    lv_mem_assert(new_spinbox);\n    if(new_spinbox == NULL) return NULL;\n\n    /*Allocate the spinbox type specific extended data*/\n    lv_spinbox_ext_t * ext = lv_obj_allocate_ext_attr(new_spinbox, sizeof(lv_spinbox_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_spinbox);\n    if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_spinbox);\n\n    /*Initialize the allocated 'ext'*/\n    ext->value              = 0;\n    ext->dec_point_pos      = 0;\n    ext->digit_count        = 5;\n    ext->digit_padding_left = 0;\n    ext->step               = 1;\n    ext->range_max          = 99999;\n    ext->range_min          = -99999;\n\n    lv_ta_set_cursor_type(new_spinbox, LV_CURSOR_BLOCK);\n    lv_ta_set_one_line(new_spinbox, true);\n    lv_ta_set_cursor_click_pos(new_spinbox, false);\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_cb(new_spinbox, lv_spinbox_signal);\n    lv_obj_set_design_cb(new_spinbox, ancestor_design); /*Leave the Text area's design function*/\n\n    /*Init the new spinbox spinbox*/\n    if(copy == NULL) {\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_spinbox_set_style(new_spinbox, LV_SPINBOX_STYLE_BG, th->style.spinbox.bg);\n            lv_spinbox_set_style(new_spinbox, LV_SPINBOX_STYLE_CURSOR, th->style.spinbox.cursor);\n            lv_spinbox_set_style(new_spinbox, LV_SPINBOX_STYLE_SB, th->style.spinbox.sb);\n        }\n    }\n    /*Copy an existing spinbox*/\n    else {\n        lv_spinbox_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n\n        lv_spinbox_set_value(new_spinbox, copy_ext->value);\n        lv_spinbox_set_digit_format(new_spinbox, copy_ext->digit_count, copy_ext->dec_point_pos);\n        lv_spinbox_set_range(new_spinbox, copy_ext->range_min, copy_ext->range_max);\n        lv_spinbox_set_step(new_spinbox, copy_ext->step);\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_spinbox);\n    }\n\n    lv_spinbox_updatevalue(new_spinbox);\n\n    LV_LOG_INFO(\"spinbox created\");\n\n    return new_spinbox;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set spinbox value\n * @param spinbox pointer to spinbox\n * @param i value to be set\n */\nvoid lv_spinbox_set_value(lv_obj_t * spinbox, int32_t i)\n{\n    lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);\n    if(ext == NULL) return;\n\n    if(i > ext->range_max) i = ext->range_max;\n    if(i < ext->range_min) i = ext->range_min;\n\n    ext->value = i;\n\n    lv_spinbox_updatevalue(spinbox);\n}\n\n/**\n * Set spinbox digit format (digit count and decimal format)\n * @param spinbox pointer to spinbox\n * @param digit_count number of digit excluding the decimal separator and the sign\n * @param separator_position number of digit before the decimal point. If 0, decimal point is not\n * shown\n */\nvoid lv_spinbox_set_digit_format(lv_obj_t * spinbox, uint8_t digit_count, uint8_t separator_position)\n{\n    lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);\n    if(ext == NULL) return;\n\n    if(digit_count > LV_SPINBOX_MAX_DIGIT_COUNT) digit_count = LV_SPINBOX_MAX_DIGIT_COUNT;\n\n    if(separator_position > LV_SPINBOX_MAX_DIGIT_COUNT) separator_position = LV_SPINBOX_MAX_DIGIT_COUNT;\n\n    ext->digit_count   = digit_count;\n    ext->dec_point_pos = separator_position;\n\n    lv_spinbox_updatevalue(spinbox);\n}\n\n/**\n * Set spinbox step\n * @param spinbox pointer to spinbox\n * @param step steps on increment/decrement\n */\nvoid lv_spinbox_set_step(lv_obj_t * spinbox, uint32_t step)\n{\n    lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);\n    if(ext == NULL) return;\n\n    ext->step = step;\n}\n\n/**\n * Set spinbox value range\n * @param spinbox pointer to spinbox\n * @param range_min maximum value, inclusive\n * @param range_max minimum value, inclusive\n */\nvoid lv_spinbox_set_range(lv_obj_t * spinbox, int32_t range_min, int32_t range_max)\n{\n    lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);\n    if(ext == NULL) return;\n\n    ext->range_max = range_max;\n    ext->range_min = range_min;\n\n    if(ext->value > ext->range_max) {\n        ext->value = ext->range_max;\n        lv_obj_invalidate(spinbox);\n    }\n    if(ext->value < ext->range_min) {\n        ext->value = ext->range_min;\n        lv_obj_invalidate(spinbox);\n    }\n}\n\n/**\n * Set spinbox left padding in digits count (added between sign and first digit)\n * @param spinbox pointer to spinbox\n * @param cb Callback function called on value change event\n */\nvoid lv_spinbox_set_padding_left(lv_obj_t * spinbox, uint8_t padding)\n{\n    lv_spinbox_ext_t * ext  = lv_obj_get_ext_attr(spinbox);\n    ext->digit_padding_left = padding;\n    lv_spinbox_updatevalue(spinbox);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the spinbox numeral value (user has to convert to float according to its digit format)\n * @param spinbox pointer to spinbox\n * @return value integer value of the spinbox\n */\nint32_t lv_spinbox_get_value(lv_obj_t * spinbox)\n{\n    lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);\n\n    return ext->value;\n}\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Select next lower digit for edition\n * @param spinbox pointer to spinbox\n */\nvoid lv_spinbox_step_next(lv_obj_t * spinbox)\n{\n    lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);\n\n    int32_t new_step = ext->step / 10;\n    if((new_step) > 0)\n        ext->step = new_step;\n    else\n        ext->step = 1;\n\n    lv_spinbox_updatevalue(spinbox);\n}\n\n/**\n * Select next higher digit for edition\n * @param spinbox pointer to spinbox\n */\nvoid lv_spinbox_step_prev(lv_obj_t * spinbox)\n{\n    lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);\n    int32_t step_limit;\n    step_limit       = LV_MATH_MAX(ext->range_max, (ext->range_min < 0 ? (-ext->range_min) : ext->range_min));\n    int32_t new_step = ext->step * 10;\n    if(new_step <= step_limit) ext->step = new_step;\n\n    lv_spinbox_updatevalue(spinbox);\n}\n\n/**\n * Increment spinbox value by one step\n * @param spinbox pointer to spinbox\n */\nvoid lv_spinbox_increment(lv_obj_t * spinbox)\n{\n    lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);\n\n    if(ext->value + ext->step <= ext->range_max) {\n        /*Special mode when zero crossing*/\n        if((ext->value + ext->step) > 0 && ext->value < 0) ext->value = -ext->value;\n        ext->value += ext->step;\n\n    } else {\n        ext->value = ext->range_max;\n    }\n\n    lv_spinbox_updatevalue(spinbox);\n}\n\n/**\n * Decrement spinbox value by one step\n * @param spinbox pointer to spinbox\n */\nvoid lv_spinbox_decrement(lv_obj_t * spinbox)\n{\n    lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);\n\n    if(ext->value - ext->step >= ext->range_min) {\n        /*Special mode when zero crossing*/\n        if((ext->value - ext->step) < 0 && ext->value > 0) ext->value = -ext->value;\n        ext->value -= ext->step;\n    } else {\n        ext->value = ext->range_min;\n    }\n\n    lv_spinbox_updatevalue(spinbox);\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Signal function of the spinbox\n * @param spinbox pointer to a spinbox object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_spinbox_signal(lv_obj_t * spinbox, lv_signal_t sign, void * param)\n{\n\n    lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);\n\n    lv_res_t res = LV_RES_OK;\n\n    /* Include the ancient signal function */\n    if(sign != LV_SIGNAL_CONTROL) {\n        res = ancestor_signal(spinbox, sign, param);\n        if(res != LV_RES_OK) return res;\n    }\n\n    if(sign == LV_SIGNAL_CLEANUP) {\n        /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_spinbox\";\n    } else if(sign == LV_SIGNAL_RELEASED) {\n        /*If released with an ENCODER then move to the next digit*/\n#if LV_USE_GROUP\n        lv_indev_t * indev = lv_indev_get_act();\n        if(lv_indev_get_type(indev) == LV_INDEV_TYPE_ENCODER) {\n            if(lv_group_get_editing(lv_obj_get_group(spinbox))) {\n                if(ext->step > 1) {\n                    lv_spinbox_step_next(spinbox);\n                } else {\n                    /*Restart from the MSB*/\n                    ext->step = 1;\n                    uint32_t i;\n                    for(i = 0; i < ext->digit_count; i++) {\n                        int32_t new_step = ext->step * 10;\n                        if(new_step >= ext->range_max) break;\n                        ext->step = new_step;\n                    }\n                    lv_spinbox_step_prev(spinbox);\n                }\n            }\n        }\n#endif\n    } else if(sign == LV_SIGNAL_CONTROL) {\n        lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());\n\n        uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/\n        if(c == LV_KEY_RIGHT) {\n            if(indev_type == LV_INDEV_TYPE_ENCODER)\n                lv_spinbox_increment(spinbox);\n            else\n                lv_spinbox_step_next(spinbox);\n        } else if(c == LV_KEY_LEFT) {\n            if(indev_type == LV_INDEV_TYPE_ENCODER)\n                lv_spinbox_decrement(spinbox);\n            else\n                lv_spinbox_step_prev(spinbox);\n        } else if(c == LV_KEY_UP) {\n            lv_spinbox_increment(spinbox);\n        } else if(c == LV_KEY_DOWN) {\n            lv_spinbox_decrement(spinbox);\n        } else {\n            lv_ta_add_char(spinbox, c);\n        }\n    }\n\n    return res;\n}\n\nstatic void lv_spinbox_updatevalue(lv_obj_t * spinbox)\n{\n    lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox);\n\n    char buf[LV_SPINBOX_MAX_DIGIT_COUNT + 8];\n    memset(buf, 0, sizeof(buf));\n    char * buf_p = buf;\n\n    /*Add the sign*/\n    (*buf_p) = ext->value >= 0 ? '+' : '-';\n    buf_p++;\n\n    int i;\n    /*padding left*/\n    for(i = 0; i < ext->digit_padding_left; i++) {\n        (*buf_p) = ' ';\n        buf_p++;\n    }\n\n    char digits[64];\n    /*Convert the numbers to string (the sign is already handled so always covert positive number)*/\n    lv_utils_num_to_str(ext->value < 0 ? -ext->value : ext->value, digits);\n\n    /*Add leading zeros*/\n    int lz_cnt = ext->digit_count - (int)strlen(digits);\n    if(lz_cnt > 0) {\n        for(i = strlen(digits); i >= 0; i--) {\n            digits[i + lz_cnt] = digits[i];\n        }\n        for(i = 0; i < lz_cnt; i++) {\n            digits[i] = '0';\n        }\n    }\n\n    int32_t intDigits;\n    intDigits = (ext->dec_point_pos == 0) ? ext->digit_count : ext->dec_point_pos;\n\n    /*Add the decimal part*/\n    for(i = 0; i < intDigits && digits[i] != '\\0'; i++) {\n        (*buf_p) = digits[i];\n        buf_p++;\n    }\n\n    if(ext->dec_point_pos != 0) {\n        /*Insert the decimal point*/\n        (*buf_p) = '.';\n        buf_p++;\n\n        for(/*Leave i*/; i < ext->digit_count && digits[i] != '\\0'; i++) {\n            (*buf_p) = digits[i];\n            buf_p++;\n        }\n    }\n\n    /*Refresh the text*/\n    lv_ta_set_text(spinbox, (char *)buf);\n\n    /*Set the cursor position*/\n    int32_t step    = ext->step;\n    uint8_t cur_pos = ext->digit_count;\n    while(step >= 10) {\n        step /= 10;\n        cur_pos--;\n    }\n\n    if(cur_pos > intDigits) cur_pos++; /*Skip teh decimal point*/\n\n    cur_pos += ext->digit_padding_left;\n\n    lv_ta_set_cursor_pos(spinbox, cur_pos);\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_sw.c",
    "content": "/**\n * @file lv_sw.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_sw.h\"\n\n#if LV_USE_SW != 0\n\n/*Testing of dependencies*/\n#if LV_USE_SLIDER == 0\n#error \"lv_sw: lv_slider is required. Enable it in lv_conf.h (LV_USE_SLIDER  1) \"\n#endif\n\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a switch objects\n * @param par pointer to an object, it will be the parent of the new switch\n * @param copy pointer to a switch object, if not NULL then the new object will be copied from it\n * @return pointer to the created switch\n */\nlv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"switch create started\");\n\n    /*Create the ancestor of switch*/\n    lv_obj_t * new_sw = lv_slider_create(par, copy);\n    lv_mem_assert(new_sw);\n    if(new_sw == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_sw);\n\n    /*Allocate the switch type specific extended data*/\n    lv_sw_ext_t * ext = lv_obj_allocate_ext_attr(new_sw, sizeof(lv_sw_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    /*Initialize the allocated 'ext' */\n    ext->changed = 0;\n#if LV_USE_ANIMATION\n    ext->anim_time = 0;\n#endif\n    ext->style_knob_off = ext->slider.style_knob;\n    ext->style_knob_on  = ext->slider.style_knob;\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_cb(new_sw, lv_sw_signal);\n\n    /*Init the new switch switch*/\n    if(copy == NULL) {\n        lv_obj_set_size(new_sw, 2 * LV_DPI / 3, LV_DPI / 3);\n        lv_slider_set_knob_in(new_sw, true);\n        lv_slider_set_range(new_sw, 0, LV_SW_MAX_VALUE);\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_sw_set_style(new_sw, LV_SW_STYLE_BG, th->style.sw.bg);\n            lv_sw_set_style(new_sw, LV_SW_STYLE_INDIC, th->style.sw.indic);\n            lv_sw_set_style(new_sw, LV_SW_STYLE_KNOB_OFF, th->style.sw.knob_off);\n            lv_sw_set_style(new_sw, LV_SW_STYLE_KNOB_ON, th->style.sw.knob_on);\n        } else {\n            /*Let the slider' style*/\n        }\n\n    }\n    /*Copy an existing switch*/\n    else {\n        lv_sw_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->style_knob_off    = copy_ext->style_knob_off;\n        ext->style_knob_on     = copy_ext->style_knob_on;\n#if LV_USE_ANIMATION\n        ext->anim_time = copy_ext->anim_time;\n#endif\n\n        if(lv_sw_get_state(new_sw))\n            lv_slider_set_style(new_sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on);\n        else\n            lv_slider_set_style(new_sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off);\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_sw);\n    }\n\n    LV_LOG_INFO(\"switch created\");\n\n    return new_sw;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Turn ON the switch\n * @param sw pointer to a switch objec\n * @param anim LV_ANOM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately\n */\nvoid lv_sw_on(lv_obj_t * sw, lv_anim_enable_t anim)\n{\n#if LV_USE_ANIMATION == 0\n    anim = LV_ANIM_OFF;\n#endif\n    lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);\n    lv_slider_set_value(sw, LV_SW_MAX_VALUE, anim);\n    lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on);\n}\n\n/**\n * Turn OFF the switch\n * @param sw pointer to a switch object\n * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately\n */\nvoid lv_sw_off(lv_obj_t * sw, lv_anim_enable_t anim)\n{\n#if LV_USE_ANIMATION == 0\n    anim = LV_ANIM_OFF;\n#endif\n    lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);\n    lv_slider_set_value(sw, 0, anim);\n    lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off);\n}\n\n/**\n * Toggle the position of the switch\n * @param sw pointer to a switch object\n * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately\n * @return resulting state of the switch.\n */\nbool lv_sw_toggle(lv_obj_t * sw, lv_anim_enable_t anim)\n{\n#if LV_USE_ANIMATION == 0\n    anim = LV_ANIM_OFF;\n#endif\n\n    bool state = lv_sw_get_state(sw);\n    if(state)\n        lv_sw_off(sw, anim);\n    else\n        lv_sw_on(sw, anim);\n\n    return !state;\n}\n\n/**\n * Set a style of a switch\n * @param sw pointer to a switch object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_sw_set_style(lv_obj_t * sw, lv_sw_style_t type, const lv_style_t * style)\n{\n    lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);\n\n    switch(type) {\n        case LV_SLIDER_STYLE_BG: lv_slider_set_style(sw, LV_SLIDER_STYLE_BG, style); break;\n        case LV_SLIDER_STYLE_INDIC: lv_bar_set_style(sw, LV_SLIDER_STYLE_INDIC, style); break;\n        case LV_SW_STYLE_KNOB_OFF:\n            ext->style_knob_off = style;\n            if(lv_sw_get_state(sw) == 0) lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, style);\n            break;\n        case LV_SW_STYLE_KNOB_ON:\n            ext->style_knob_on = style;\n            if(lv_sw_get_state(sw) != 0) lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, style);\n            break;\n    }\n}\n\nvoid lv_sw_set_anim_time(lv_obj_t * sw, uint16_t anim_time)\n{\n#if LV_USE_ANIMATION\n    lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);\n    ext->anim_time    = anim_time;\n#else\n    (void)sw;\n    (void)anim_time;\n#endif\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get a style of a switch\n * @param sw pointer to a  switch object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_sw_get_style(const lv_obj_t * sw, lv_sw_style_t type)\n{\n    const lv_style_t * style = NULL;\n    lv_sw_ext_t * ext        = lv_obj_get_ext_attr(sw);\n\n    switch(type) {\n        case LV_SW_STYLE_BG: style = lv_slider_get_style(sw, LV_SLIDER_STYLE_BG); break;\n        case LV_SW_STYLE_INDIC: style = lv_slider_get_style(sw, LV_SLIDER_STYLE_INDIC); break;\n        case LV_SW_STYLE_KNOB_OFF: style = ext->style_knob_off; break;\n        case LV_SW_STYLE_KNOB_ON: style = ext->style_knob_on; break;\n        default: style = NULL; break;\n    }\n\n    return style;\n}\n\nuint16_t lv_sw_get_anim_time(const lv_obj_t * sw)\n{\n\n#if LV_USE_ANIMATION\n    lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);\n    return ext->anim_time;\n#else\n    (void)sw; /*Unused*/\n    return 0;\n#endif\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Signal function of the switch\n * @param sw pointer to a switch object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param)\n{\n    lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);\n\n    /*Save the current (old) value before slider signal modifies it. It will be required in the\n     * later calculations*/\n    int16_t old_val;\n    if(sign == LV_SIGNAL_PRESSING)\n        old_val = ext->slider.drag_value;\n    else\n        old_val = lv_slider_get_value(sw);\n\n    /*Don't let the slider to call the action. Switch handles it differently*/\n    lv_event_cb_t event_cb = sw->event_cb;\n    sw->event_cb           = NULL;\n\n    lv_res_t res;\n    /* Include the ancient signal function */\n\n    res = ancestor_signal(sw, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    sw->event_cb = event_cb;\n\n    if(sign == LV_SIGNAL_CLEANUP) {\n        /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/\n    } else if(sign == LV_SIGNAL_PRESSED) {\n\n        /*Save the x coordinate of the pressed point to see if the switch was slid*/\n        lv_indev_t * indev = lv_indev_get_act();\n        if(indev) {\n            lv_point_t p;\n            lv_indev_get_point(indev, &p);\n            ext->start_x = p.x;\n        }\n        ext->slided  = 0;\n        ext->changed = 0;\n    } else if(sign == LV_SIGNAL_PRESSING) {\n        /*See if the switch was slid (moved at least a little)*/\n        lv_indev_t * indev = lv_indev_get_act();\n        if(indev) {\n            lv_point_t p = {0, 0};\n            lv_indev_get_point(indev, &p);\n            if(LV_MATH_ABS(p.x - ext->start_x) > LV_INDEV_DEF_DRAG_LIMIT) ext->slided = 1;\n        }\n\n        /*If didn't slide then revert the min/max value. So click without slide won't move the\n         * switch as a slider*/\n        if(ext->slided == 0) {\n            if(lv_sw_get_state(sw))\n                ext->slider.drag_value = LV_SW_MAX_VALUE;\n            else\n                ext->slider.drag_value = 0;\n        }\n\n        /*If explicitly changed (by slide) don't need to be toggled on release*/\n        int16_t threshold = LV_SW_MAX_VALUE / 2;\n        if((old_val < threshold && ext->slider.drag_value > threshold) ||\n           (old_val > threshold && ext->slider.drag_value < threshold)) {\n            ext->changed = 1;\n        }\n    } else if(sign == LV_SIGNAL_PRESS_LOST) {\n        if(lv_sw_get_state(sw)) {\n            lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on);\n            lv_slider_set_value(sw, LV_SW_MAX_VALUE, LV_ANIM_ON);\n            if(res != LV_RES_OK) return res;\n        } else {\n            lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off);\n            lv_slider_set_value(sw, 0, LV_ANIM_ON);\n            if(res != LV_RES_OK) return res;\n        }\n    } else if(sign == LV_SIGNAL_RELEASED) {\n        /*If not dragged then toggle the switch*/\n        if(ext->changed == 0) {\n            int32_t state;\n            if(lv_sw_get_state(sw)) {\n                lv_sw_off(sw, LV_ANIM_ON);\n                state = 0;\n            } else {\n                lv_sw_on(sw, LV_ANIM_ON);\n                state = 1;\n            }\n\n            res = lv_event_send(sw, LV_EVENT_VALUE_CHANGED, &state);\n            if(res != LV_RES_OK) return res;\n        }\n        /*If the switch was dragged then calculate the new state based on the current position*/\n        else {\n            int16_t v = lv_slider_get_value(sw);\n            int32_t state;\n            if(v > LV_SW_MAX_VALUE / 2) {\n                lv_sw_on(sw, LV_ANIM_ON);\n                state = 1;\n            } else {\n                lv_sw_off(sw, LV_ANIM_ON);\n                state = 0;\n            }\n            res = lv_event_send(sw, LV_EVENT_VALUE_CHANGED, &state);\n            if(res != LV_RES_OK) return res;\n        }\n    } else if(sign == LV_SIGNAL_CONTROL) {\n        char c = *((char *)param);\n        uint32_t state;\n        if(c == LV_KEY_RIGHT || c == LV_KEY_UP) {\n            lv_slider_set_value(sw, LV_SW_MAX_VALUE, true);\n            state = 1;\n            res   = lv_event_send(sw, LV_EVENT_VALUE_CHANGED, &state);\n            if(res != LV_RES_OK) return res;\n        } else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) {\n            lv_slider_set_value(sw, 0, true);\n            state = 0;\n            res   = lv_event_send(sw, LV_EVENT_VALUE_CHANGED, &state);\n            if(res != LV_RES_OK) return res;\n        }\n    } else if(sign == LV_SIGNAL_GET_EDITABLE) {\n        bool * editable = (bool *)param;\n        *editable       = false; /*The ancestor slider is editable the switch is not*/\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_sw\";\n    }\n\n    return res;\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_ta.c",
    "content": "/**\n * @file lv_ta.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_ta.h\"\n#if LV_USE_TA != 0\n#include <string.h>\n#include \"libs/lvgl/lv_core/lv_group.h\"\n#include \"libs/lvgl/lv_core/lv_refr.h\"\n#include \"libs/lvgl/lv_draw/lv_draw.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_misc/lv_anim.h\"\n#include \"libs/lvgl/lv_misc/lv_txt.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n\n/*********************\n *      DEFINES\n *********************/\n/*Test configuration*/\n\n#ifndef LV_TA_DEF_CURSOR_BLINK_TIME\n#define LV_TA_DEF_CURSOR_BLINK_TIME 400 /*ms*/\n#endif\n\n#ifndef LV_TA_DEF_PWD_SHOW_TIME\n#define LV_TA_DEF_PWD_SHOW_TIME 1500 /*ms*/\n#endif\n\n#define LV_TA_DEF_WIDTH (2 * LV_DPI)\n#define LV_TA_DEF_HEIGHT (1 * LV_DPI)\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_ta_design(lv_obj_t * ta, const lv_area_t * mask, lv_design_mode_t mode);\nstatic bool lv_ta_scrollable_design(lv_obj_t * scrl, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_ta_signal(lv_obj_t * ta, lv_signal_t sign, void * param);\nstatic lv_res_t lv_ta_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, void * param);\n#if LV_USE_ANIMATION\nstatic void cursor_blink_anim(lv_obj_t * ta, lv_anim_value_t show);\nstatic void pwd_char_hider_anim(lv_obj_t * ta, lv_anim_value_t x);\nstatic void pwd_char_hider_anim_ready(lv_anim_t * a);\n#endif\nstatic void pwd_char_hider(lv_obj_t * ta);\nstatic bool char_is_accepted(lv_obj_t * ta, uint32_t c);\nstatic void get_cursor_style(lv_obj_t * ta, lv_style_t * style_res);\nstatic void refr_cursor_area(lv_obj_t * ta);\nstatic void placeholder_update(lv_obj_t * ta);\nstatic void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign, lv_indev_t * click_source);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_design_cb_t ancestor_design;\nstatic lv_design_cb_t scrl_design;\nstatic lv_signal_cb_t ancestor_signal;\nstatic lv_signal_cb_t scrl_signal;\nstatic const char * ta_insert_replace;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a text area objects\n * @param par pointer to an object, it will be the parent of the new text area\n * @param copy pointer to a text area object, if not NULL then the new object will be copied from it\n * @return pointer to the created text area\n */\nlv_obj_t * lv_ta_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"text area create started\");\n\n    /*Create the ancestor object*/\n    lv_obj_t * new_ta = lv_page_create(par, copy);\n    lv_mem_assert(new_ta);\n    if(new_ta == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_ta);\n    if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_ta);\n    if(scrl_signal == NULL) scrl_signal = lv_obj_get_signal_cb(lv_page_get_scrl(new_ta));\n    if(scrl_design == NULL) scrl_design = lv_obj_get_design_cb(lv_page_get_scrl(new_ta));\n\n    /*Allocate the object type specific extended data*/\n    lv_ta_ext_t * ext = lv_obj_allocate_ext_attr(new_ta, sizeof(lv_ta_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    ext->cursor.state      = 1;\n    ext->pwd_mode          = 0;\n    ext->pwd_tmp           = NULL;\n    ext->pwd_show_time     = LV_TA_DEF_PWD_SHOW_TIME;\n    ext->accapted_chars    = NULL;\n    ext->max_length        = 0;\n    ext->cursor.style      = NULL;\n    ext->cursor.blink_time = LV_TA_DEF_CURSOR_BLINK_TIME;\n    ext->cursor.pos        = 0;\n    ext->cursor.click_pos  = 1;\n    ext->cursor.type       = LV_CURSOR_LINE;\n    ext->cursor.valid_x    = 0;\n    ext->one_line          = 0;\n#if LV_LABEL_TEXT_SEL\n    ext->text_sel_en = 0;\n#endif\n    ext->label       = NULL;\n    ext->placeholder = NULL;\n\n#if LV_USE_ANIMATION == 0\n    ext->pwd_show_time     = 0;\n    ext->cursor.blink_time = 0;\n#endif\n\n    lv_obj_set_signal_cb(new_ta, lv_ta_signal);\n    lv_obj_set_signal_cb(lv_page_get_scrl(new_ta), lv_ta_scrollable_signal);\n    lv_obj_set_design_cb(new_ta, lv_ta_design);\n\n    /*Init the new text area object*/\n    if(copy == NULL) {\n        lv_page_set_scrl_fit2(new_ta, LV_FIT_FLOOD, LV_FIT_TIGHT);\n\n        ext->label = lv_label_create(new_ta, NULL);\n\n        lv_obj_set_design_cb(ext->page.scrl, lv_ta_scrollable_design);\n\n        lv_label_set_long_mode(ext->label, LV_LABEL_LONG_BREAK);\n        lv_label_set_text(ext->label, \"Text area\");\n        lv_obj_set_click(ext->label, false);\n        lv_obj_set_size(new_ta, LV_TA_DEF_WIDTH, LV_TA_DEF_HEIGHT);\n        lv_ta_set_sb_mode(new_ta, LV_SB_MODE_DRAG);\n        lv_page_set_style(new_ta, LV_PAGE_STYLE_SCRL, &lv_style_transp_tight);\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_ta_set_style(new_ta, LV_TA_STYLE_BG, th->style.ta.area);\n            lv_ta_set_style(new_ta, LV_TA_STYLE_SB, th->style.ta.sb);\n        } else {\n            lv_ta_set_style(new_ta, LV_TA_STYLE_BG, &lv_style_pretty);\n        }\n    }\n    /*Copy an existing object*/\n    else {\n        lv_obj_set_design_cb(ext->page.scrl, lv_ta_scrollable_design);\n        lv_ta_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->label             = lv_label_create(new_ta, copy_ext->label);\n        ext->pwd_mode          = copy_ext->pwd_mode;\n        ext->accapted_chars    = copy_ext->accapted_chars;\n        ext->max_length        = copy_ext->max_length;\n        ext->cursor.style      = copy_ext->cursor.style;\n        ext->cursor.pos        = copy_ext->cursor.pos;\n        ext->cursor.valid_x    = copy_ext->cursor.valid_x;\n        ext->cursor.type       = copy_ext->cursor.type;\n        if(copy_ext->one_line) lv_ta_set_one_line(new_ta, true);\n\n        lv_ta_set_style(new_ta, LV_TA_STYLE_CURSOR, lv_ta_get_style(copy, LV_TA_STYLE_CURSOR));\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_ta);\n    }\n\n#if LV_USE_ANIMATION\n    if(ext->cursor.blink_time) {\n        /*Create a cursor blinker animation*/\n        lv_anim_t a;\n        a.var            = new_ta;\n        a.exec_cb        = (lv_anim_exec_xcb_t)cursor_blink_anim;\n        a.time           = ext->cursor.blink_time;\n        a.act_time       = 0;\n        a.ready_cb       = NULL;\n        a.start          = 1;\n        a.end            = 0;\n        a.repeat         = 1;\n        a.repeat_pause   = 0;\n        a.playback       = 1;\n        a.playback_pause = 0;\n        a.path_cb        = lv_anim_path_step;\n        lv_anim_create(&a);\n    }\n#endif\n\n    LV_LOG_INFO(\"text area created\");\n\n    return new_ta;\n}\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/**\n * Insert a character to the current cursor position.\n * To add a wide char, e.g. 'Á' use `lv_txt_encoded_conv_wc('Á')`\n * @param ta pointer to a text area object\n * @param c a character (e.g. 'a')\n */\nvoid lv_ta_add_char(lv_obj_t * ta, uint32_t c)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n    uint32_t letter_buf[2];\n    letter_buf[0] = c;\n    letter_buf[1] = '\\0';\n\n    ta_insert_replace = NULL;\n    lv_event_send(ta, LV_EVENT_INSERT, letter_buf);\n    if(ta_insert_replace) {\n        if(ta_insert_replace[0] == '\\0') return; /*Drop this text*/\n\n        /*Add the replaced text directly it's different from the original*/\n        if(strcmp(ta_insert_replace, (char *)letter_buf)) {\n            lv_ta_add_text(ta, ta_insert_replace);\n            return;\n        }\n    }\n\n    if(ext->one_line && (c == '\\n' || c == '\\r')) {\n        LV_LOG_INFO(\"Text area: line break ignored in one-line mode\");\n        return;\n    }\n\n    uint32_t c_uni = lv_txt_encoded_next((const char *)&c, NULL);\n\n    if(char_is_accepted(ta, c_uni) == false) {\n        LV_LOG_INFO(\"Character is no accepted by the text area (too long text or not in the \"\n                    \"accepted list)\");\n        return;\n    }\n\n    /*If a new line was added it shouldn't show edge flash effect*/\n    bool edge_flash_en = lv_ta_get_edge_flash(ta);\n    lv_ta_set_edge_flash(ta, false);\n\n    if(ext->pwd_mode != 0) pwd_char_hider(ta); /*Make sure all the current text contains only '*'*/\n\n    lv_label_ins_text(ext->label, ext->cursor.pos, (const char *)letter_buf); /*Insert the character*/\n    lv_ta_clear_selection(ta);                                                /*Clear selection*/\n\n    if(ext->pwd_mode != 0) {\n\n        ext->pwd_tmp = lv_mem_realloc(ext->pwd_tmp, strlen(ext->pwd_tmp) + 2); /*+2: the new char + \\0 */\n        lv_mem_assert(ext->pwd_tmp);\n        if(ext->pwd_tmp == NULL) return;\n\n        lv_txt_ins(ext->pwd_tmp, ext->cursor.pos, (const char *)letter_buf);\n\n#if LV_USE_ANIMATION\n        /*Auto hide characters*/\n        lv_anim_t a;\n        a.var            = ta;\n        a.exec_cb        = (lv_anim_exec_xcb_t)pwd_char_hider_anim;\n        a.time           = ext->pwd_show_time;\n        a.act_time       = 0;\n        a.ready_cb       = pwd_char_hider_anim_ready;\n        a.start          = 0;\n        a.end            = 1;\n        a.repeat         = 0;\n        a.repeat_pause   = 0;\n        a.playback       = 0;\n        a.playback_pause = 0;\n        a.path_cb        = lv_anim_path_step;\n        lv_anim_create(&a);\n\n#else\n        pwd_char_hider(ta);\n#endif\n    }\n\n    /*Move the cursor after the new character*/\n    lv_ta_set_cursor_pos(ta, lv_ta_get_cursor_pos(ta) + 1);\n\n    /*Revert the original edge flash state*/\n    lv_ta_set_edge_flash(ta, edge_flash_en);\n\n    placeholder_update(ta);\n\n    lv_event_send(ta, LV_EVENT_VALUE_CHANGED, NULL);\n}\n\n/**\n * Insert a text to the current cursor position\n * @param ta pointer to a text area object\n * @param txt a '\\0' terminated string to insert\n */\nvoid lv_ta_add_text(lv_obj_t * ta, const char * txt)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n    ta_insert_replace = NULL;\n    lv_event_send(ta, LV_EVENT_INSERT, txt);\n    if(ta_insert_replace) {\n        if(ta_insert_replace[0] == '\\0') return; /*Drop this text*/\n\n        /*Add the replaced text directly it's different from the original*/\n        if(strcmp(ta_insert_replace, txt)) {\n            lv_ta_add_text(ta, ta_insert_replace);\n            return;\n        }\n    }\n\n    if(ext->pwd_mode != 0) pwd_char_hider(ta); /*Make sure all the current text contains only '*'*/\n\n    /*Add the character one-by-one if not all characters are accepted or there is character limit.*/\n    if(lv_ta_get_accepted_chars(ta) || lv_ta_get_max_length(ta)) {\n        uint32_t i = 0;\n        while(txt[i] != '\\0') {\n            uint32_t c = lv_txt_encoded_next(txt, &i);\n            lv_ta_add_char(ta, lv_txt_unicode_to_encoded(c));\n        }\n        return;\n    }\n\n    /*If a new line was added it shouldn't show edge flash effect*/\n    bool edge_flash_en = lv_ta_get_edge_flash(ta);\n    lv_ta_set_edge_flash(ta, false);\n\n    /*Insert the text*/\n    lv_label_ins_text(ext->label, ext->cursor.pos, txt);\n    lv_ta_clear_selection(ta);\n\n    if(ext->pwd_mode != 0) {\n        ext->pwd_tmp = lv_mem_realloc(ext->pwd_tmp, strlen(ext->pwd_tmp) + strlen(txt) + 1);\n        lv_mem_assert(ext->pwd_tmp);\n        if(ext->pwd_tmp == NULL) return;\n\n        lv_txt_ins(ext->pwd_tmp, ext->cursor.pos, txt);\n\n#if LV_USE_ANIMATION\n        /*Auto hide characters*/\n        lv_anim_t a;\n        a.var            = ta;\n        a.exec_cb        = (lv_anim_exec_xcb_t)pwd_char_hider_anim;\n        a.time           = ext->pwd_show_time;\n        a.act_time       = 0;\n        a.ready_cb       = pwd_char_hider_anim_ready;\n        a.start          = 0;\n        a.end            = 1;\n        a.repeat         = 0;\n        a.repeat_pause   = 0;\n        a.playback       = 0;\n        a.playback_pause = 0;\n        a.path_cb        = lv_anim_path_step;\n        lv_anim_create(&a);\n#else\n        pwd_char_hider(ta);\n#endif\n    }\n\n    /*Move the cursor after the new text*/\n    lv_ta_set_cursor_pos(ta, lv_ta_get_cursor_pos(ta) + lv_txt_get_encoded_length(txt));\n\n    /*Revert the original edge flash state*/\n    lv_ta_set_edge_flash(ta, edge_flash_en);\n\n    placeholder_update(ta);\n\n    lv_event_send(ta, LV_EVENT_VALUE_CHANGED, NULL);\n}\n\n/**\n * Delete a the left character from the current cursor position\n * @param ta pointer to a text area object\n */\nvoid lv_ta_del_char(lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    uint16_t cur_pos  = ext->cursor.pos;\n\n    if(cur_pos == 0) return;\n\n    ta_insert_replace = NULL;\n    char del_buf[2]   = {LV_KEY_DEL, '\\0'};\n    lv_event_send(ta, LV_EVENT_INSERT, del_buf);\n    if(ta_insert_replace) {\n        if(ta_insert_replace[0] == '\\0') return; /*Drop this text*/\n\n        /*Add the replaced text directly it's different from the original*/\n        if(strcmp(ta_insert_replace, del_buf)) {\n            lv_ta_add_text(ta, ta_insert_replace);\n            return;\n        }\n    }\n\n    char * label_txt = lv_label_get_text(ext->label);\n    /*Delete a character*/\n    lv_txt_cut(label_txt, ext->cursor.pos - 1, 1);\n    /*Refresh the label*/\n    lv_label_set_text(ext->label, label_txt);\n    lv_ta_clear_selection(ta);\n\n    /*Don't let 'width == 0' because cursor will not be visible*/\n    if(lv_obj_get_width(ext->label) == 0) {\n        const lv_style_t * style = lv_obj_get_style(ext->label);\n        lv_obj_set_width(ext->label, style->line.width);\n    }\n\n    if(ext->pwd_mode != 0) {\n        uint32_t byte_pos = lv_txt_encoded_get_byte_id(ext->pwd_tmp, ext->cursor.pos - 1);\n        lv_txt_cut(ext->pwd_tmp, ext->cursor.pos - 1, lv_txt_encoded_size(&label_txt[byte_pos]));\n\n        ext->pwd_tmp = lv_mem_realloc(ext->pwd_tmp, strlen(ext->pwd_tmp) + 1);\n        lv_mem_assert(ext->pwd_tmp);\n        if(ext->pwd_tmp == NULL) return;\n    }\n\n    /*Move the cursor to the place of the deleted character*/\n    lv_ta_set_cursor_pos(ta, ext->cursor.pos - 1);\n\n    placeholder_update(ta);\n\n    lv_event_send(ta, LV_EVENT_VALUE_CHANGED, NULL);\n}\n\n/**\n * Delete the right character from the current cursor position\n * @param ta pointer to a text area object\n */\nvoid lv_ta_del_char_forward(lv_obj_t * ta)\n{\n    uint16_t cp = lv_ta_get_cursor_pos(ta);\n    lv_ta_set_cursor_pos(ta, cp + 1);\n    if(cp != lv_ta_get_cursor_pos(ta)) lv_ta_del_char(ta);\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the text of a text area\n * @param ta pointer to a text area\n * @param txt pointer to the text\n */\nvoid lv_ta_set_text(lv_obj_t * ta, const char * txt)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n    /*Clear the existing selection*/\n    lv_ta_clear_selection(ta);\n\n    /*Add the character one-by-one if not all characters are accepted or there is character limit.*/\n    if(lv_ta_get_accepted_chars(ta) || lv_ta_get_max_length(ta)) {\n        lv_label_set_text(ext->label, \"\");\n        lv_ta_set_cursor_pos(ta, LV_TA_CURSOR_LAST);\n\n        uint32_t i = 0;\n        while(txt[i] != '\\0') {\n            uint32_t c = lv_txt_encoded_next(txt, &i);\n            lv_ta_add_char(ta, lv_txt_unicode_to_encoded(c));\n        }\n    } else {\n        lv_label_set_text(ext->label, txt);\n        lv_ta_set_cursor_pos(ta, LV_TA_CURSOR_LAST);\n    }\n\n    /*Don't let 'width == 0' because the cursor will not be visible*/\n    if(lv_obj_get_width(ext->label) == 0) {\n        const lv_style_t * style = lv_obj_get_style(ext->label);\n        lv_obj_set_width(ext->label, lv_font_get_glyph_width(style->text.font, ' ', '\\0'));\n    }\n\n    if(ext->pwd_mode != 0) {\n        ext->pwd_tmp = lv_mem_realloc(ext->pwd_tmp, strlen(txt) + 1);\n        lv_mem_assert(ext->pwd_tmp);\n        if(ext->pwd_tmp == NULL) return;\n        strcpy(ext->pwd_tmp, txt);\n\n#if LV_USE_ANIMATION\n        /*Auto hide characters*/\n        lv_anim_t a;\n        a.var            = ta;\n        a.exec_cb        = (lv_anim_exec_xcb_t)pwd_char_hider_anim;\n        a.time           = ext->pwd_show_time;\n        a.act_time       = 0;\n        a.ready_cb       = pwd_char_hider_anim_ready;\n        a.start          = 0;\n        a.end            = 1;\n        a.repeat         = 0;\n        a.repeat_pause   = 0;\n        a.playback       = 0;\n        a.playback_pause = 0;\n        a.path_cb        = lv_anim_path_step;\n        lv_anim_create(&a);\n#else\n        pwd_char_hider(ta);\n#endif\n    }\n\n    placeholder_update(ta);\n\n    lv_event_send(ta, LV_EVENT_VALUE_CHANGED, NULL);\n}\n\n/**\n * Set the placeholder text of a text area\n * @param ta pointer to a text area\n * @param txt pointer to the text\n */\nvoid lv_ta_set_placeholder_text(lv_obj_t * ta, const char * txt)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n    /*Create the placeholder label only when it is needed*/\n    if(ext->placeholder == NULL) {\n        ext->placeholder = lv_label_create(ta, NULL);\n\n        if(ext->one_line) {\n            lv_label_set_long_mode(ext->placeholder, LV_LABEL_LONG_EXPAND);\n        } else {\n            lv_label_set_long_mode(ext->placeholder, LV_LABEL_LONG_BREAK);\n        }\n    }\n\n    lv_label_set_text(ext->placeholder, txt);\n\n    placeholder_update(ta);\n}\n\n/**\n * Set the cursor position\n * @param obj pointer to a text area object\n * @param pos the new cursor position in character index\n *             < 0 : index from the end of the text\n *             LV_TA_CURSOR_LAST: go after the last character\n */\nvoid lv_ta_set_cursor_pos(lv_obj_t * ta, int16_t pos)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    if(ext->cursor.pos == pos) return;\n\n    uint16_t len = lv_txt_get_encoded_length(lv_label_get_text(ext->label));\n\n    if(pos < 0) pos = len + pos;\n\n    if(pos > len || pos == LV_TA_CURSOR_LAST) pos = len;\n\n    ext->cursor.pos = pos;\n\n    /*Position the label to make the cursor visible*/\n    lv_obj_t * label_par = lv_obj_get_parent(ext->label);\n    lv_point_t cur_pos;\n    const lv_style_t * style = lv_obj_get_style(ta);\n    const lv_font_t * font_p = style->text.font;\n    lv_area_t label_cords;\n    lv_area_t ta_cords;\n    lv_label_get_letter_pos(ext->label, pos, &cur_pos);\n    lv_obj_get_coords(ta, &ta_cords);\n    lv_obj_get_coords(ext->label, &label_cords);\n\n    /*Check the top*/\n    lv_coord_t font_h = lv_font_get_line_height(font_p);\n    if(lv_obj_get_y(label_par) + cur_pos.y < 0) {\n        lv_obj_set_y(label_par, -cur_pos.y + style->body.padding.top);\n    }\n\n    /*Check the bottom*/\n    if(label_cords.y1 + cur_pos.y + font_h + style->body.padding.bottom > ta_cords.y2) {\n        lv_obj_set_y(label_par, -(cur_pos.y - lv_obj_get_height(ta) + font_h + style->body.padding.top +\n                                  style->body.padding.bottom));\n    }\n    /*Check the left (use the font_h as general unit)*/\n    if(lv_obj_get_x(label_par) + cur_pos.x < font_h) {\n        lv_obj_set_x(label_par, -cur_pos.x + font_h);\n    }\n\n    /*Check the right (use the font_h as general unit)*/\n    if(label_cords.x1 + cur_pos.x + font_h + style->body.padding.right > ta_cords.x2) {\n        lv_obj_set_x(label_par, -(cur_pos.x - lv_obj_get_width(ta) + font_h + style->body.padding.left +\n                                  style->body.padding.right));\n    }\n\n    ext->cursor.valid_x = cur_pos.x;\n\n#if LV_USE_ANIMATION\n    if(ext->cursor.blink_time) {\n        /*Reset cursor blink animation*/\n        lv_anim_t a;\n        a.var            = ta;\n        a.exec_cb        = (lv_anim_exec_xcb_t)cursor_blink_anim;\n        a.time           = ext->cursor.blink_time;\n        a.act_time       = 0;\n        a.ready_cb       = NULL;\n        a.start          = 1;\n        a.end            = 0;\n        a.repeat         = 1;\n        a.repeat_pause   = 0;\n        a.playback       = 1;\n        a.playback_pause = 0;\n        a.path_cb        = lv_anim_path_step;\n        lv_anim_create(&a);\n    }\n#endif\n\n    refr_cursor_area(ta);\n}\n\n/**\n * Set the cursor type.\n * @param ta pointer to a text area object\n * @param cur_type: element of 'lv_ta_cursor_type_t'\n */\nvoid lv_ta_set_cursor_type(lv_obj_t * ta, lv_cursor_type_t cur_type)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    if(ext->cursor.type == cur_type) return;\n\n    ext->cursor.type = cur_type;\n\n    refr_cursor_area(ta);\n}\n\n/**\n * Enable/Disable the positioning of the the cursor by clicking the text on the text area.\n * @param ta pointer to a text area object\n * @param en true: enable click positions; false: disable\n */\nvoid lv_ta_set_cursor_click_pos(lv_obj_t * ta, bool en)\n{\n    lv_ta_ext_t * ext     = lv_obj_get_ext_attr(ta);\n    ext->cursor.click_pos = en ? 1 : 0;\n}\n\n/**\n * Enable/Disable password mode\n * @param ta pointer to a text area object\n * @param en true: enable, false: disable\n */\nvoid lv_ta_set_pwd_mode(lv_obj_t * ta, bool en)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    if(ext->pwd_mode == en) return;\n\n    /*Pwd mode is now enabled*/\n    if(ext->pwd_mode == 0 && en != false) {\n        char * txt   = lv_label_get_text(ext->label);\n        uint16_t len = strlen(txt);\n        ext->pwd_tmp = lv_mem_alloc(len + 1);\n        lv_mem_assert(ext->pwd_tmp);\n        if(ext->pwd_tmp == NULL) return;\n\n        strcpy(ext->pwd_tmp, txt);\n\n        uint16_t i;\n        for(i = 0; i < len; i++) {\n            txt[i] = '*'; /*All char to '*'*/\n        }\n        txt[i] = '\\0';\n\n        lv_ta_clear_selection(ta);\n\n        lv_label_set_text(ext->label, NULL);\n    }\n    /*Pwd mode is now disabled*/\n    else if(ext->pwd_mode == 1 && en == false) {\n        lv_ta_clear_selection(ta);\n        lv_label_set_text(ext->label, ext->pwd_tmp);\n        lv_mem_free(ext->pwd_tmp);\n        ext->pwd_tmp = NULL;\n    }\n\n    ext->pwd_mode = en == false ? 0 : 1;\n\n    refr_cursor_area(ta);\n}\n\n/**\n * Configure the text area to one line or back to normal\n * @param ta pointer to a Text area object\n * @param en true: one line, false: normal\n */\nvoid lv_ta_set_one_line(lv_obj_t * ta, bool en)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    if(ext->one_line == en) return;\n\n    if(en) {\n        const lv_style_t * style_ta    = lv_obj_get_style(ta);\n        const lv_style_t * style_scrl  = lv_obj_get_style(lv_page_get_scrl(ta));\n        const lv_style_t * style_label = lv_obj_get_style(ext->label);\n        lv_coord_t font_h              = lv_font_get_line_height(style_label->text.font);\n\n        ext->one_line = 1;\n        lv_page_set_scrl_fit2(ta, LV_FIT_TIGHT, LV_FIT_FLOOD);\n        lv_obj_set_height(ta, font_h + style_ta->body.padding.top + style_ta->body.padding.bottom +\n                                  style_scrl->body.padding.top + style_scrl->body.padding.bottom);\n        lv_label_set_long_mode(ext->label, LV_LABEL_LONG_EXPAND);\n        if(ext->placeholder) lv_label_set_long_mode(ext->placeholder, LV_LABEL_LONG_EXPAND);\n        lv_obj_set_pos(lv_page_get_scrl(ta), style_ta->body.padding.left, style_ta->body.padding.top);\n    } else {\n        const lv_style_t * style_ta = lv_obj_get_style(ta);\n\n        ext->one_line = 0;\n        lv_page_set_scrl_fit2(ta, LV_FIT_FLOOD, LV_FIT_TIGHT);\n        lv_label_set_long_mode(ext->label, LV_LABEL_LONG_BREAK);\n        if(ext->placeholder) lv_label_set_long_mode(ext->placeholder, LV_LABEL_LONG_BREAK);\n\n        lv_obj_set_height(ta, LV_TA_DEF_HEIGHT);\n        lv_obj_set_pos(lv_page_get_scrl(ta), style_ta->body.padding.left, style_ta->body.padding.top);\n    }\n\n    placeholder_update(ta);\n    refr_cursor_area(ta);\n}\n\n/**\n * Set the alignment of the text area.\n * In one line mode the text can be scrolled only with `LV_LABEL_ALIGN_LEFT`.\n * This function should be called if the size of text area changes.\n * @param ta pointer to a text are object\n * @param align the desired alignment from `lv_label_align_t`. (LV_LABEL_ALIGN_LEFT/CENTER/RIGHT)\n */\nvoid lv_ta_set_text_align(lv_obj_t * ta, lv_label_align_t align)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    lv_obj_t * label  = lv_ta_get_label(ta);\n    if(!ext->one_line) {\n        lv_label_set_align(label, align);\n    } else {\n        /*Normal left align. Just let the text expand*/\n        if(align == LV_LABEL_ALIGN_LEFT) {\n            lv_label_set_long_mode(label, LV_LABEL_LONG_EXPAND);\n            lv_page_set_scrl_fit2(ta, LV_FIT_TIGHT, LV_FIT_FLOOD);\n            lv_label_set_align(label, align);\n\n        }\n        /*Else use fix label width equal to the Text area width*/\n        else {\n            lv_label_set_long_mode(label, LV_LABEL_LONG_CROP);\n            lv_page_set_scrl_fit2(ta, LV_FIT_FLOOD, LV_FIT_FLOOD);\n            lv_label_set_align(label, align);\n\n            lv_obj_set_width(label, lv_page_get_fit_width(ta));\n        }\n    }\n\n    refr_cursor_area(ta);\n}\n\n/**\n * Set a list of characters. Only these characters will be accepted by the text area\n * @param ta pointer to  Text Area\n * @param list list of characters. Only the pointer is saved. E.g. \"+-.,0123456789\"\n */\nvoid lv_ta_set_accepted_chars(lv_obj_t * ta, const char * list)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n    ext->accapted_chars = list;\n}\n\n/**\n * Set max length of a Text Area.\n * @param ta pointer to  Text Area\n * @param num the maximal number of characters can be added (`lv_ta_set_text` ignores it)\n */\nvoid lv_ta_set_max_length(lv_obj_t * ta, uint16_t num)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n    ext->max_length = num;\n}\n\n/**\n * In `LV_EVENT_INSERT` the text which planned to be inserted can be replaced by an other text.\n * It can be used to add automatic formatting to the text area.\n * @param ta pointer to a text area.\n * @param txt pointer to a new string to insert. If `\"\"` no text will be added.\n *            The variable must be live after the `event_cb` exists. (Should be `global` or\n * `static`)\n */\nvoid lv_ta_set_insert_replace(lv_obj_t * ta, const char * txt)\n{\n    (void)ta; /*Unused*/\n    ta_insert_replace = txt;\n}\n\n/**\n * Set a style of a text area\n * @param ta pointer to a text area object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_ta_set_style(lv_obj_t * ta, lv_ta_style_t type, const lv_style_t * style)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n    switch(type) {\n        case LV_TA_STYLE_BG: lv_page_set_style(ta, LV_PAGE_STYLE_BG, style); break;\n        case LV_TA_STYLE_SB: lv_page_set_style(ta, LV_PAGE_STYLE_SB, style); break;\n        case LV_TA_STYLE_EDGE_FLASH: lv_page_set_style(ta, LV_PAGE_STYLE_EDGE_FLASH, style); break;\n        case LV_TA_STYLE_CURSOR:\n            ext->cursor.style = style;\n            lv_obj_refresh_ext_draw_pad(lv_page_get_scrl(ta)); /*Refresh ext. size because of cursor drawing*/\n            refr_cursor_area(ta);\n            break;\n        case LV_TA_STYLE_PLACEHOLDER:\n            if(ext->placeholder) lv_label_set_style(ext->placeholder, LV_LABEL_STYLE_MAIN, style);\n            break;\n    }\n}\n\n/**\n * Enable/disable selection mode.\n * @param ta pointer to a text area object\n * @param en true or false to enable/disable selection mode\n */\nvoid lv_ta_set_text_sel(lv_obj_t * ta, bool en)\n{\n#if LV_LABEL_TEXT_SEL\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n    ext->text_sel_en = en;\n\n    if(!en) lv_ta_clear_selection(ta);\n#else\n    (void)ta; /*Unused*/\n    (void)en; /*Unused*/\n#endif\n}\n\n/**\n * Set how long show the password before changing it to '*'\n * @param ta pointer to Text area\n * @param time show time in milliseconds. 0: hide immediately.\n */\nvoid lv_ta_set_pwd_show_time(lv_obj_t * ta, uint16_t time)\n{\n#if LV_USE_ANIMATION == 0\n    time = 0;\n#endif\n\n    lv_ta_ext_t * ext  = lv_obj_get_ext_attr(ta);\n    ext->pwd_show_time = time;\n}\n\n/**\n * Set cursor blink animation time\n * @param ta pointer to Text area\n * @param time blink period. 0: disable blinking\n */\nvoid lv_ta_set_cursor_blink_time(lv_obj_t * ta, uint16_t time)\n{\n#if LV_USE_ANIMATION == 0\n    time = 0;\n#endif\n\n    lv_ta_ext_t * ext      = lv_obj_get_ext_attr(ta);\n    ext->cursor.blink_time = time;\n\n#if LV_USE_ANIMATION\n    if(ext->cursor.blink_time) {\n        /*Reset cursor blink animation*/\n        lv_anim_t a;\n        a.var            = ta;\n        a.exec_cb        = (lv_anim_exec_xcb_t)cursor_blink_anim;\n        a.time           = ext->cursor.blink_time;\n        a.act_time       = 0;\n        a.ready_cb       = NULL;\n        a.start          = 1;\n        a.end            = 0;\n        a.repeat         = 1;\n        a.repeat_pause   = 0;\n        a.playback       = 1;\n        a.playback_pause = 0;\n        a.path_cb        = lv_anim_path_step;\n        lv_anim_create(&a);\n    } else {\n        ext->cursor.state = 1;\n    }\n#else\n    ext->cursor.state = 1;\n#endif\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the text of a text area. In password mode it gives the real text (not '*'s).\n * @param ta pointer to a text area object\n * @return pointer to the text\n */\nconst char * lv_ta_get_text(const lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n    const char * txt;\n    if(ext->pwd_mode == 0) {\n        txt = lv_label_get_text(ext->label);\n    } else {\n        txt = ext->pwd_tmp;\n    }\n\n    return txt;\n}\n\n/**\n * Get the placeholder text of a text area\n * @param ta pointer to a text area object\n * @return pointer to the text\n */\nconst char * lv_ta_get_placeholder_text(lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n    const char * txt = NULL;\n\n    if(ext->placeholder) txt = lv_label_get_text(ext->label);\n\n    return txt;\n}\n\n/**\n * Get the label of a text area\n * @param ta pointer to a text area object\n * @return pointer to the label object\n */\nlv_obj_t * lv_ta_get_label(const lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    return ext->label;\n}\n\n/**\n * Get the current cursor position in character index\n * @param ta pointer to a text area object\n * @return the cursor position\n */\nuint16_t lv_ta_get_cursor_pos(const lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    return ext->cursor.pos;\n}\n\n/**\n * Get the current cursor type.\n * @param ta pointer to a text area object\n * @return element of 'lv_ta_cursor_type_t'\n */\nlv_cursor_type_t lv_ta_get_cursor_type(const lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    return ext->cursor.type;\n}\n\n/**\n * Get whether the cursor click positioning is enabled or not.\n * @param ta pointer to a text area object\n * @return true: enable click positions; false: disable\n */\nbool lv_ta_get_cursor_click_pos(lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    return ext->cursor.click_pos ? true : false;\n}\n\n/**\n * Get the password mode attribute\n * @param ta pointer to a text area object\n * @return true: password mode is enabled, false: disabled\n */\nbool lv_ta_get_pwd_mode(const lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    return ext->pwd_mode == 0 ? false : true;\n}\n\n/**\n * Get the one line configuration attribute\n * @param ta pointer to a text area object\n * @return true: one line configuration is enabled, false: disabled\n */\nbool lv_ta_get_one_line(const lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    return ext->one_line == 0 ? false : true;\n}\n\n/**\n * Get a list of accepted characters.\n * @param ta pointer to  Text Area\n * @return list of accented characters.\n */\nconst char * lv_ta_get_accepted_chars(lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n    return ext->accapted_chars;\n}\n\n/**\n * Set max length of a Text Area.\n * @param ta pointer to  Text Area\n * @return the maximal number of characters to be add\n */\nuint16_t lv_ta_get_max_length(lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    return ext->max_length;\n}\n\n/**\n * Get a style of a text area\n * @param ta pointer to a text area object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_ta_get_style(const lv_obj_t * ta, lv_ta_style_t type)\n{\n    const lv_style_t * style = NULL;\n    lv_ta_ext_t * ext        = lv_obj_get_ext_attr(ta);\n\n    switch(type) {\n        case LV_TA_STYLE_BG: style = lv_page_get_style(ta, LV_PAGE_STYLE_BG); break;\n        case LV_TA_STYLE_SB: style = lv_page_get_style(ta, LV_PAGE_STYLE_SB); break;\n        case LV_TA_STYLE_EDGE_FLASH: style = lv_page_get_style(ta, LV_PAGE_STYLE_EDGE_FLASH); break;\n        case LV_TA_STYLE_CURSOR: style = ext->cursor.style; break;\n        case LV_TA_STYLE_PLACEHOLDER:\n            if(ext->placeholder) style = lv_label_get_style(ext->placeholder, LV_LABEL_STYLE_MAIN);\n            break;\n        default: style = NULL; break;\n    }\n\n    return style;\n}\n\n/**\n * Find whether text is selected or not.\n * @param ta Text area object\n * @return whether text is selected or not\n */\nbool lv_ta_text_is_selected(const lv_obj_t * ta)\n{\n#if LV_LABEL_TEXT_SEL\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n    if((lv_label_get_text_sel_start(ext->label) == LV_LABEL_TEXT_SEL_OFF ||\n        lv_label_get_text_sel_end(ext->label) == LV_LABEL_TEXT_SEL_OFF)) {\n        return true;\n    } else {\n        return false;\n    }\n#else\n    (void)ta; /*Unused*/\n    return false;\n#endif\n}\n\n/**\n * Find whether selection mode is enabled.\n * @param ta pointer to a text area object\n * @return true: selection mode is enabled, false: disabled\n */\nbool lv_ta_get_text_sel_en(lv_obj_t * ta)\n{\n#if LV_LABEL_TEXT_SEL\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    return ext->text_sel_en;\n#else\n    (void)ta; /*Unused*/\n    return false;\n#endif\n}\n\n/**\n * Set how long show the password before changing it to '*'\n * @param ta pointer to Text area\n * @return show time in milliseconds. 0: hide immediately.\n */\nuint16_t lv_ta_get_pwd_show_time(lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n    return ext->pwd_show_time;\n}\n\n/**\n * Set cursor blink animation time\n * @param ta pointer to Text area\n * @return time blink period. 0: disable blinking\n */\nuint16_t lv_ta_get_cursor_blink_time(lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    return ext->cursor.blink_time;\n}\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Clear the selection on the text area.\n * @param ta Text area object\n */\nvoid lv_ta_clear_selection(lv_obj_t * ta)\n{\n#if LV_LABEL_TEXT_SEL\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n    if(lv_label_get_text_sel_start(ext->label) != LV_LABEL_TEXT_SEL_OFF ||\n       lv_label_get_text_sel_end(ext->label) != LV_LABEL_TEXT_SEL_OFF) {\n        lv_label_set_text_sel_start(ext->label, LV_LABEL_TEXT_SEL_OFF);\n        lv_label_set_text_sel_end(ext->label, LV_LABEL_TEXT_SEL_OFF);\n    }\n#else\n    (void)ta; /*Unused*/\n#endif\n}\n\n/**\n * Move the cursor one character right\n * @param ta pointer to a text area object\n */\nvoid lv_ta_cursor_right(lv_obj_t * ta)\n{\n    uint16_t cp = lv_ta_get_cursor_pos(ta);\n    cp++;\n    lv_ta_set_cursor_pos(ta, cp);\n}\n\n/**\n * Move the cursor one character left\n * @param ta pointer to a text area object\n */\nvoid lv_ta_cursor_left(lv_obj_t * ta)\n{\n    uint16_t cp = lv_ta_get_cursor_pos(ta);\n    if(cp > 0) {\n        cp--;\n        lv_ta_set_cursor_pos(ta, cp);\n    }\n}\n\n/**\n * Move the cursor one line down\n * @param ta pointer to a text area object\n */\nvoid lv_ta_cursor_down(lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    lv_point_t pos;\n\n    /*Get the position of the current letter*/\n    lv_label_get_letter_pos(ext->label, lv_ta_get_cursor_pos(ta), &pos);\n\n    /*Increment the y with one line and keep the valid x*/\n    const lv_style_t * label_style = lv_obj_get_style(ext->label);\n    const lv_font_t * font_p       = label_style->text.font;\n    lv_coord_t font_h              = lv_font_get_line_height(font_p);\n    pos.y += font_h + label_style->text.line_space + 1;\n    pos.x = ext->cursor.valid_x;\n\n    /*Do not go below the last line*/\n    if(pos.y < lv_obj_get_height(ext->label)) {\n        /*Get the letter index on the new cursor position and set it*/\n        uint16_t new_cur_pos = lv_label_get_letter_on(ext->label, &pos);\n\n        lv_coord_t cur_valid_x_tmp = ext->cursor.valid_x; /*Cursor position set overwrites the valid positon */\n        lv_ta_set_cursor_pos(ta, new_cur_pos);\n        ext->cursor.valid_x = cur_valid_x_tmp;\n    }\n}\n\n/**\n * Move the cursor one line up\n * @param ta pointer to a text area object\n */\nvoid lv_ta_cursor_up(lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    lv_point_t pos;\n\n    /*Get the position of the current letter*/\n    lv_label_get_letter_pos(ext->label, lv_ta_get_cursor_pos(ta), &pos);\n\n    /*Decrement the y with one line and keep the valid x*/\n    const lv_style_t * label_style = lv_obj_get_style(ext->label);\n    const lv_font_t * font         = label_style->text.font;\n    lv_coord_t font_h              = lv_font_get_line_height(font);\n    pos.y -= font_h + label_style->text.line_space - 1;\n    pos.x = ext->cursor.valid_x;\n\n    /*Get the letter index on the new cursor position and set it*/\n    uint16_t new_cur_pos       = lv_label_get_letter_on(ext->label, &pos);\n    lv_coord_t cur_valid_x_tmp = ext->cursor.valid_x; /*Cursor position set overwrites the valid positon */\n    lv_ta_set_cursor_pos(ta, new_cur_pos);\n    ext->cursor.valid_x = cur_valid_x_tmp;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the text areas\n * @param ta pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW_MAIN: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_ta_design(lv_obj_t * ta, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    if(mode == LV_DESIGN_COVER_CHK) {\n        /*Return false if the object is not covers the mask_p area*/\n        return ancestor_design(ta, mask, mode);\n    } else if(mode == LV_DESIGN_DRAW_MAIN) {\n        /*Draw the object*/\n        ancestor_design(ta, mask, mode);\n\n    } else if(mode == LV_DESIGN_DRAW_POST) {\n        ancestor_design(ta, mask, mode);\n    }\n    return true;\n}\n\n/**\n * An extended scrollable design of the page. Calls the normal design function and draws a cursor.\n * @param scrl pointer to the scrollable part of the Text area\n * @param mask  the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW_MAIN: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @return return true/false, depends on 'mode'\n */\nstatic bool lv_ta_scrollable_design(lv_obj_t * scrl, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    if(mode == LV_DESIGN_COVER_CHK) {\n        /*Return false if the object is not covers the mask_p area*/\n        return scrl_design(scrl, mask, mode);\n    } else if(mode == LV_DESIGN_DRAW_MAIN) {\n        /*Draw the object*/\n        scrl_design(scrl, mask, mode);\n    } else if(mode == LV_DESIGN_DRAW_POST) {\n        scrl_design(scrl, mask, mode);\n\n        /*Draw the cursor*/\n        lv_obj_t * ta     = lv_obj_get_parent(scrl);\n        lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n        if(ext->cursor.type == LV_CURSOR_NONE || (ext->cursor.type & LV_CURSOR_HIDDEN) || ext->cursor.state == 0) {\n            return true; /*The cursor is not visible now*/\n        }\n\n        lv_style_t cur_style;\n        get_cursor_style(ta, &cur_style);\n\n        const char * txt = lv_label_get_text(ext->label);\n\n        /*Draw he cursor according to the type*/\n        lv_area_t cur_area;\n        lv_area_copy(&cur_area, &ext->cursor.area);\n\n        cur_area.x1 += ext->label->coords.x1;\n        cur_area.y1 += ext->label->coords.y1;\n        cur_area.x2 += ext->label->coords.x1;\n        cur_area.y2 += ext->label->coords.y1;\n\n        lv_opa_t opa_scale = lv_obj_get_opa_scale(ta);\n\n        if(ext->cursor.type == LV_CURSOR_LINE) {\n            lv_draw_rect(&cur_area, mask, &cur_style, opa_scale);\n        } else if(ext->cursor.type == LV_CURSOR_BLOCK) {\n            lv_draw_rect(&cur_area, mask, &cur_style, opa_scale);\n\n            char letter_buf[8] = {0};\n            memcpy(letter_buf, &txt[ext->cursor.txt_byte_pos], lv_txt_encoded_size(&txt[ext->cursor.txt_byte_pos]));\n\n            cur_area.x1 += cur_style.body.padding.left;\n            cur_area.y1 += cur_style.body.padding.top;\n            lv_draw_label(&cur_area, mask, &cur_style, opa_scale, letter_buf, LV_TXT_FLAG_NONE, 0,\n                          LV_LABEL_TEXT_SEL_OFF, LV_LABEL_TEXT_SEL_OFF, NULL);\n\n        } else if(ext->cursor.type == LV_CURSOR_OUTLINE) {\n            cur_style.body.opa = LV_OPA_TRANSP;\n            if(cur_style.body.border.width == 0) cur_style.body.border.width = 1; /*Be sure the border will be drawn*/\n            lv_draw_rect(&cur_area, mask, &cur_style, opa_scale);\n        } else if(ext->cursor.type == LV_CURSOR_UNDERLINE) {\n            lv_draw_rect(&cur_area, mask, &cur_style, opa_scale);\n        }\n    }\n\n    return true;\n}\n\n/**\n * Signal function of the text area\n * @param ta pointer to a text area object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_ta_signal(lv_obj_t * ta, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(ta, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    if(sign == LV_SIGNAL_CLEANUP) {\n        if(ext->pwd_tmp != NULL) lv_mem_free(ext->pwd_tmp);\n\n        /* (The created label will be deleted automatically) */\n    } else if(sign == LV_SIGNAL_STYLE_CHG) {\n        if(ext->label) {\n            lv_obj_t * scrl               = lv_page_get_scrl(ta);\n            const lv_style_t * style_ta   = lv_obj_get_style(ta);\n            const lv_style_t * style_scrl = lv_obj_get_style(scrl);\n            if(ext->one_line) {\n                /*In one line mode refresh the Text Area height because 'vpad' can modify it*/\n                const lv_style_t * style_label = lv_obj_get_style(ext->label);\n                lv_coord_t font_h              = lv_font_get_line_height(style_label->text.font);\n                lv_obj_set_height(ta, font_h + style_ta->body.padding.top + style_ta->body.padding.bottom +\n                                          style_scrl->body.padding.top + style_scrl->body.padding.bottom);\n            } else {\n                /*In not one line mode refresh the Label width because 'hpad' can modify it*/\n                lv_obj_set_width(ext->label, lv_page_get_fit_width(ta));\n                lv_obj_set_pos(ext->label, style_scrl->body.padding.left,\n                               style_scrl->body.padding.right); /*Be sure the Label is in the correct position*/\n\n                if(ext->placeholder) {\n                    lv_obj_set_width(ext->placeholder, lv_page_get_fit_width(ta));\n                    lv_obj_set_pos(ext->placeholder, style_scrl->body.padding.left,\n                                   style_scrl->body.padding.top); /*Be sure the placeholder is in the correct position*/\n                }\n            }\n            lv_label_set_text(ext->label, NULL);\n        }\n    } else if(sign == LV_SIGNAL_CORD_CHG) {\n        /*Set the label width according to the text area width*/\n        if(ext->label) {\n            if(lv_obj_get_width(ta) != lv_area_get_width(param) || lv_obj_get_height(ta) != lv_area_get_height(param)) {\n                lv_obj_t * scrl               = lv_page_get_scrl(ta);\n                const lv_style_t * style_scrl = lv_obj_get_style(scrl);\n                lv_obj_set_width(ext->label, lv_page_get_fit_width(ta));\n                lv_obj_set_pos(ext->label, style_scrl->body.padding.left, style_scrl->body.padding.top);\n                lv_label_set_text(ext->label, NULL); /*Refresh the label*/\n\n                refr_cursor_area(ta);\n            }\n        }\n        /*Set the placeholder width according to the text area width*/\n        if(ext->placeholder) {\n            if(lv_obj_get_width(ta) != lv_area_get_width(param) || lv_obj_get_height(ta) != lv_area_get_height(param)) {\n                lv_obj_t * scrl               = lv_page_get_scrl(ta);\n                const lv_style_t * style_scrl = lv_obj_get_style(scrl);\n                lv_obj_set_width(ext->placeholder, lv_page_get_fit_width(ta));\n                lv_obj_set_pos(ext->placeholder, style_scrl->body.padding.left, style_scrl->body.padding.top);\n                lv_label_set_text(ext->placeholder, NULL); /*Refresh the label*/\n\n                refr_cursor_area(ta);\n            }\n        }\n    } else if(sign == LV_SIGNAL_CONTROL) {\n        uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/\n        if(c == LV_KEY_RIGHT)\n            lv_ta_cursor_right(ta);\n        else if(c == LV_KEY_LEFT)\n            lv_ta_cursor_left(ta);\n        else if(c == LV_KEY_UP)\n            lv_ta_cursor_up(ta);\n        else if(c == LV_KEY_DOWN)\n            lv_ta_cursor_down(ta);\n        else if(c == LV_KEY_BACKSPACE)\n            lv_ta_del_char(ta);\n        else if(c == LV_KEY_DEL)\n            lv_ta_del_char_forward(ta);\n        else if(c == LV_KEY_HOME)\n            lv_ta_set_cursor_pos(ta, 0);\n        else if(c == LV_KEY_END)\n            lv_ta_set_cursor_pos(ta, LV_TA_CURSOR_LAST);\n        else {\n            lv_ta_add_char(ta, c);\n        }\n    } else if(sign == LV_SIGNAL_GET_EDITABLE) {\n        bool * editable = (bool *)param;\n        *editable       = true;\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_ta\";\n    } else if(sign == LV_SIGNAL_DEFOCUS) {\n        lv_cursor_type_t cur_type;\n        cur_type = lv_ta_get_cursor_type(ta);\n        lv_ta_set_cursor_type(ta, cur_type | LV_CURSOR_HIDDEN);\n    } else if(sign == LV_SIGNAL_FOCUS) {\n#if LV_USE_GROUP\n        lv_cursor_type_t cur_type;\n        cur_type                   = lv_ta_get_cursor_type(ta);\n        lv_group_t * g             = lv_obj_get_group(ta);\n        bool editing               = lv_group_get_editing(g);\n        lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());\n\n        /*Encoders need special handling*/\n        if(indev_type == LV_INDEV_TYPE_ENCODER) {\n            if(editing)\n                lv_ta_set_cursor_type(ta, cur_type & (~LV_CURSOR_HIDDEN));\n            else\n                lv_ta_set_cursor_type(ta, cur_type | LV_CURSOR_HIDDEN);\n        } else {\n            lv_ta_set_cursor_type(ta, cur_type & (~LV_CURSOR_HIDDEN));\n        }\n#endif\n    } else if(sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_PRESSING || sign == LV_SIGNAL_PRESS_LOST ||\n              sign == LV_SIGNAL_RELEASED) {\n        update_cursor_position_on_click(ta, sign, (lv_indev_t *)param);\n    }\n    return res;\n}\n\n/**\n * Signal function of the scrollable part of the text area\n * @param scrl pointer to scrollable part of a text area object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_ta_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = scrl_signal(scrl, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_obj_t * ta     = lv_obj_get_parent(scrl);\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n    if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {\n        /*Set ext. size because the cursor might be out of this object*/\n        const lv_style_t * style_label = lv_obj_get_style(ext->label);\n        lv_coord_t font_h              = lv_font_get_line_height(style_label->text.font);\n        scrl->ext_draw_pad             = LV_MATH_MAX(scrl->ext_draw_pad, style_label->text.line_space + font_h);\n    } else if(sign == LV_SIGNAL_CORD_CHG) {\n        /*Set the label width according to the text area width*/\n        if(ext->label) {\n            if(lv_obj_get_width(scrl) != lv_area_get_width(param) ||\n               lv_obj_get_height(scrl) != lv_area_get_height(param)) {\n\n                const lv_style_t * style_scrl = lv_obj_get_style(scrl);\n                lv_obj_set_width(ext->label, lv_page_get_fit_width(ta));\n                lv_obj_set_pos(ext->label, style_scrl->body.padding.left, style_scrl->body.padding.top);\n                lv_label_set_text(ext->label, NULL); /*Refresh the label*/\n\n                refr_cursor_area(ta);\n            }\n        }\n    } else if(sign == LV_SIGNAL_PRESSING || sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_PRESS_LOST ||\n              sign == LV_SIGNAL_RELEASED) {\n        update_cursor_position_on_click(ta, sign, (lv_indev_t *)param);\n    }\n\n    return res;\n}\n\n#if LV_USE_ANIMATION\n\n/**\n * Called to blink the cursor\n * @param ta pointer to a text area\n * @param hide 1: hide the cursor, 0: show it\n */\nstatic void cursor_blink_anim(lv_obj_t * ta, lv_anim_value_t show)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    if(show != ext->cursor.state) {\n        ext->cursor.state = show == 0 ? 0 : 1;\n        if(ext->cursor.type != LV_CURSOR_NONE && (ext->cursor.type & LV_CURSOR_HIDDEN) == 0) {\n            lv_disp_t * disp = lv_obj_get_disp(ta);\n            lv_area_t area_tmp;\n            lv_area_copy(&area_tmp, &ext->cursor.area);\n            area_tmp.x1 += ext->label->coords.x1;\n            area_tmp.y1 += ext->label->coords.y1;\n            area_tmp.x2 += ext->label->coords.x1;\n            area_tmp.y2 += ext->label->coords.y1;\n            lv_inv_area(disp, &area_tmp);\n        }\n    }\n}\n\n/**\n * Dummy function to animate char hiding in pwd mode.\n * Does nothing, but a function is required in car hiding anim.\n * (pwd_char_hider callback do the real job)\n * @param ta unused\n * @param x unused\n */\nstatic void pwd_char_hider_anim(lv_obj_t * ta, lv_anim_value_t x)\n{\n    (void)ta;\n    (void)x;\n}\n\n/**\n * Call when an animation is ready to convert all characters to '*'\n * @param a pointer to the animation\n */\nstatic void pwd_char_hider_anim_ready(lv_anim_t * a)\n{\n    lv_obj_t * ta = a->var;\n    pwd_char_hider(ta);\n}\n#endif\n\n/**\n * Hide all characters (convert them to '*')\n * @param ta: pointer to text area object\n */\nstatic void pwd_char_hider(lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    if(ext->pwd_mode != 0) {\n        char * txt  = lv_label_get_text(ext->label);\n        int16_t len = lv_txt_get_encoded_length(txt);\n        bool refr   = false;\n        uint16_t i;\n        for(i = 0; i < len; i++) {\n            txt[i] = '*';\n            refr   = true;\n        }\n\n        txt[i] = '\\0';\n\n        if(refr != false) lv_label_set_text(ext->label, txt);\n    }\n}\n\n/**\n * Test an unicode character if it is accepted or not. Checks max length and accepted char list.\n * @param ta pointer to a test area object\n * @param c an unicode character\n * @return true: accapted; false: rejected\n */\nstatic bool char_is_accepted(lv_obj_t * ta, uint32_t c)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n    /*If no restriction accept it*/\n    if(ext->accapted_chars == NULL && ext->max_length == 0) return true;\n\n    /*Too many characters?*/\n    if(ext->max_length > 0 && lv_txt_get_encoded_length(lv_ta_get_text(ta)) >= ext->max_length) {\n        return false;\n    }\n\n    /*Accepted character?*/\n    if(ext->accapted_chars) {\n        uint32_t i = 0;\n        uint32_t a;\n        while(ext->accapted_chars[i] != '\\0') {\n            a = lv_txt_encoded_next(ext->accapted_chars, &i);\n            if(a == c) return true; /*Accepted*/\n        }\n\n        return false; /*The character wasn't in the list*/\n    } else {\n        return true; /*If the accepted char list in not specified the accept the character*/\n    }\n}\n\nstatic void get_cursor_style(lv_obj_t * ta, lv_style_t * style_res)\n{\n    lv_ta_ext_t * ext              = lv_obj_get_ext_attr(ta);\n    const lv_style_t * label_style = lv_obj_get_style(ext->label);\n\n    if(ext->cursor.style) {\n        lv_style_copy(style_res, ext->cursor.style);\n    } else {\n        /*If cursor style is not specified then use the modified label style */\n        lv_style_copy(style_res, label_style);\n        lv_color_t clv_color_tmp = style_res->text.color; /*Make letter color to cursor color*/\n        style_res->text.color =\n            style_res->body.main_color; /*In block mode the letter color will be current background color*/\n        style_res->body.main_color     = clv_color_tmp;\n        style_res->body.grad_color     = clv_color_tmp;\n        style_res->body.border.color   = clv_color_tmp;\n        style_res->body.border.opa     = LV_OPA_COVER;\n        style_res->body.border.width   = 1;\n        style_res->body.shadow.width   = 0;\n        style_res->body.radius         = 0;\n        style_res->body.opa            = LV_OPA_COVER;\n        style_res->body.padding.left   = 0;\n        style_res->body.padding.right  = 0;\n        style_res->body.padding.top    = 0;\n        style_res->body.padding.bottom = 0;\n        style_res->line.width          = 1;\n        style_res->body.opa            = LV_OPA_COVER;\n    }\n}\n\nstatic void refr_cursor_area(lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n\n    const lv_style_t * label_style = lv_obj_get_style(ext->label);\n\n    lv_style_t cur_style;\n    get_cursor_style(ta, &cur_style);\n\n    uint16_t cur_pos = lv_ta_get_cursor_pos(ta);\n    const char * txt = lv_label_get_text(ext->label);\n\n    uint32_t byte_pos;\n    byte_pos = lv_txt_encoded_get_byte_id(txt, cur_pos);\n\n    uint32_t letter = lv_txt_encoded_next(&txt[byte_pos], NULL);\n\n    lv_coord_t letter_h = lv_font_get_line_height(label_style->text.font);\n\n    /*Set letter_w (set not 0 on non printable but valid chars)*/\n    lv_coord_t letter_w;\n    if(letter == '\\0' || letter == '\\n' || letter == '\\r') {\n        letter_w = lv_font_get_glyph_width(label_style->text.font, ' ', '\\0');\n    } else {\n        /*`letter_next` parameter is '\\0' to ignore kerning*/\n        letter_w = lv_font_get_glyph_width(label_style->text.font, letter, '\\0');\n    }\n\n    lv_point_t letter_pos;\n    lv_label_get_letter_pos(ext->label, cur_pos, &letter_pos);\n\n    /*If the cursor is out of the text (most right) draw it to the next line*/\n    if(letter_pos.x + ext->label->coords.x1 + letter_w > ext->label->coords.x2 && ext->one_line == 0 &&\n       lv_label_get_align(ext->label) != LV_LABEL_ALIGN_RIGHT) {\n        letter_pos.x = 0;\n        letter_pos.y += letter_h + label_style->text.line_space;\n\n        if(letter != '\\0') {\n            byte_pos += lv_txt_encoded_size(&txt[byte_pos]);\n            letter = lv_txt_encoded_next(&txt[byte_pos], NULL);\n        }\n\n        if(letter == '\\0' || letter == '\\n' || letter == '\\r') {\n            letter_w = lv_font_get_glyph_width(label_style->text.font, ' ', '\\0');\n        } else {\n            letter_w = lv_font_get_glyph_width(label_style->text.font, letter, '\\0');\n        }\n    }\n\n    /*Save the byte position. It is required to draw `LV_CURSOR_BLOCK`*/\n    ext->cursor.txt_byte_pos = byte_pos;\n\n    /*Draw he cursor according to the type*/\n    lv_area_t cur_area;\n\n    if(ext->cursor.type == LV_CURSOR_LINE) {\n        cur_area.x1 =\n            letter_pos.x + cur_style.body.padding.left - (cur_style.line.width >> 1) - (cur_style.line.width & 0x1);\n        cur_area.y1 = letter_pos.y + cur_style.body.padding.top;\n        cur_area.x2 = letter_pos.x + cur_style.body.padding.right + (cur_style.line.width >> 1);\n        cur_area.y2 = letter_pos.y + cur_style.body.padding.bottom + letter_h;\n    } else if(ext->cursor.type == LV_CURSOR_BLOCK) {\n        cur_area.x1 = letter_pos.x - cur_style.body.padding.left;\n        cur_area.y1 = letter_pos.y - cur_style.body.padding.top;\n        cur_area.x2 = letter_pos.x + cur_style.body.padding.right + letter_w;\n        cur_area.y2 = letter_pos.y + cur_style.body.padding.bottom + letter_h;\n\n    } else if(ext->cursor.type == LV_CURSOR_OUTLINE) {\n        cur_area.x1 = letter_pos.x - cur_style.body.padding.left;\n        cur_area.y1 = letter_pos.y - cur_style.body.padding.top;\n        cur_area.x2 = letter_pos.x + cur_style.body.padding.right + letter_w;\n        cur_area.y2 = letter_pos.y + cur_style.body.padding.bottom + letter_h;\n    } else if(ext->cursor.type == LV_CURSOR_UNDERLINE) {\n        cur_area.x1 = letter_pos.x + cur_style.body.padding.left;\n        cur_area.y1 = letter_pos.y + cur_style.body.padding.top + letter_h - (cur_style.line.width >> 1);\n        cur_area.x2 = letter_pos.x + cur_style.body.padding.right + letter_w;\n        cur_area.y2 = letter_pos.y + cur_style.body.padding.bottom + letter_h + (cur_style.line.width >> 1) +\n                      (cur_style.line.width & 0x1);\n    }\n\n    /*Save the new area*/\n    lv_disp_t * disp = lv_obj_get_disp(ta);\n    lv_area_t area_tmp;\n    lv_area_copy(&area_tmp, &ext->cursor.area);\n    area_tmp.x1 += ext->label->coords.x1;\n    area_tmp.y1 += ext->label->coords.y1;\n    area_tmp.x2 += ext->label->coords.x1;\n    area_tmp.y2 += ext->label->coords.y1;\n    lv_inv_area(disp, &area_tmp);\n\n    lv_area_copy(&ext->cursor.area, &cur_area);\n\n    lv_area_copy(&area_tmp, &ext->cursor.area);\n    area_tmp.x1 += ext->label->coords.x1;\n    area_tmp.y1 += ext->label->coords.y1;\n    area_tmp.x2 += ext->label->coords.x1;\n    area_tmp.y2 += ext->label->coords.y1;\n    lv_inv_area(disp, &area_tmp);\n}\n\nstatic void placeholder_update(lv_obj_t * ta)\n{\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    const char * ta_text;\n\n    if(ext->placeholder == NULL) return;\n\n    ta_text = lv_ta_get_text(ta);\n\n    if(ta_text[0] == '\\0') {\n        /*Be sure the main label and the placeholder has the same coordinates*/\n        lv_obj_t * scrl               = lv_page_get_scrl(ta);\n        const lv_style_t * style_scrl = lv_obj_get_style(scrl);\n        lv_obj_set_pos(ext->placeholder, style_scrl->body.padding.left, style_scrl->body.padding.top);\n        lv_obj_set_pos(ext->label, style_scrl->body.padding.left, style_scrl->body.padding.top);\n\n        lv_obj_set_width(ext->placeholder, lv_page_get_fit_width(ta));\n        lv_obj_set_hidden(ext->placeholder, false);\n    } else {\n        lv_obj_set_hidden(ext->placeholder, true);\n    }\n}\n\nstatic void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign, lv_indev_t * click_source)\n{\n\n    if(click_source == NULL) return;\n\n    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);\n    if(ext->cursor.click_pos == 0) return;\n    if(ext->cursor.type == LV_CURSOR_NONE) return;\n\n    if(lv_indev_get_type(click_source) == LV_INDEV_TYPE_KEYPAD ||\n       lv_indev_get_type(click_source) == LV_INDEV_TYPE_ENCODER) {\n        return;\n    }\n\n    lv_area_t label_coords;\n    lv_obj_get_coords(ext->label, &label_coords);\n\n    lv_point_t point_act, vect_act;\n    lv_indev_get_point(click_source, &point_act);\n    lv_indev_get_vect(click_source, &vect_act);\n\n    if(point_act.x < 0 || point_act.y < 0) return; /*Ignore event from keypad*/\n    lv_point_t relative_position;\n    relative_position.x = point_act.x - label_coords.x1;\n    relative_position.y = point_act.y - label_coords.y1;\n\n    lv_coord_t label_width = lv_obj_get_width(ext->label);\n\n    uint16_t index_of_char_at_position;\n\n#if LV_LABEL_TEXT_SEL\n    lv_label_ext_t * ext_label = lv_obj_get_ext_attr(ext->label);\n    bool click_outside_label;\n    /*Check if the click happened on the left side of the area outside the label*/\n    if(relative_position.x < 0) {\n        index_of_char_at_position = 0;\n        click_outside_label       = true;\n    }\n    /*Check if the click happened on the right side of the area outside the label*/\n    else if(relative_position.x >= label_width) {\n        index_of_char_at_position = LV_TA_CURSOR_LAST;\n        click_outside_label       = true;\n    } else {\n        index_of_char_at_position = lv_label_get_letter_on(ext->label, &relative_position);\n        click_outside_label       = !lv_label_is_char_under_pos(ext->label, &relative_position);\n    }\n\n    if(ext->text_sel_en) {\n        if(!ext->text_sel_in_prog && !click_outside_label && sign == LV_SIGNAL_PRESSED) {\n            /*Input device just went down. Store the selection start position*/\n            ext->tmp_sel_start    = index_of_char_at_position;\n            ext->tmp_sel_end      = LV_LABEL_TEXT_SEL_OFF;\n            ext->text_sel_in_prog = 1;\n            lv_obj_set_drag(lv_page_get_scrl(ta), false);\n        } else if(ext->text_sel_in_prog && sign == LV_SIGNAL_PRESSING) {\n            /*Input device may be moving. Store the end position */\n            ext->tmp_sel_end = index_of_char_at_position;\n        } else if(ext->text_sel_in_prog && (sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_RELEASED)) {\n            /*Input device is released. Check if anything was selected.*/\n            lv_obj_set_drag(lv_page_get_scrl(ta), true);\n        }\n    }\n\n    if(ext->text_sel_in_prog || sign == LV_SIGNAL_PRESSED) lv_ta_set_cursor_pos(ta, index_of_char_at_position);\n\n    if(ext->text_sel_in_prog) {\n        /*If the selected area has changed then update the real values and*/\n        /*invalidate the text area.*/\n\n        if(ext->tmp_sel_start > ext->tmp_sel_end) {\n            if(ext_label->txt_sel_start != ext->tmp_sel_end || ext_label->txt_sel_end != ext->tmp_sel_start) {\n                ext_label->txt_sel_start = ext->tmp_sel_end;\n                ext_label->txt_sel_end   = ext->tmp_sel_start;\n                lv_obj_invalidate(ta);\n            }\n        } else if(ext->tmp_sel_start < ext->tmp_sel_end) {\n            if(ext_label->txt_sel_start != ext->tmp_sel_start || ext_label->txt_sel_end != ext->tmp_sel_end) {\n                ext_label->txt_sel_start = ext->tmp_sel_start;\n                ext_label->txt_sel_end   = ext->tmp_sel_end;\n                lv_obj_invalidate(ta);\n            }\n        } else {\n            if(ext_label->txt_sel_start != LV_LABEL_TEXT_SEL_OFF || ext_label->txt_sel_end != LV_LABEL_TEXT_SEL_OFF) {\n                ext_label->txt_sel_start = LV_LABEL_TEXT_SEL_OFF;\n                ext_label->txt_sel_end   = LV_LABEL_TEXT_SEL_OFF;\n                lv_obj_invalidate(ta);\n            }\n        }\n        /*Finish selection if necessary */\n        if(sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_RELEASED) {\n            ext->text_sel_in_prog = 0;\n        }\n    }\n#else\n    /*Check if the click happened on the left side of the area outside the label*/\n    if(relative_position.x < 0) {\n        index_of_char_at_position = 0;\n    }\n    /*Check if the click happened on the right side of the area outside the label*/\n    else if(relative_position.x >= label_width) {\n        index_of_char_at_position = LV_TA_CURSOR_LAST;\n    } else {\n        index_of_char_at_position = lv_label_get_letter_on(ext->label, &relative_position);\n    }\n\n    if(sign == LV_SIGNAL_PRESSED) lv_ta_set_cursor_pos(ta, index_of_char_at_position);\n#endif\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_table.c",
    "content": "/**\n * @file lv_table.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_table.h\"\n#if LV_USE_TABLE != 0\n\n#include \"libs/lvgl/lv_misc/lv_txt.h\"\n#include \"libs/lvgl/lv_misc/lv_math.h\"\n#include \"libs/lvgl/lv_draw/lv_draw_label.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic bool lv_table_design(lv_obj_t * table, const lv_area_t * mask, lv_design_mode_t mode);\nstatic lv_res_t lv_table_signal(lv_obj_t * table, lv_signal_t sign, void * param);\nstatic lv_coord_t get_row_height(lv_obj_t * table, uint16_t row_id);\nstatic void refr_size(lv_obj_t * table);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\nstatic lv_design_cb_t ancestor_scrl_design;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a table object\n * @param par pointer to an object, it will be the parent of the new table\n * @param copy pointer to a table object, if not NULL then the new object will be copied from it\n * @return pointer to the created table\n */\nlv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"table create started\");\n\n    /*Create the ancestor of table*/\n    lv_obj_t * new_table = lv_obj_create(par, copy);\n    lv_mem_assert(new_table);\n    if(new_table == NULL) return NULL;\n\n    /*Allocate the table type specific extended data*/\n    lv_table_ext_t * ext = lv_obj_allocate_ext_attr(new_table, sizeof(lv_table_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_table);\n    if(ancestor_scrl_design == NULL) ancestor_scrl_design = lv_obj_get_design_cb(new_table);\n\n    /*Initialize the allocated 'ext' */\n    ext->cell_data     = NULL;\n    ext->cell_style[0] = &lv_style_plain;\n    ext->cell_style[1] = &lv_style_plain;\n    ext->cell_style[2] = &lv_style_plain;\n    ext->cell_style[3] = &lv_style_plain;\n    ext->col_cnt       = 0;\n    ext->row_cnt       = 0;\n\n    uint16_t i;\n    for(i = 0; i < LV_TABLE_COL_MAX; i++) {\n        ext->col_w[i] = LV_DPI;\n    }\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_cb(new_table, lv_table_signal);\n    lv_obj_set_design_cb(new_table, lv_table_design);\n\n    /*Init the new table table*/\n    if(copy == NULL) {\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_table_set_style(new_table, LV_TABLE_STYLE_BG, th->style.table.bg);\n            lv_table_set_style(new_table, LV_TABLE_STYLE_CELL1, th->style.table.cell);\n            lv_table_set_style(new_table, LV_TABLE_STYLE_CELL2, th->style.table.cell);\n            lv_table_set_style(new_table, LV_TABLE_STYLE_CELL3, th->style.table.cell);\n            lv_table_set_style(new_table, LV_TABLE_STYLE_CELL4, th->style.table.cell);\n        } else {\n            lv_table_set_style(new_table, LV_TABLE_STYLE_BG, &lv_style_plain_color);\n        }\n        lv_obj_set_click(new_table, false); /*Can be removed if click support is added*/\n    }\n    /*Copy an existing table*/\n    else {\n        lv_table_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->cell_style[0]        = copy_ext->cell_style[0];\n        ext->cell_style[1]        = copy_ext->cell_style[1];\n        ext->cell_style[2]        = copy_ext->cell_style[2];\n        ext->cell_style[3]        = copy_ext->cell_style[3];\n        ext->col_cnt              = copy_ext->col_cnt;\n        ext->row_cnt              = copy_ext->row_cnt;\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_table);\n    }\n\n    LV_LOG_INFO(\"table created\");\n\n    return new_table;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the value of a cell.\n * @param table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @param txt text to display in the cell. It will be copied and saved so this variable is not\n * required after this function call.\n */\nvoid lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const char * txt)\n{\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n    if(row >= ext->row_cnt || col >= ext->col_cnt) {\n        LV_LOG_WARN(\"lv_table_set_cell_value: invalid row or column\");\n        return;\n    }\n    uint32_t cell = row * ext->col_cnt + col;\n    lv_table_cell_format_t format;\n\n    /*Save the format byte*/\n    if(ext->cell_data[cell]) {\n        format.format_byte = ext->cell_data[cell][0];\n    }\n    /*Initialize the format byte*/\n    else {\n        format.s.align       = LV_LABEL_ALIGN_LEFT;\n        format.s.right_merge = 0;\n        format.s.type        = 0;\n        format.s.crop        = 0;\n    }\n\n    ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], strlen(txt) + 2); /*+1: trailing '\\0; +1: format byte*/\n    strcpy(ext->cell_data[cell] + 1, txt);                                        /*Leave the format byte*/\n    ext->cell_data[cell][0] = format.format_byte;\n    refr_size(table);\n}\n\n/**\n * Set the number of rows\n * @param table table pointer to a Table object\n * @param row_cnt number of rows\n */\nvoid lv_table_set_row_cnt(lv_obj_t * table, uint16_t row_cnt)\n{\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n    uint16_t old_row_cnt = ext->row_cnt;\n    ext->row_cnt         = row_cnt;\n\n    if(ext->row_cnt > 0 && ext->col_cnt > 0) {\n        ext->cell_data = lv_mem_realloc(ext->cell_data, ext->row_cnt * ext->col_cnt * sizeof(char *));\n\n        /*Initilize the new fields*/\n        if(old_row_cnt < row_cnt) {\n            uint16_t old_cell_cnt = old_row_cnt * ext->col_cnt;\n            uint32_t new_cell_cnt = ext->col_cnt * ext->row_cnt;\n            memset(&ext->cell_data[old_cell_cnt], 0, (new_cell_cnt - old_cell_cnt) * sizeof(ext->cell_data[0]));\n        }\n    } else {\n        lv_mem_free(ext->cell_data);\n        ext->cell_data = NULL;\n    }\n\n    refr_size(table);\n}\n\n/**\n * Set the number of columns\n * @param table table pointer to a Table object\n * @param col_cnt number of columns. Must be < LV_TABLE_COL_MAX\n */\nvoid lv_table_set_col_cnt(lv_obj_t * table, uint16_t col_cnt)\n{\n\n    if(col_cnt >= LV_TABLE_COL_MAX) {\n        LV_LOG_WARN(\"lv_table_set_col_cnt: too many columns. Must be < LV_TABLE_COL_MAX.\");\n        return;\n    }\n\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n    uint16_t old_col_cnt = ext->col_cnt;\n    ext->col_cnt         = col_cnt;\n\n    if(ext->row_cnt > 0 && ext->col_cnt > 0) {\n        ext->cell_data = lv_mem_realloc(ext->cell_data, ext->row_cnt * ext->col_cnt * sizeof(char *));\n        /*Initilize the new fields*/\n        if(old_col_cnt < col_cnt) {\n            uint16_t old_cell_cnt = old_col_cnt * ext->row_cnt;\n            uint32_t new_cell_cnt = ext->col_cnt * ext->row_cnt;\n            memset(&ext->cell_data[old_cell_cnt], 0, (new_cell_cnt - old_cell_cnt) * sizeof(ext->cell_data[0]));\n        }\n\n    } else {\n        lv_mem_free(ext->cell_data);\n        ext->cell_data = NULL;\n    }\n    refr_size(table);\n}\n\n/**\n * Set the width of a column\n * @param table table pointer to a Table object\n * @param col_id id of the column [0 .. LV_TABLE_COL_MAX -1]\n * @param w width of the column\n */\nvoid lv_table_set_col_width(lv_obj_t * table, uint16_t col_id, lv_coord_t w)\n{\n    if(col_id >= LV_TABLE_COL_MAX) {\n        LV_LOG_WARN(\"lv_table_set_col_width: too big 'col_id'. Must be < LV_TABLE_COL_MAX.\");\n        return;\n    }\n\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n    ext->col_w[col_id]   = w;\n    refr_size(table);\n}\n\n/**\n * Set the text align in a cell\n * @param table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @param align LV_LABEL_ALIGN_LEFT or LV_LABEL_ALIGN_CENTER or LV_LABEL_ALIGN_RIGHT\n */\nvoid lv_table_set_cell_align(lv_obj_t * table, uint16_t row, uint16_t col, lv_label_align_t align)\n{\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n    if(row >= ext->row_cnt || col >= ext->col_cnt) {\n        LV_LOG_WARN(\"lv_table_set_cell_align: invalid row or column\");\n        return;\n    }\n    uint32_t cell = row * ext->col_cnt + col;\n\n    if(ext->cell_data[cell] == NULL) {\n        ext->cell_data[cell]    = lv_mem_alloc(2); /*+1: trailing '\\0; +1: format byte*/\n        ext->cell_data[cell][0] = 0;\n        ext->cell_data[cell][1] = '\\0';\n    }\n\n    lv_table_cell_format_t format;\n    format.format_byte      = ext->cell_data[cell][0];\n    format.s.align          = align;\n    ext->cell_data[cell][0] = format.format_byte;\n}\n\n/**\n * Set the type of a cell.\n * @param table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @param type 1,2,3 or 4. The cell style will be chosen accordingly.\n */\nvoid lv_table_set_cell_type(lv_obj_t * table, uint16_t row, uint16_t col, uint8_t type)\n{\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n    if(row >= ext->row_cnt || col >= ext->col_cnt) {\n        LV_LOG_WARN(\"lv_table_set_cell_type: invalid row or column\");\n        return;\n    }\n    uint32_t cell = row * ext->col_cnt + col;\n\n    if(ext->cell_data[cell] == NULL) {\n        ext->cell_data[cell]    = lv_mem_alloc(2); /*+1: trailing '\\0; +1: format byte*/\n        ext->cell_data[cell][0] = 0;\n        ext->cell_data[cell][1] = '\\0';\n    }\n\n    if(type > 0) type--; /*User gives 1,2,3,4 but easier to handle 0, 1, 2, 3*/\n    if(type >= LV_TABLE_CELL_STYLE_CNT) type = LV_TABLE_CELL_STYLE_CNT - 1;\n\n    lv_table_cell_format_t format;\n    format.format_byte      = ext->cell_data[cell][0];\n    format.s.type           = type;\n    ext->cell_data[cell][0] = format.format_byte;\n}\n\n/**\n * Set the cell crop. (Don't adjust the height of the cell according to its content)\n * @param table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @param crop true: crop the cell content; false: set the cell height to the content.\n */\nvoid lv_table_set_cell_crop(lv_obj_t * table, uint16_t row, uint16_t col, bool crop)\n{\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n    if(row >= ext->row_cnt || col >= ext->col_cnt) {\n        LV_LOG_WARN(\"lv_table_set_cell_crop: invalid row or column\");\n        return;\n    }\n    uint32_t cell = row * ext->col_cnt + col;\n\n    if(ext->cell_data[cell] == NULL) {\n        ext->cell_data[cell]    = lv_mem_alloc(2); /*+1: trailing '\\0; +1: format byte*/\n        ext->cell_data[cell][0] = 0;\n        ext->cell_data[cell][1] = '\\0';\n    }\n\n    lv_table_cell_format_t format;\n    format.format_byte      = ext->cell_data[cell][0];\n    format.s.crop           = crop;\n    ext->cell_data[cell][0] = format.format_byte;\n}\n\n/**\n * Merge a cell with the right neighbor. The value of the cell to the right won't be displayed.\n * @param table table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @param en true: merge right; false: don't merge right\n */\nvoid lv_table_set_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col, bool en)\n{\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n    if(row >= ext->row_cnt || col >= ext->col_cnt) {\n        LV_LOG_WARN(\"lv_table_set_cell_merge_right: invalid row or column\");\n        return;\n    }\n\n    uint32_t cell = row * ext->col_cnt + col;\n\n    if(ext->cell_data[cell] == NULL) {\n        ext->cell_data[cell]    = lv_mem_alloc(2); /*+1: trailing '\\0; +1: format byte*/\n        ext->cell_data[cell][0] = 0;\n        ext->cell_data[cell][1] = '\\0';\n    }\n\n    lv_table_cell_format_t format;\n    format.format_byte      = ext->cell_data[cell][0];\n    format.s.right_merge    = en ? 1 : 0;\n    ext->cell_data[cell][0] = format.format_byte;\n    refr_size(table);\n}\n\n/**\n * Set a style of a table.\n * @param table pointer to table object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_table_set_style(lv_obj_t * table, lv_table_style_t type, const lv_style_t * style)\n{\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n\n    switch(type) {\n        case LV_TABLE_STYLE_BG:\n            lv_obj_set_style(table, style);\n            refr_size(table);\n            break;\n        case LV_TABLE_STYLE_CELL1:\n            ext->cell_style[0] = style;\n            refr_size(table);\n            break;\n        case LV_TABLE_STYLE_CELL2:\n            ext->cell_style[1] = style;\n            refr_size(table);\n            break;\n        case LV_TABLE_STYLE_CELL3:\n            ext->cell_style[2] = style;\n            refr_size(table);\n            break;\n        case LV_TABLE_STYLE_CELL4:\n            ext->cell_style[3] = style;\n            refr_size(table);\n            break;\n    }\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the value of a cell.\n * @param table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @return text in the cell\n */\nconst char * lv_table_get_cell_value(lv_obj_t * table, uint16_t row, uint16_t col)\n{\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n    if(row >= ext->row_cnt || col >= ext->col_cnt) {\n        LV_LOG_WARN(\"lv_table_set_cell_value: invalid row or column\");\n        return \"\";\n    }\n    uint32_t cell = row * ext->col_cnt + col;\n\n    if(ext->cell_data[cell] == NULL) return \"\";\n\n    return &ext->cell_data[cell][1]; /*Skip the format byte*/\n}\n\n/**\n * Get the number of rows.\n * @param table table pointer to a Table object\n * @return number of rows.\n */\nuint16_t lv_table_get_row_cnt(lv_obj_t * table)\n{\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n    return ext->row_cnt;\n}\n\n/**\n * Get the number of columns.\n * @param table table pointer to a Table object\n * @return number of columns.\n */\nuint16_t lv_table_get_col_cnt(lv_obj_t * table)\n{\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n    return ext->col_cnt;\n}\n\n/**\n * Get the width of a column\n * @param table table pointer to a Table object\n * @param col_id id of the column [0 .. LV_TABLE_COL_MAX -1]\n * @return width of the column\n */\nlv_coord_t lv_table_get_col_width(lv_obj_t * table, uint16_t col_id)\n{\n    if(col_id >= LV_TABLE_COL_MAX) {\n        LV_LOG_WARN(\"lv_table_set_col_width: too big 'col_id'. Must be < LV_TABLE_COL_MAX.\");\n        return 0;\n    }\n\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n    return ext->col_w[col_id];\n}\n\n/**\n * Get the text align of a cell\n * @param table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @return LV_LABEL_ALIGN_LEFT (default in case of error) or LV_LABEL_ALIGN_CENTER or\n * LV_LABEL_ALIGN_RIGHT\n */\nlv_label_align_t lv_table_get_cell_align(lv_obj_t * table, uint16_t row, uint16_t col)\n{\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n    if(row >= ext->row_cnt || col >= ext->col_cnt) {\n        LV_LOG_WARN(\"lv_table_set_cell_align: invalid row or column\");\n        return LV_LABEL_ALIGN_LEFT; /*Just return with something*/\n    }\n    uint32_t cell = row * ext->col_cnt + col;\n\n    if(ext->cell_data[cell] == NULL)\n        return LV_LABEL_ALIGN_LEFT; /*Just return with something*/\n    else {\n        lv_table_cell_format_t format;\n        format.format_byte = ext->cell_data[cell][0];\n        return format.s.align;\n    }\n}\n\n/**\n * Get the type of a cell\n * @param table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @return 1,2,3 or 4\n */\nlv_label_align_t lv_table_get_cell_type(lv_obj_t * table, uint16_t row, uint16_t col)\n{\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n    if(row >= ext->row_cnt || col >= ext->col_cnt) {\n        LV_LOG_WARN(\"lv_table_get_cell_type: invalid row or column\");\n        return 1; /*Just return with something*/\n    }\n    uint32_t cell = row * ext->col_cnt + col;\n\n    if(ext->cell_data[cell] == NULL)\n        return 1; /*Just return with something*/\n    else {\n        lv_table_cell_format_t format;\n        format.format_byte = ext->cell_data[cell][0];\n        return format.s.type + 1; /*0,1,2,3 is stored but user sees 1,2,3,4*/\n    }\n}\n\n/**\n * Get the crop property of a cell\n * @param table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @return true: text crop enabled; false: disabled\n */\nlv_label_align_t lv_table_get_cell_crop(lv_obj_t * table, uint16_t row, uint16_t col)\n{\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n    if(row >= ext->row_cnt || col >= ext->col_cnt) {\n        LV_LOG_WARN(\"lv_table_get_cell_crop: invalid row or column\");\n        return false; /*Just return with something*/\n    }\n    uint32_t cell = row * ext->col_cnt + col;\n\n    if(ext->cell_data[cell] == NULL)\n        return false; /*Just return with something*/\n    else {\n        lv_table_cell_format_t format;\n        format.format_byte = ext->cell_data[cell][0];\n        return format.s.crop;\n    }\n}\n\n/**\n * Get the cell merge attribute.\n * @param table table pointer to a Table object\n * @param row id of the row [0 .. row_cnt -1]\n * @param col id of the column [0 .. col_cnt -1]\n * @return true: merge right; false: don't merge right\n */\nbool lv_table_get_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col)\n{\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n    if(row >= ext->row_cnt || col >= ext->col_cnt) {\n        LV_LOG_WARN(\"lv_table_get_cell_merge_right: invalid row or column\");\n        return false;\n    }\n\n    uint32_t cell = row * ext->col_cnt + col;\n\n    if(ext->cell_data[cell] == NULL)\n        return false;\n    else {\n        lv_table_cell_format_t format;\n        format.format_byte = ext->cell_data[cell][0];\n        return format.s.right_merge ? true : false;\n    }\n}\n\n/**\n * Get style of a table.\n * @param table pointer to table object\n * @param type which style should be get\n * @return style pointer to the style\n */\nconst lv_style_t * lv_table_get_style(const lv_obj_t * table, lv_table_style_t type)\n{\n    lv_table_ext_t * ext     = lv_obj_get_ext_attr(table);\n    const lv_style_t * style = NULL;\n\n    switch(type) {\n        case LV_TABLE_STYLE_BG: style = lv_obj_get_style(table); break;\n        case LV_TABLE_STYLE_CELL1: style = ext->cell_style[0]; break;\n        case LV_TABLE_STYLE_CELL2: style = ext->cell_style[1]; break;\n        case LV_TABLE_STYLE_CELL3: style = ext->cell_style[2]; break;\n        case LV_TABLE_STYLE_CELL4: style = ext->cell_style[3]; break;\n        default: return NULL;\n    }\n\n    return style;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Handle the drawing related tasks of the tables\n * @param table pointer to an object\n * @param mask the object will be drawn only in this area\n * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area\n *                                  (return 'true' if yes)\n *             LV_DESIGN_DRAW: draw the object (always return 'true')\n *             LV_DESIGN_DRAW_POST: drawing after every children are drawn\n * @param return true/false, depends on 'mode'\n */\nstatic bool lv_table_design(lv_obj_t * table, const lv_area_t * mask, lv_design_mode_t mode)\n{\n    /*Return false if the object is not covers the mask_p area*/\n    if(mode == LV_DESIGN_COVER_CHK) {\n        return false;\n    }\n    /*Draw the object*/\n    else if(mode == LV_DESIGN_DRAW_MAIN) {\n        ancestor_scrl_design(table, mask, mode);\n\n        lv_table_ext_t * ext        = lv_obj_get_ext_attr(table);\n        const lv_style_t * bg_style = lv_obj_get_style(table);\n        const lv_style_t * cell_style;\n        lv_coord_t h_row;\n        lv_point_t txt_size;\n        lv_area_t cell_area;\n        lv_area_t txt_area;\n        lv_txt_flag_t txt_flags;\n        lv_opa_t opa_scale = lv_obj_get_opa_scale(table);\n\n        uint16_t col;\n        uint16_t row;\n        uint16_t cell = 0;\n\n        cell_area.y2 = table->coords.y1 + bg_style->body.padding.top;\n        for(row = 0; row < ext->row_cnt; row++) {\n            h_row = get_row_height(table, row);\n\n            cell_area.y1 = cell_area.y2;\n            cell_area.y2 = cell_area.y1 + h_row;\n\n            cell_area.x2 = table->coords.x1 + bg_style->body.padding.left;\n\n            for(col = 0; col < ext->col_cnt; col++) {\n\n                lv_table_cell_format_t format;\n                if(ext->cell_data[cell]) {\n                    format.format_byte = ext->cell_data[cell][0];\n                } else {\n                    format.s.right_merge = 0;\n                    format.s.align       = LV_LABEL_ALIGN_LEFT;\n                    format.s.type        = 0;\n                    format.s.crop        = 1;\n                }\n\n                cell_style   = ext->cell_style[format.s.type];\n                cell_area.x1 = cell_area.x2;\n                cell_area.x2 = cell_area.x1 + ext->col_w[col];\n\n                uint16_t col_merge = 0;\n                for(col_merge = 0; col_merge + col < ext->col_cnt - 1; col_merge++) {\n\n                    if(ext->cell_data[cell + col_merge] != NULL) {\n                        format.format_byte = ext->cell_data[cell + col_merge][0];\n                        if(format.s.right_merge)\n                            cell_area.x2 += ext->col_w[col + col_merge + 1];\n                        else\n                            break;\n                    } else {\n                        break;\n                    }\n                }\n\n                lv_draw_rect(&cell_area, mask, cell_style, opa_scale);\n\n                if(ext->cell_data[cell]) {\n\n                    txt_area.x1 = cell_area.x1 + cell_style->body.padding.left;\n                    txt_area.x2 = cell_area.x2 - cell_style->body.padding.right;\n                    txt_area.y1 = cell_area.y1 + cell_style->body.padding.top;\n                    txt_area.y2 = cell_area.y2 - cell_style->body.padding.bottom;\n                    /*Align the content to the middle if not cropped*/\n                    if(format.s.crop == 0) {\n                        txt_flags = LV_TXT_FLAG_NONE;\n                    } else {\n                        txt_flags = LV_TXT_FLAG_EXPAND;\n                    }\n\n                    lv_txt_get_size(&txt_size, ext->cell_data[cell] + 1, cell_style->text.font,\n                                    cell_style->text.letter_space, cell_style->text.line_space,\n                                    lv_area_get_width(&txt_area), txt_flags);\n\n                    /*Align the content to the middle if not cropped*/\n                    if(format.s.crop == 0) {\n                        txt_area.y1 = cell_area.y1 + h_row / 2 - txt_size.y / 2;\n                        txt_area.y2 = cell_area.y1 + h_row / 2 + txt_size.y / 2;\n                    }\n\n                    switch(format.s.align) {\n                        default:\n                        case LV_LABEL_ALIGN_LEFT: txt_flags |= LV_TXT_FLAG_NONE; break;\n                        case LV_LABEL_ALIGN_RIGHT: txt_flags |= LV_TXT_FLAG_RIGHT; break;\n                        case LV_LABEL_ALIGN_CENTER: txt_flags |= LV_TXT_FLAG_CENTER; break;\n                    }\n\n                    lv_area_t label_mask;\n                    bool label_mask_ok;\n                    label_mask_ok = lv_area_intersect(&label_mask, mask, &cell_area);\n                    if(label_mask_ok) {\n                        lv_draw_label(&txt_area, &label_mask, cell_style, opa_scale, ext->cell_data[cell] + 1,\n                                      txt_flags, NULL, -1, -1, NULL);\n                    }\n                    /*Draw lines after '\\n's*/\n                    lv_point_t p1;\n                    lv_point_t p2;\n                    p1.x = cell_area.x1;\n                    p2.x = cell_area.x2;\n                    uint16_t i;\n                    for(i = 1; ext->cell_data[cell][i] != '\\0'; i++) {\n                        if(ext->cell_data[cell][i] == '\\n') {\n                            ext->cell_data[cell][i] = '\\0';\n                            lv_txt_get_size(&txt_size, ext->cell_data[cell] + 1, cell_style->text.font,\n                                            cell_style->text.letter_space, cell_style->text.line_space,\n                                            lv_area_get_width(&txt_area), txt_flags);\n\n                            p1.y = txt_area.y1 + txt_size.y + cell_style->text.line_space / 2;\n                            p2.y = txt_area.y1 + txt_size.y + cell_style->text.line_space / 2;\n                            lv_draw_line(&p1, &p2, mask, cell_style, opa_scale);\n\n                            ext->cell_data[cell][i] = '\\n';\n                        }\n                    }\n                }\n\n                cell += col_merge + 1;\n                col += col_merge;\n            }\n        }\n    }\n    /*Post draw when the children are drawn*/\n    else if(mode == LV_DESIGN_DRAW_POST) {\n    }\n\n    return true;\n}\n\n/**\n * Signal function of the table\n * @param table pointer to a table object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_table_signal(lv_obj_t * table, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(table, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    if(sign == LV_SIGNAL_CLEANUP) {\n        /*Free the cell texts*/\n        lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n        uint16_t cell;\n        for(cell = 0; cell < ext->col_cnt * ext->row_cnt; cell++) {\n            if(ext->cell_data[cell]) {\n                lv_mem_free(ext->cell_data[cell]);\n                ext->cell_data[cell] = NULL;\n            }\n        }\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_table\";\n    }\n\n    return res;\n}\n\nstatic void refr_size(lv_obj_t * table)\n{\n    lv_coord_t h = 0;\n    lv_coord_t w = 0;\n\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n\n    uint16_t i;\n    for(i = 0; i < ext->col_cnt; i++) {\n        w += ext->col_w[i];\n    }\n    for(i = 0; i < ext->row_cnt; i++) {\n        h += get_row_height(table, i);\n    }\n\n    const lv_style_t * bg_style = lv_obj_get_style(table);\n\n    w += bg_style->body.padding.left + bg_style->body.padding.right;\n    h += bg_style->body.padding.top + bg_style->body.padding.bottom;\n\n    lv_obj_set_size(table, w + 1, h + 1);\n    lv_obj_invalidate(table);\n}\n\nstatic lv_coord_t get_row_height(lv_obj_t * table, uint16_t row_id)\n{\n    lv_table_ext_t * ext = lv_obj_get_ext_attr(table);\n    lv_point_t txt_size;\n    lv_coord_t txt_w;\n    const lv_style_t * cell_style;\n\n    uint16_t row_start = row_id * ext->col_cnt;\n    uint16_t cell;\n    uint16_t col;\n    lv_coord_t h_max = lv_font_get_line_height(ext->cell_style[0]->text.font) + ext->cell_style[0]->body.padding.top +\n                       ext->cell_style[0]->body.padding.bottom;\n\n    for(cell = row_start, col = 0; cell < row_start + ext->col_cnt; cell++, col++) {\n        if(ext->cell_data[cell] != NULL) {\n\n            txt_w              = ext->col_w[col];\n            uint16_t col_merge = 0;\n            for(col_merge = 0; col_merge + col < ext->col_cnt - 1; col_merge++) {\n\n                if(ext->cell_data[cell + col_merge] != NULL) {\n                    lv_table_cell_format_t format;\n                    format.format_byte = ext->cell_data[cell + col_merge][0];\n                    if(format.s.right_merge)\n                        txt_w += ext->col_w[col + col_merge + 1];\n                    else\n                        break;\n                } else {\n                    break;\n                }\n            }\n\n            lv_table_cell_format_t format;\n            format.format_byte = ext->cell_data[cell][0];\n            cell_style         = ext->cell_style[format.s.type];\n\n            /*With text crop assume 1 line*/\n            if(format.s.crop) {\n                h_max = LV_MATH_MAX(lv_font_get_line_height(cell_style->text.font) + cell_style->body.padding.top +\n                                        cell_style->body.padding.bottom,\n                                    h_max);\n            }\n            /*Without text crop calculate the height of the text in the cell*/\n            else {\n                txt_w -= cell_style->body.padding.left + cell_style->body.padding.right;\n\n                lv_txt_get_size(&txt_size, ext->cell_data[cell] + 1, cell_style->text.font,\n                                cell_style->text.letter_space, cell_style->text.line_space, txt_w, LV_TXT_FLAG_NONE);\n\n                h_max = LV_MATH_MAX(txt_size.y + cell_style->body.padding.top + cell_style->body.padding.bottom, h_max);\n                cell += col_merge;\n                col += col_merge;\n            }\n        }\n    }\n\n    return h_max;\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_tabview.c",
    "content": "/**\n * @file lv_tab.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_tabview.h\"\n#if LV_USE_TABVIEW != 0\n\n#include \"libs/lvgl/lv_objx/lv_btnm.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_misc/lv_anim.h\"\n#include \"libs/lvgl/lv_core/lv_disp.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#if LV_USE_ANIMATION\n#ifndef LV_TABVIEW_DEF_ANIM_TIME\n#define LV_TABVIEW_DEF_ANIM_TIME 300 /*Animation time of focusing to the a list element [ms] (0: no animation)  */\n#endif\n#else\n#undef LV_TABVIEW_DEF_ANIM_TIME\n#define LV_TABVIEW_DEF_ANIM_TIME 0 /*No animations*/\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic lv_res_t lv_tabview_signal(lv_obj_t * tabview, lv_signal_t sign, void * param);\nstatic lv_res_t tabpage_signal(lv_obj_t * tab_page, lv_signal_t sign, void * param);\nstatic lv_res_t tabpage_scrl_signal(lv_obj_t * tab_scrl, lv_signal_t sign, void * param);\n\nstatic void tabpage_pressed_handler(lv_obj_t * tabview, lv_obj_t * tabpage);\nstatic void tabpage_pressing_handler(lv_obj_t * tabview, lv_obj_t * tabpage);\nstatic void tabpage_press_lost_handler(lv_obj_t * tabview, lv_obj_t * tabpage);\nstatic void tab_btnm_event_cb(lv_obj_t * tab_btnm, lv_event_t event);\nstatic void tabview_realign(lv_obj_t * tabview);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\nstatic lv_signal_cb_t page_signal;\nstatic lv_signal_cb_t page_scrl_signal;\nstatic const char * tab_def[] = {\"\"};\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a Tab view object\n * @param par pointer to an object, it will be the parent of the new tab\n * @param copy pointer to a tab object, if not NULL then the new object will be copied from it\n * @return pointer to the created tab\n */\nlv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"tab view create started\");\n\n    /*Create the ancestor of tab*/\n    lv_obj_t * new_tabview = lv_obj_create(par, copy);\n    lv_mem_assert(new_tabview);\n    if(new_tabview == NULL) return NULL;\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_tabview);\n\n    /*Allocate the tab type specific extended data*/\n    lv_tabview_ext_t * ext = lv_obj_allocate_ext_attr(new_tabview, sizeof(lv_tabview_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    /*Initialize the allocated 'ext' */\n    ext->drag_hor     = 0;\n    ext->draging      = 0;\n    ext->scroll_ver   = 0;\n    ext->slide_enable = 1;\n    ext->tab_cur      = 0;\n    ext->point_last.x = 0;\n    ext->point_last.y = 0;\n    ext->content      = NULL;\n    ext->indic        = NULL;\n    ext->btns         = NULL;\n    ext->btns_pos     = LV_TABVIEW_BTNS_POS_TOP;\n#if LV_USE_ANIMATION\n    ext->anim_time = LV_TABVIEW_DEF_ANIM_TIME;\n#endif\n    ext->btns_hide = 0;\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_cb(new_tabview, lv_tabview_signal);\n\n    /*Init the new tab tab*/\n    if(copy == NULL) {\n        ext->tab_name_ptr = lv_mem_alloc(sizeof(char *));\n        lv_mem_assert(ext->tab_name_ptr);\n        if(ext->tab_name_ptr == NULL) return NULL;\n        ext->tab_name_ptr[0] = \"\";\n        ext->tab_cnt         = 0;\n\n        /* Set a size which fits into the parent.\n         * Don't use `par` directly because if the tabview is created on a page it is moved to the\n         * scrollable so the parent has changed */\n        lv_obj_set_size(new_tabview, lv_obj_get_width_fit(lv_obj_get_parent(new_tabview)),\n                        lv_obj_get_height_fit(lv_obj_get_parent(new_tabview)));\n\n        ext->content = lv_cont_create(new_tabview, NULL);\n        ext->btns    = lv_btnm_create(new_tabview, NULL);\n        ext->indic   = lv_obj_create(ext->btns, NULL);\n\n        lv_obj_set_height(ext->btns, 3 * LV_DPI / 4);\n        lv_btnm_set_map(ext->btns, tab_def);\n        lv_obj_set_event_cb(ext->btns, tab_btnm_event_cb);\n\n        lv_obj_set_width(ext->indic, LV_DPI);\n        lv_obj_align(ext->indic, ext->btns, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);\n        lv_obj_set_click(ext->indic, false);\n\n        lv_cont_set_fit2(ext->content, LV_FIT_TIGHT, LV_FIT_NONE);\n        lv_cont_set_layout(ext->content, LV_LAYOUT_ROW_T);\n        lv_cont_set_style(ext->content, LV_CONT_STYLE_MAIN, &lv_style_transp_tight);\n        lv_obj_set_height(ext->content, lv_obj_get_height(new_tabview) - lv_obj_get_height(ext->btns));\n        lv_obj_align(ext->content, ext->btns, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_BG, th->style.tabview.bg);\n            lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_INDIC, th->style.tabview.indic);\n            lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_BTN_BG, th->style.tabview.btn.bg);\n            lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_BTN_REL, th->style.tabview.btn.rel);\n            lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_BTN_PR, th->style.tabview.btn.pr);\n            lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_BTN_TGL_REL, th->style.tabview.btn.tgl_rel);\n            lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_BTN_TGL_PR, th->style.tabview.btn.tgl_pr);\n        } else {\n            lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_BG, &lv_style_plain);\n            lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_BTN_BG, &lv_style_transp);\n            lv_tabview_set_style(new_tabview, LV_TABVIEW_STYLE_INDIC, &lv_style_plain_color);\n        }\n    }\n    /*Copy an existing tab view*/\n    else {\n        lv_tabview_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->point_last.x           = 0;\n        ext->point_last.y           = 0;\n        ext->btns                   = lv_btnm_create(new_tabview, copy_ext->btns);\n        ext->indic                  = lv_obj_create(ext->btns, copy_ext->indic);\n        ext->content                = lv_cont_create(new_tabview, copy_ext->content);\n#if LV_USE_ANIMATION\n        ext->anim_time = copy_ext->anim_time;\n#endif\n\n        ext->tab_name_ptr = lv_mem_alloc(sizeof(char *));\n        lv_mem_assert(ext->tab_name_ptr);\n        if(ext->tab_name_ptr == NULL) return NULL;\n        ext->tab_name_ptr[0] = \"\";\n        lv_btnm_set_map(ext->btns, ext->tab_name_ptr);\n\n        uint16_t i;\n        lv_obj_t * new_tab;\n        lv_obj_t * copy_tab;\n        for(i = 0; i < copy_ext->tab_cnt; i++) {\n            new_tab  = lv_tabview_add_tab(new_tabview, copy_ext->tab_name_ptr[i]);\n            copy_tab = lv_tabview_get_tab(copy, i);\n            lv_page_set_style(new_tab, LV_PAGE_STYLE_BG, lv_page_get_style(copy_tab, LV_PAGE_STYLE_BG));\n            lv_page_set_style(new_tab, LV_PAGE_STYLE_SCRL, lv_page_get_style(copy_tab, LV_PAGE_STYLE_SCRL));\n            lv_page_set_style(new_tab, LV_PAGE_STYLE_SB, lv_page_get_style(copy_tab, LV_PAGE_STYLE_SB));\n        }\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_tabview);\n    }\n\n    LV_LOG_INFO(\"tab view created\");\n\n    return new_tabview;\n}\n\n/**\n * Delete all children of the scrl object, without deleting scrl child.\n * @param obj pointer to an object\n */\nvoid lv_tabview_clean(lv_obj_t * obj)\n{\n    lv_obj_t * scrl = lv_page_get_scrl(obj);\n    lv_obj_clean(scrl);\n}\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/**\n * Add a new tab with the given name\n * @param tabview pointer to Tab view object where to ass the new tab\n * @param name the text on the tab button\n * @return pointer to the created page object (lv_page). You can create your content here\n */\nlv_obj_t * lv_tabview_add_tab(lv_obj_t * tabview, const char * name)\n{\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n\n    /*Create the container page*/\n    lv_obj_t * h = lv_page_create(ext->content, NULL);\n    lv_obj_set_size(h, lv_obj_get_width(tabview), lv_obj_get_height(ext->content));\n    lv_page_set_sb_mode(h, LV_SB_MODE_AUTO);\n    lv_page_set_style(h, LV_PAGE_STYLE_BG, &lv_style_transp);\n    lv_page_set_style(h, LV_PAGE_STYLE_SCRL, &lv_style_transp);\n\n    if(page_signal == NULL) page_signal = lv_obj_get_signal_cb(h);\n    if(page_scrl_signal == NULL) page_scrl_signal = lv_obj_get_signal_cb(lv_page_get_scrl(h));\n    lv_obj_set_signal_cb(h, tabpage_signal);\n    lv_obj_set_signal_cb(lv_page_get_scrl(h), tabpage_scrl_signal);\n\n    /*Extend the button matrix map with the new name*/\n    char * name_dm;\n    name_dm = lv_mem_alloc(strlen(name) + 1); /*+1 for the the closing '\\0' */\n    lv_mem_assert(name_dm);\n    if(name_dm == NULL) return NULL;\n    strcpy(name_dm, name);\n\n    ext->tab_cnt++;\n\n    switch(ext->btns_pos) {\n        case LV_TABVIEW_BTNS_POS_TOP:\n        case LV_TABVIEW_BTNS_POS_BOTTOM:\n            ext->tab_name_ptr = lv_mem_realloc(ext->tab_name_ptr, sizeof(char *) * (ext->tab_cnt + 1));\n            break;\n        case LV_TABVIEW_BTNS_POS_LEFT:\n        case LV_TABVIEW_BTNS_POS_RIGHT:\n            ext->tab_name_ptr = lv_mem_realloc(ext->tab_name_ptr, sizeof(char *) * (ext->tab_cnt * 2));\n            break;\n    }\n\n    lv_mem_assert(ext->tab_name_ptr);\n    if(ext->tab_name_ptr == NULL) return NULL;\n\n    /* FIXME: It is not possible yet to switch tab button position from/to top/bottom from/to left/right at runtime.\n     * Method: clean extra \\n when switch from LV_TABVIEW_BTNS_POS_LEFT or LV_TABVIEW_BTNS_POS_RIGHT\n     * to LV_TABVIEW_BTNS_POS_TOP or LV_TABVIEW_BTNS_POS_BOTTOM.\n     */\n    switch(ext->btns_pos) {\n        case LV_TABVIEW_BTNS_POS_TOP:\n        case LV_TABVIEW_BTNS_POS_BOTTOM:\n            ext->tab_name_ptr[ext->tab_cnt - 1] = name_dm;\n            ext->tab_name_ptr[ext->tab_cnt]     = \"\";\n            break;\n        case LV_TABVIEW_BTNS_POS_LEFT:\n        case LV_TABVIEW_BTNS_POS_RIGHT:\n            if(ext->tab_cnt == 1) {\n                ext->tab_name_ptr[0] = name_dm;\n                ext->tab_name_ptr[1] = \"\";\n            } else {\n                ext->tab_name_ptr[ext->tab_cnt * 2 - 3] = \"\\n\";\n                ext->tab_name_ptr[ext->tab_cnt * 2 - 2] = name_dm;\n                ext->tab_name_ptr[ext->tab_cnt * 2 - 1] = \"\";\n            }\n            break;\n    }\n\n    /* The button matrix's map still points to the old `tab_name_ptr` which might be freed by\n     * `lv_mem_realloc`. So make its current map invalid*/\n    lv_btnm_ext_t * btnm_ext = lv_obj_get_ext_attr(ext->btns);\n    btnm_ext->map_p          = NULL;\n\n    lv_btnm_set_map(ext->btns, ext->tab_name_ptr);\n    lv_btnm_set_btn_ctrl(ext->btns, ext->tab_cur, LV_BTNM_CTRL_NO_REPEAT);\n\n    /*Modify the indicator size*/\n    const lv_style_t * style_tabs = lv_obj_get_style(ext->btns);\n    lv_coord_t indic_size;\n    lv_coord_t max_h, btn_h, act_y;\n\n    switch(ext->btns_pos) {\n        case LV_TABVIEW_BTNS_POS_TOP:\n        case LV_TABVIEW_BTNS_POS_BOTTOM:\n            indic_size = (lv_obj_get_width(tabview) - style_tabs->body.padding.inner * (ext->tab_cnt - 1) -\n                          style_tabs->body.padding.left - style_tabs->body.padding.right) /\n                         ext->tab_cnt;\n            lv_obj_set_width(ext->indic, indic_size);\n            lv_obj_set_x(ext->indic, indic_size * ext->tab_cur + style_tabs->body.padding.inner * ext->tab_cur +\n                                         style_tabs->body.padding.left);\n            break;\n        case LV_TABVIEW_BTNS_POS_LEFT:\n        case LV_TABVIEW_BTNS_POS_RIGHT:\n            max_h = lv_obj_get_height(ext->btns) - style_tabs->body.padding.top - style_tabs->body.padding.bottom;\n            btn_h = max_h - ((ext->tab_cnt - 1) * style_tabs->body.padding.inner);\n            btn_h = btn_h / ext->tab_cnt;\n            btn_h--; /*-1 because e.g. height = 100 means 101 pixels (0..100)*/\n            act_y = style_tabs->body.padding.top + ext->tab_cur * (btn_h + style_tabs->body.padding.inner);\n\n            lv_obj_set_height(ext->indic, btn_h);\n            lv_obj_set_y(ext->indic, act_y);\n            break;\n    }\n\n    /*Set the first btn as active*/\n    if(ext->tab_cnt == 1) {\n        ext->tab_cur = 0;\n    }\n\n    tabview_realign(tabview); /*Set the size of the pages, tab buttons and indicator*/\n\n    lv_tabview_set_tab_act(tabview, ext->tab_cur, false);\n\n    return h;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set a new tab\n * @param tabview pointer to Tab view object\n * @param id index of a tab to load\n * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately\n */\nvoid lv_tabview_set_tab_act(lv_obj_t * tabview, uint16_t id, lv_anim_enable_t anim)\n{\n#if LV_USE_ANIMATION == 0\n    anim = LV_ANIM_OFF;\n#endif\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n\n    const lv_style_t * style = lv_obj_get_style(ext->content);\n\n    if(id >= ext->tab_cnt) id = ext->tab_cnt - 1;\n\n    lv_btnm_clear_btn_ctrl(ext->btns, ext->tab_cur, LV_BTNM_CTRL_TGL_STATE);\n\n    ext->tab_cur = id;\n\n    lv_coord_t cont_x;\n\n    switch(ext->btns_pos) {\n        case LV_TABVIEW_BTNS_POS_TOP:\n        case LV_TABVIEW_BTNS_POS_BOTTOM:\n            cont_x = -(lv_obj_get_width(tabview) * id + style->body.padding.inner * id + style->body.padding.left);\n            break;\n        case LV_TABVIEW_BTNS_POS_LEFT:\n            cont_x = -((lv_obj_get_width(tabview) - lv_obj_get_width(ext->btns)) * id + style->body.padding.inner * id +\n                       style->body.padding.left) +\n                     lv_obj_get_width(ext->btns);\n            break;\n        case LV_TABVIEW_BTNS_POS_RIGHT:\n            cont_x = -((lv_obj_get_width(tabview) - lv_obj_get_width(ext->btns)) * id + style->body.padding.inner * id +\n                       style->body.padding.left);\n            break;\n    }\n\n    if(anim == LV_ANIM_OFF || lv_tabview_get_anim_time(tabview) == 0) {\n        lv_obj_set_x(ext->content, cont_x);\n    }\n#if LV_USE_ANIMATION\n    else {\n        lv_anim_t a;\n        a.var            = ext->content;\n        a.start          = lv_obj_get_x(ext->content);\n        a.end            = cont_x;\n        a.exec_cb        = (lv_anim_exec_xcb_t)lv_obj_set_x;\n        a.path_cb        = lv_anim_path_linear;\n        a.ready_cb       = NULL;\n        a.act_time       = 0;\n        a.time           = ext->anim_time;\n        a.playback       = 0;\n        a.playback_pause = 0;\n        a.repeat         = 0;\n        a.repeat_pause   = 0;\n        lv_anim_create(&a);\n    }\n#endif\n\n    /*Move the indicator*/\n    const lv_style_t * tabs_style = lv_obj_get_style(ext->btns);\n    lv_coord_t indic_size;\n    lv_coord_t indic_pos;\n\n    switch(ext->btns_pos) {\n        case LV_TABVIEW_BTNS_POS_TOP:\n        case LV_TABVIEW_BTNS_POS_BOTTOM:\n            indic_size = lv_obj_get_width(ext->indic);\n            indic_pos  = indic_size * id + tabs_style->body.padding.inner * id + tabs_style->body.padding.left;\n            break;\n        case LV_TABVIEW_BTNS_POS_LEFT:\n        case LV_TABVIEW_BTNS_POS_RIGHT:\n            indic_size = lv_obj_get_height(ext->indic);\n            indic_pos  = tabs_style->body.padding.top + id * (indic_size + tabs_style->body.padding.inner);\n            break;\n    }\n\n#if LV_USE_ANIMATION\n    if(anim == LV_ANIM_OFF || ext->anim_time == 0)\n#endif\n    {\n        switch(ext->btns_pos) {\n            case LV_TABVIEW_BTNS_POS_TOP:\n            case LV_TABVIEW_BTNS_POS_BOTTOM: lv_obj_set_x(ext->indic, indic_pos); break;\n            case LV_TABVIEW_BTNS_POS_LEFT:\n            case LV_TABVIEW_BTNS_POS_RIGHT: lv_obj_set_y(ext->indic, indic_pos); break;\n        }\n    }\n#if LV_USE_ANIMATION\n    else {\n        lv_anim_t a;\n        a.var = ext->indic;\n\n        switch(ext->btns_pos) {\n            case LV_TABVIEW_BTNS_POS_TOP:\n            case LV_TABVIEW_BTNS_POS_BOTTOM:\n                a.start   = lv_obj_get_x(ext->indic);\n                a.end     = indic_pos;\n                a.exec_cb = (lv_anim_exec_xcb_t)lv_obj_set_x;\n                break;\n            case LV_TABVIEW_BTNS_POS_LEFT:\n            case LV_TABVIEW_BTNS_POS_RIGHT:\n                a.start   = lv_obj_get_y(ext->indic);\n                a.end     = indic_pos;\n                a.exec_cb = (lv_anim_exec_xcb_t)lv_obj_set_y;\n                break;\n        }\n\n        a.path_cb        = lv_anim_path_linear;\n        a.ready_cb       = NULL;\n        a.act_time       = 0;\n        a.time           = ext->anim_time;\n        a.playback       = 0;\n        a.playback_pause = 0;\n        a.repeat         = 0;\n        a.repeat_pause   = 0;\n        lv_anim_create(&a);\n    }\n#endif\n\n    lv_btnm_set_btn_ctrl(ext->btns, ext->tab_cur, LV_BTNM_CTRL_TGL_STATE);\n}\n\n/**\n * Enable horizontal sliding with touch pad\n * @param tabview pointer to Tab view object\n * @param en true: enable sliding; false: disable sliding\n */\nvoid lv_tabview_set_sliding(lv_obj_t * tabview, bool en)\n{\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n    ext->slide_enable      = en == false ? 0 : 1;\n}\n\n/**\n * Set the animation time of tab view when a new tab is loaded\n * @param tabview pointer to Tab view object\n * @param anim_time_ms time of animation in milliseconds\n */\nvoid lv_tabview_set_anim_time(lv_obj_t * tabview, uint16_t anim_time)\n{\n#if LV_USE_ANIMATION\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n    ext->anim_time         = anim_time;\n#else\n    (void)tabview;\n    (void)anim_time;\n#endif\n}\n\n/**\n * Set the style of a tab view\n * @param tabview pointer to a tan view object\n * @param type which style should be set\n * @param style pointer to the new style\n */\nvoid lv_tabview_set_style(lv_obj_t * tabview, lv_tabview_style_t type, const lv_style_t * style)\n{\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n\n    switch(type) {\n        case LV_TABVIEW_STYLE_BG: lv_obj_set_style(tabview, style); break;\n        case LV_TABVIEW_STYLE_BTN_BG:\n            lv_btnm_set_style(ext->btns, LV_BTNM_STYLE_BG, style);\n            tabview_realign(tabview);\n            break;\n        case LV_TABVIEW_STYLE_BTN_REL:\n            lv_btnm_set_style(ext->btns, LV_BTNM_STYLE_BTN_REL, style);\n            tabview_realign(tabview);\n            break;\n        case LV_TABVIEW_STYLE_BTN_PR: lv_btnm_set_style(ext->btns, LV_BTNM_STYLE_BTN_PR, style); break;\n        case LV_TABVIEW_STYLE_BTN_TGL_REL: lv_btnm_set_style(ext->btns, LV_BTNM_STYLE_BTN_TGL_REL, style); break;\n        case LV_TABVIEW_STYLE_BTN_TGL_PR: lv_btnm_set_style(ext->btns, LV_BTNM_STYLE_BTN_TGL_PR, style); break;\n        case LV_TABVIEW_STYLE_INDIC:\n            lv_obj_set_style(ext->indic, style);\n\n            switch(ext->btns_pos) {\n                case LV_TABVIEW_BTNS_POS_TOP:\n                case LV_TABVIEW_BTNS_POS_BOTTOM: lv_obj_set_height(ext->indic, style->body.padding.inner); break;\n                case LV_TABVIEW_BTNS_POS_LEFT:\n                case LV_TABVIEW_BTNS_POS_RIGHT: lv_obj_set_width(ext->indic, style->body.padding.inner); break;\n            }\n\n            tabview_realign(tabview);\n            break;\n    }\n}\n\n/**\n * Set the position of tab select buttons\n * @param tabview pointer to a tan view object\n * @param btns_pos which button position\n */\nvoid lv_tabview_set_btns_pos(lv_obj_t * tabview, lv_tabview_btns_pos_t btns_pos)\n{\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n\n    ext->btns_pos = btns_pos;\n    tabview_realign(tabview);\n}\n\n/**\n * Set whether tab buttons are hidden\n * @param tabview pointer to a tab view object\n * @param en whether tab buttons are hidden\n */\nvoid lv_tabview_set_btns_hidden(lv_obj_t * tabview, bool en)\n{\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n\n    ext->btns_hide = en;\n    tabview_realign(tabview);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the index of the currently active tab\n * @param tabview pointer to Tab view object\n * @return the active btn index\n */\nuint16_t lv_tabview_get_tab_act(const lv_obj_t * tabview)\n{\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n    return ext->tab_cur;\n}\n\n/**\n * Get the number of tabs\n * @param tabview pointer to Tab view object\n * @return btn count\n */\nuint16_t lv_tabview_get_tab_count(const lv_obj_t * tabview)\n{\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n    return ext->tab_cnt;\n}\n\n/**\n * Get the page (content area) of a tab\n * @param tabview pointer to Tab view object\n * @param id index of the btn (>= 0)\n * @return pointer to page (lv_page) object\n */\nlv_obj_t * lv_tabview_get_tab(const lv_obj_t * tabview, uint16_t id)\n{\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n    uint16_t i             = 0;\n    lv_obj_t * page        = lv_obj_get_child_back(ext->content, NULL);\n\n    while(page != NULL && i != id) {\n        i++;\n        page = lv_obj_get_child_back(ext->content, page);\n    }\n\n    if(i == id) return page;\n\n    return NULL;\n}\n\n/**\n * Get horizontal sliding is enabled or not\n * @param tabview pointer to Tab view object\n * @return true: enable sliding; false: disable sliding\n */\nbool lv_tabview_get_sliding(const lv_obj_t * tabview)\n{\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n    return ext->slide_enable ? true : false;\n}\n\n/**\n * Get the animation time of tab view when a new tab is loaded\n * @param tabview pointer to Tab view object\n * @return time of animation in milliseconds\n */\nuint16_t lv_tabview_get_anim_time(const lv_obj_t * tabview)\n{\n#if LV_USE_ANIMATION\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n    return ext->anim_time;\n#else\n    (void)tabview;\n    return 0;\n#endif\n}\n\n/**\n * Get a style of a tab view\n * @param tabview pointer to a ab view object\n * @param type which style should be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_tabview_get_style(const lv_obj_t * tabview, lv_tabview_style_t type)\n{\n    const lv_style_t * style = NULL;\n    lv_tabview_ext_t * ext   = lv_obj_get_ext_attr(tabview);\n\n    switch(type) {\n        case LV_TABVIEW_STYLE_BG: style = lv_obj_get_style(tabview); break;\n        case LV_TABVIEW_STYLE_BTN_BG: style = lv_btnm_get_style(ext->btns, LV_BTNM_STYLE_BG); break;\n        case LV_TABVIEW_STYLE_BTN_REL: style = lv_btnm_get_style(ext->btns, LV_BTNM_STYLE_BTN_REL); break;\n        case LV_TABVIEW_STYLE_BTN_PR: style = lv_btnm_get_style(ext->btns, LV_BTNM_STYLE_BTN_PR); break;\n        case LV_TABVIEW_STYLE_BTN_TGL_REL: style = lv_btnm_get_style(ext->btns, LV_BTNM_STYLE_BTN_TGL_REL); break;\n        case LV_TABVIEW_STYLE_BTN_TGL_PR: style = lv_btnm_get_style(ext->btns, LV_BTNM_STYLE_BTN_TGL_PR); break;\n        default: style = NULL; break;\n    }\n\n    return style;\n}\n\n/**\n * Get position of tab select buttons\n * @param tabview pointer to a ab view object\n */\nlv_tabview_btns_pos_t lv_tabview_get_btns_pos(const lv_obj_t * tabview)\n{\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n    return ext->btns_pos;\n}\n\n/**\n * Get whether tab buttons are hidden\n * @param tabview pointer to a tab view object\n * @return whether tab buttons are hidden\n */\nbool lv_tabview_get_btns_hidden(const lv_obj_t * tabview)\n{\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n\n    return ext->btns_hide;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Signal function of the Tab view\n * @param tabview pointer to a Tab view object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_tabview_signal(lv_obj_t * tabview, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(tabview, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n    if(sign == LV_SIGNAL_CLEANUP) {\n        uint8_t i;\n        for(i = 0; ext->tab_name_ptr[i][0] != '\\0'; i++) lv_mem_free(ext->tab_name_ptr[i]);\n\n        lv_mem_free(ext->tab_name_ptr);\n        ext->tab_name_ptr = NULL;\n        ext->btns         = NULL; /*These objects were children so they are already invalid*/\n        ext->content      = NULL;\n    } else if(sign == LV_SIGNAL_CORD_CHG) {\n        if(ext->content != NULL && (lv_obj_get_width(tabview) != lv_area_get_width(param) ||\n                                    lv_obj_get_height(tabview) != lv_area_get_height(param))) {\n            tabview_realign(tabview);\n        }\n    } else if(sign == LV_SIGNAL_RELEASED) {\n#if LV_USE_GROUP\n        /*If released by a KEYPAD or ENCODER then really the tab buttons should be released.\n         * So simulate a CLICK on the tab buttons*/\n        lv_indev_t * indev         = lv_indev_get_act();\n        lv_indev_type_t indev_type = lv_indev_get_type(indev);\n        if(indev_type == LV_INDEV_TYPE_KEYPAD ||\n           (indev_type == LV_INDEV_TYPE_ENCODER && lv_group_get_editing(lv_obj_get_group(tabview)))) {\n            lv_event_send(ext->btns, LV_EVENT_CLICKED, lv_event_get_data());\n        }\n#endif\n    } else if(sign == LV_SIGNAL_FOCUS || sign == LV_SIGNAL_DEFOCUS || sign == LV_SIGNAL_CONTROL) {\n        /* The button matrix is not in a group (the tab view is in it) but it should handle the\n         * group signals. So propagate the related signals to the button matrix manually*/\n        if(ext->btns) {\n            ext->btns->signal_cb(ext->btns, sign, param);\n        }\n\n        if(sign == LV_SIGNAL_FOCUS) {\n            lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());\n            /*With ENCODER select the first button only in edit mode*/\n            if(indev_type == LV_INDEV_TYPE_ENCODER) {\n#if LV_USE_GROUP\n                lv_group_t * g = lv_obj_get_group(tabview);\n                if(lv_group_get_editing(g)) {\n                    lv_btnm_ext_t * btnm_ext = lv_obj_get_ext_attr(ext->btns);\n                    btnm_ext->btn_id_pr      = 0;\n                    lv_obj_invalidate(ext->btns);\n                }\n#endif\n            } else {\n                lv_btnm_ext_t * btnm_ext = lv_obj_get_ext_attr(ext->btns);\n                btnm_ext->btn_id_pr      = 0;\n                lv_obj_invalidate(ext->btns);\n            }\n        }\n    } else if(sign == LV_SIGNAL_GET_EDITABLE) {\n        bool * editable = (bool *)param;\n        *editable       = true;\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_tabview\";\n    }\n\n    return res;\n}\n\n/**\n * Signal function of a tab's page\n * @param tab pointer to a tab page object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t tabpage_signal(lv_obj_t * tab_page, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = page_signal(tab_page, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_obj_t * cont    = lv_obj_get_parent(tab_page);\n    lv_obj_t * tabview = lv_obj_get_parent(cont);\n\n    if(lv_tabview_get_sliding(tabview) == false) return res;\n\n    if(sign == LV_SIGNAL_PRESSED) {\n        tabpage_pressed_handler(tabview, tab_page);\n    } else if(sign == LV_SIGNAL_PRESSING) {\n        tabpage_pressing_handler(tabview, tab_page);\n    } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) {\n        tabpage_press_lost_handler(tabview, tab_page);\n    }\n\n    return res;\n}\n/**\n * Signal function of the tab page's scrollable object\n * @param tab_scrl pointer to a tab page's scrollable object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t tabpage_scrl_signal(lv_obj_t * tab_scrl, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = page_scrl_signal(tab_scrl, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_obj_t * tab_page = lv_obj_get_parent(tab_scrl);\n    lv_obj_t * cont     = lv_obj_get_parent(tab_page);\n    lv_obj_t * tabview  = lv_obj_get_parent(cont);\n\n    if(lv_tabview_get_sliding(tabview) == false) return res;\n\n    if(sign == LV_SIGNAL_PRESSED) {\n        tabpage_pressed_handler(tabview, tab_page);\n    } else if(sign == LV_SIGNAL_PRESSING) {\n        tabpage_pressing_handler(tabview, tab_page);\n    } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) {\n        tabpage_press_lost_handler(tabview, tab_page);\n    }\n\n    return res;\n}\n\n/**\n * Called when a tab's page or scrollable object is pressed\n * @param tabview pointer to the btn view object\n * @param tabpage pointer to the page of a btn\n */\nstatic void tabpage_pressed_handler(lv_obj_t * tabview, lv_obj_t * tabpage)\n{\n    (void)tabpage;\n\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n    lv_indev_t * indev     = lv_indev_get_act();\n    lv_indev_get_point(indev, &ext->point_last);\n}\n\n/**\n * Called when a tab's page or scrollable object is being pressed\n * @param tabview pointer to the btn view object\n * @param tabpage pointer to the page of a btn\n */\nstatic void tabpage_pressing_handler(lv_obj_t * tabview, lv_obj_t * tabpage)\n{\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n    lv_indev_t * indev     = lv_indev_get_act();\n    lv_point_t point_act;\n    lv_indev_get_point(indev, &point_act);\n    lv_coord_t x_diff = point_act.x - ext->point_last.x;\n    lv_coord_t y_diff = point_act.y - ext->point_last.y;\n\n    if(!ext->scroll_ver && (x_diff >= LV_INDEV_DEF_DRAG_LIMIT || x_diff <= -LV_INDEV_DEF_DRAG_LIMIT)) {\n        ext->draging = 1;\n        /*Check if the page is on the edge */\n        if((lv_page_on_edge(tabpage, LV_PAGE_EDGE_LEFT) && x_diff > 0) ||\n           (lv_page_on_edge(tabpage, LV_PAGE_EDGE_RIGHT) && x_diff < 0)) {\n            if(ext->drag_hor == 0) {\n                ext->point_last.x = point_act.x;\n                ext->point_last.y = point_act.y;\n            }\n            ext->drag_hor = 1;\n            lv_obj_set_drag(lv_page_get_scrl(tabpage), false);\n\n        } else if(ext->drag_hor == 0) {\n            ext->drag_hor = 0;\n        }\n    } else if(y_diff >= LV_INDEV_DEF_DRAG_LIMIT || y_diff <= -LV_INDEV_DEF_DRAG_LIMIT) {\n        ext->drag_hor   = 0;\n        ext->draging    = 1;\n        ext->scroll_ver = 1;\n    } else\n        ext->draging = 0;\n\n    if(ext->drag_hor) {\n        lv_obj_set_x(ext->content, lv_obj_get_x(ext->content) + point_act.x - ext->point_last.x);\n        ext->point_last.x = point_act.x;\n        ext->point_last.y = point_act.y;\n\n        /*Move the indicator*/\n        const lv_style_t * tabs_style = lv_obj_get_style(ext->btns);\n        lv_coord_t indic_size;\n        lv_coord_t p;\n        lv_coord_t indic_y;\n        const lv_style_t * indic_style;\n\n        switch(ext->btns_pos) {\n            case LV_TABVIEW_BTNS_POS_TOP:\n            case LV_TABVIEW_BTNS_POS_BOTTOM:\n                indic_size  = lv_obj_get_width(ext->indic);\n                indic_style = lv_obj_get_style(ext->indic);\n                p = ((tabpage->coords.x1 - tabview->coords.x1) * (indic_size + tabs_style->body.padding.inner)) /\n                    lv_obj_get_width(tabview);\n\n                lv_obj_set_x(ext->indic, indic_size * ext->tab_cur + tabs_style->body.padding.inner * ext->tab_cur +\n                                             indic_style->body.padding.left - p);\n                break;\n            case LV_TABVIEW_BTNS_POS_LEFT:\n            case LV_TABVIEW_BTNS_POS_RIGHT:\n                indic_size = lv_obj_get_height(ext->indic);\n                indic_y = tabs_style->body.padding.top + ext->tab_cur * (indic_size + tabs_style->body.padding.inner);\n                lv_obj_set_y(ext->indic, indic_y);\n                break;\n        }\n    }\n}\n\n/**\n * Called when a tab's page or scrollable object is released or the press is lost\n * @param tabview pointer to the btn view object\n * @param tabpage pointer to the page of a btn\n */\nstatic void tabpage_press_lost_handler(lv_obj_t * tabview, lv_obj_t * tabpage)\n{\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n    ext->drag_hor          = 0;\n    ext->draging           = 0;\n    ext->scroll_ver        = 0;\n\n    lv_obj_set_drag(lv_page_get_scrl(tabpage), true);\n\n    lv_indev_t * indev = lv_indev_get_act();\n    lv_point_t point_act;\n    lv_indev_get_point(indev, &point_act);\n    lv_point_t vect;\n    lv_indev_get_vect(indev, &vect);\n    lv_coord_t x_predict = 0;\n\n    while(vect.x != 0) {\n        x_predict += vect.x;\n        vect.x = vect.x * (100 - LV_INDEV_DEF_DRAG_THROW) / 100;\n    }\n\n    lv_coord_t page_x1  = tabpage->coords.x1 - tabview->coords.x1 + x_predict;\n    lv_coord_t page_x2  = page_x1 + lv_obj_get_width(tabpage);\n    lv_coord_t treshold = lv_obj_get_width(tabview) / 2;\n\n    uint16_t tab_cur = ext->tab_cur;\n    if(page_x1 > treshold) {\n        if(tab_cur != 0) tab_cur--;\n    } else if(page_x2 < treshold) {\n        if(tab_cur < ext->tab_cnt - 1) tab_cur++;\n    }\n\n    uint32_t id_prev = lv_tabview_get_tab_act(tabview);\n    lv_tabview_set_tab_act(tabview, tab_cur, LV_ANIM_ON);\n    uint32_t id_new = lv_tabview_get_tab_act(tabview);\n\n    lv_res_t res = LV_RES_OK;\n    if(id_prev != id_new) res = lv_event_send(tabview, LV_EVENT_VALUE_CHANGED, &id_new);\n\n    if(res != LV_RES_OK) return;\n}\n\n/**\n * Called when a tab button is clicked\n * @param tab_btnm pointer to the tab's button matrix object\n * @param event type of the event\n */\nstatic void tab_btnm_event_cb(lv_obj_t * tab_btnm, lv_event_t event)\n{\n    if(event != LV_EVENT_CLICKED) return;\n\n    uint16_t btn_id = lv_btnm_get_active_btn(tab_btnm);\n    if(btn_id == LV_BTNM_BTN_NONE) return;\n\n    lv_btnm_clear_btn_ctrl_all(tab_btnm, LV_BTNM_CTRL_TGL_STATE);\n    lv_btnm_set_btn_ctrl(tab_btnm, btn_id, LV_BTNM_CTRL_TGL_STATE);\n\n    lv_obj_t * tabview = lv_obj_get_parent(tab_btnm);\n\n    uint32_t id_prev = lv_tabview_get_tab_act(tabview);\n    lv_tabview_set_tab_act(tabview, btn_id, LV_ANIM_ON);\n    uint32_t id_new = lv_tabview_get_tab_act(tabview);\n\n    lv_res_t res = LV_RES_OK;\n    if(id_prev != id_new) res = lv_event_send(tabview, LV_EVENT_VALUE_CHANGED, &id_new);\n\n    if(res != LV_RES_OK) return;\n}\n\n/**\n * Realign and resize the elements of Tab view\n * @param tabview pointer to a Tab view object\n */\nstatic void tabview_realign(lv_obj_t * tabview)\n{\n    lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);\n\n    lv_obj_set_width(ext->btns, lv_obj_get_width(tabview));\n\n    if(ext->btns_hide) {\n        lv_obj_set_hidden(ext->btns, true);\n        lv_obj_set_hidden(ext->indic, true);\n        lv_obj_set_height(ext->content, lv_obj_get_height(tabview));\n        lv_obj_align(ext->content, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0);\n    } else if(ext->tab_cnt != 0) {\n        lv_obj_set_hidden(ext->btns, false);\n        lv_obj_set_hidden(ext->indic, false);\n\n        const lv_style_t * style_btn_bg  = lv_tabview_get_style(tabview, LV_TABVIEW_STYLE_BTN_BG);\n        const lv_style_t * style_btn_rel = lv_tabview_get_style(tabview, LV_TABVIEW_STYLE_BTN_REL);\n\n        /*Set the indicator width/height*/\n        lv_coord_t indic_size;\n        lv_coord_t max_h;\n\n        switch(ext->btns_pos) {\n            case LV_TABVIEW_BTNS_POS_TOP:\n            case LV_TABVIEW_BTNS_POS_BOTTOM:\n                indic_size = (lv_obj_get_width(tabview) - style_btn_bg->body.padding.inner * (ext->tab_cnt - 1) -\n                              style_btn_bg->body.padding.left - style_btn_bg->body.padding.right) /\n                             ext->tab_cnt;\n                lv_obj_set_width(ext->indic, indic_size);\n                break;\n            case LV_TABVIEW_BTNS_POS_LEFT:\n            case LV_TABVIEW_BTNS_POS_RIGHT:\n                lv_obj_set_height(ext->btns, lv_obj_get_height(tabview));\n\n                max_h =\n                    lv_obj_get_height(ext->btns) - style_btn_bg->body.padding.top - style_btn_bg->body.padding.bottom;\n                indic_size = max_h - ((ext->tab_cnt - 1) * style_btn_bg->body.padding.inner);\n                indic_size = indic_size / ext->tab_cnt;\n                indic_size--; /*-1 because e.g. height = 100 means 101 pixels (0..100)*/\n                lv_obj_set_height(ext->indic, indic_size);\n                break;\n        }\n\n        /*Set the tabs height/width*/\n        lv_coord_t btns_size;\n\n        switch(ext->btns_pos) {\n            case LV_TABVIEW_BTNS_POS_TOP:\n            case LV_TABVIEW_BTNS_POS_BOTTOM:\n                btns_size = lv_font_get_line_height(style_btn_rel->text.font) + style_btn_rel->body.padding.top +\n                            style_btn_rel->body.padding.bottom + style_btn_bg->body.padding.top +\n                            style_btn_bg->body.padding.bottom;\n                lv_obj_set_height(ext->btns, btns_size);\n                break;\n            case LV_TABVIEW_BTNS_POS_LEFT:\n            case LV_TABVIEW_BTNS_POS_RIGHT:\n                btns_size = lv_font_get_glyph_width(style_btn_rel->text.font, 'A', '\\0') +\n                            style_btn_rel->body.padding.left + style_btn_rel->body.padding.right +\n                            style_btn_bg->body.padding.left + style_btn_bg->body.padding.right;\n                lv_obj_set_width(ext->btns, btns_size);\n                break;\n        }\n\n        switch(ext->btns_pos) {\n            case LV_TABVIEW_BTNS_POS_TOP:\n            case LV_TABVIEW_BTNS_POS_BOTTOM:\n                lv_obj_set_height(ext->content, lv_obj_get_height(tabview) - lv_obj_get_height(ext->btns));\n                break;\n            case LV_TABVIEW_BTNS_POS_LEFT:\n            case LV_TABVIEW_BTNS_POS_RIGHT: lv_obj_set_height(ext->content, lv_obj_get_height(tabview)); break;\n        }\n\n        switch(ext->btns_pos) {\n            case LV_TABVIEW_BTNS_POS_TOP:\n                lv_obj_align(ext->btns, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0);\n                lv_obj_align(ext->content, ext->btns, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);\n                lv_obj_align(ext->indic, ext->btns, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);\n\n                lv_cont_set_fit2(ext->content, LV_FIT_TIGHT, LV_FIT_NONE);\n                lv_cont_set_layout(ext->content, LV_LAYOUT_ROW_T);\n                lv_obj_set_height(ext->content, lv_obj_get_height(tabview) - lv_obj_get_height(ext->btns));\n                break;\n            case LV_TABVIEW_BTNS_POS_BOTTOM:\n                lv_obj_align(ext->content, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0);\n                lv_obj_align(ext->btns, ext->content, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);\n                lv_obj_align(ext->indic, ext->btns, LV_ALIGN_IN_TOP_LEFT, 0, 0);\n\n                lv_cont_set_fit2(ext->content, LV_FIT_TIGHT, LV_FIT_NONE);\n                lv_cont_set_layout(ext->content, LV_LAYOUT_ROW_T);\n                lv_obj_set_height(ext->content, lv_obj_get_height(tabview) - lv_obj_get_height(ext->btns));\n                break;\n            case LV_TABVIEW_BTNS_POS_LEFT:\n                lv_obj_align(ext->btns, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0);\n                lv_obj_align(ext->content, tabview, LV_ALIGN_IN_TOP_LEFT, lv_obj_get_width(ext->btns), 0);\n                lv_obj_align(ext->indic, ext->btns, LV_ALIGN_IN_TOP_RIGHT, 0, 0);\n\n                lv_cont_set_fit2(ext->content, LV_FIT_TIGHT, LV_FIT_NONE);\n                lv_cont_set_layout(ext->content, LV_LAYOUT_ROW_T);\n                lv_obj_set_width(ext->content, lv_obj_get_width(tabview) - lv_obj_get_width(ext->btns));\n\n                lv_obj_set_height(ext->btns, lv_obj_get_height(tabview));\n                lv_obj_set_width(ext->indic, style_btn_bg->body.padding.inner);\n                break;\n            case LV_TABVIEW_BTNS_POS_RIGHT:\n                lv_obj_align(ext->btns, NULL, LV_ALIGN_IN_TOP_RIGHT, 0, 0);\n                lv_obj_align(ext->content, tabview, LV_ALIGN_IN_TOP_LEFT, 0, 0);\n                lv_obj_align(ext->indic, ext->btns, LV_ALIGN_IN_TOP_LEFT, 0, 0);\n\n                lv_cont_set_fit2(ext->content, LV_FIT_TIGHT, LV_FIT_NONE);\n                lv_cont_set_layout(ext->content, LV_LAYOUT_ROW_T);\n                lv_obj_set_width(ext->content, lv_obj_get_width(tabview) - lv_obj_get_width(ext->btns));\n\n                lv_obj_set_height(ext->btns, lv_obj_get_height(tabview));\n                lv_obj_set_width(ext->indic, style_btn_bg->body.padding.inner);\n                break;\n        }\n    }\n\n    lv_obj_t * pages = lv_obj_get_child(ext->content, NULL);\n    while(pages != NULL) {\n        if(lv_obj_get_signal_cb(pages) == tabpage_signal) { /*Be sure adjust only the pages (user can other things)*/\n            switch(ext->btns_pos) {\n                case LV_TABVIEW_BTNS_POS_TOP:\n                case LV_TABVIEW_BTNS_POS_BOTTOM:\n                    lv_obj_set_size(pages, lv_obj_get_width(tabview), lv_obj_get_height(ext->content));\n                    break;\n                case LV_TABVIEW_BTNS_POS_LEFT:\n                case LV_TABVIEW_BTNS_POS_RIGHT:\n                    lv_obj_set_size(pages, lv_obj_get_width(tabview) - lv_obj_get_width(ext->btns),\n                                    lv_obj_get_height(ext->content));\n                    break;\n            }\n        }\n        pages = lv_obj_get_child(ext->content, pages);\n    }\n\n    if(!ext->btns_hide) {\n        switch(ext->btns_pos) {\n            case LV_TABVIEW_BTNS_POS_TOP: lv_obj_align(ext->indic, ext->btns, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); break;\n            case LV_TABVIEW_BTNS_POS_BOTTOM: lv_obj_align(ext->indic, ext->btns, LV_ALIGN_IN_TOP_LEFT, 0, 0); break;\n            case LV_TABVIEW_BTNS_POS_LEFT: lv_obj_align(ext->indic, ext->btns, LV_ALIGN_IN_TOP_RIGHT, 0, 0); break;\n            case LV_TABVIEW_BTNS_POS_RIGHT: lv_obj_align(ext->indic, ext->btns, LV_ALIGN_IN_TOP_LEFT, 0, 0); break;\n        }\n    }\n\n    lv_tabview_set_tab_act(tabview, ext->tab_cur, LV_ANIM_OFF);\n}\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_tileview.c",
    "content": "/**\n * @file lv_tileview.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_tileview.h\"\n#if LV_USE_TILEVIEW != 0\n\n#include \"utils/types.h\"\n#include \"libs/lvgl/lv_objx/lv_cont.h\"\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n\n/*********************\n *      DEFINES\n *********************/\n#if LV_USE_ANIMATION\n#ifndef LV_TILEVIEW_DEF_ANIM_TIME\n#define LV_TILEVIEW_DEF_ANIM_TIME 300 /*Animation time loading a tile [ms] (0: no animation)  */\n#endif\n#else\n#undef LV_TILEVIEW_DEF_ANIM_TIME\n#define LV_TILEVIEW_DEF_ANIM_TIME 0 /*No animations*/\n#endif\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic lv_res_t lv_tileview_signal(lv_obj_t * tileview, lv_signal_t sign, void * param);\nstatic lv_res_t lv_tileview_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param);\nstatic void tileview_scrl_event_cb(lv_obj_t * scrl, lv_event_t event);\nstatic void drag_end_handler(lv_obj_t * tileview);\nstatic bool set_valid_drag_dirs(lv_obj_t * tileview);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\nstatic lv_signal_cb_t ancestor_scrl_signal;\nstatic lv_design_cb_t ancestor_design;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a tileview object\n * @param par pointer to an object, it will be the parent of the new tileview\n * @param copy pointer to a tileview object, if not NULL then the new object will be copied from it\n * @return pointer to the created tileview\n */\nlv_obj_t * lv_tileview_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"tileview create started\");\n\n    /*Create the ancestor of tileview*/\n    lv_obj_t * new_tileview = lv_page_create(par, copy);\n    lv_mem_assert(new_tileview);\n    if(new_tileview == NULL) return NULL;\n\n    /*Allocate the tileview type specific extended data*/\n    lv_tileview_ext_t * ext = lv_obj_allocate_ext_attr(new_tileview, sizeof(lv_tileview_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_tileview);\n    if(ancestor_scrl_signal == NULL) ancestor_scrl_signal = lv_obj_get_signal_cb(lv_page_get_scrl(new_tileview));\n    if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_tileview);\n\n        /*Initialize the allocated 'ext' */\n#if LV_USE_ANIMATION\n    ext->anim_time = LV_TILEVIEW_DEF_ANIM_TIME;\n#endif\n    ext->act_id.x      = 0;\n    ext->act_id.y      = 0;\n    ext->valid_pos     = NULL;\n    ext->valid_pos_cnt = 0;\n\n    /*The signal and design functions are not copied so set them here*/\n    lv_obj_set_signal_cb(new_tileview, lv_tileview_signal);\n    lv_obj_set_signal_cb(lv_page_get_scrl(new_tileview), lv_tileview_scrl_signal);\n\n    /*Init the new tileview*/\n    if(copy == NULL) {\n        /* Set a size which fits into the parent.\n         * Don't use `par` directly because if the tileview is created on a page it is moved to the\n         * scrollable so the parent has changed */\n        lv_obj_set_size(new_tileview, lv_obj_get_width_fit(lv_obj_get_parent(new_tileview)),\n                        lv_obj_get_height_fit(lv_obj_get_parent(new_tileview)));\n\n        lv_obj_set_drag_throw(lv_page_get_scrl(new_tileview), false);\n        lv_page_set_scrl_fit(new_tileview, LV_FIT_TIGHT);\n        lv_obj_set_event_cb(ext->page.scrl, tileview_scrl_event_cb);\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_page_set_style(new_tileview, LV_PAGE_STYLE_BG, th->style.tileview.bg);\n            lv_page_set_style(new_tileview, LV_PAGE_STYLE_SCRL, th->style.tileview.scrl);\n            lv_page_set_style(new_tileview, LV_PAGE_STYLE_SB, th->style.tileview.sb);\n        } else {\n            lv_page_set_style(new_tileview, LV_PAGE_STYLE_BG, &lv_style_transp_tight);\n            lv_page_set_style(new_tileview, LV_PAGE_STYLE_SCRL, &lv_style_transp_tight);\n        }\n    }\n    /*Copy an existing tileview*/\n    else {\n        lv_tileview_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        ext->act_id.x                = copy_ext->act_id.x;\n        ext->act_id.y                = copy_ext->act_id.y;\n        ext->valid_pos               = copy_ext->valid_pos;\n        ext->valid_pos_cnt           = copy_ext->valid_pos_cnt;\n#if LV_USE_ANIMATION\n        ext->anim_time = copy_ext->anim_time;\n#endif\n\n        /*Refresh the style with new signal function*/\n        lv_obj_refresh_style(new_tileview);\n    }\n\n    LV_LOG_INFO(\"tileview created\");\n\n    return new_tileview;\n}\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/**\n * Register an object on the tileview. The register object will able to slide the tileview\n * @param tileview pointer to a Tileview object\n * @param element pointer to an object\n */\nvoid lv_tileview_add_element(lv_obj_t * tileview, lv_obj_t * element)\n{\n    /* Let the objects event to propagate to the scrollable part of the tileview.\n     * It is required the handle dargging of the tileview with the element.*/\n    element->parent_event = 1;\n    lv_obj_set_drag_parent(element, true);\n\n    /* When adding a new element the coordinates may shift.\n     * For example y=1 can become y=1 if an element is added to the top.\n     * So be sure the current tile is correctly shown*/\n    lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);\n    lv_tileview_set_tile_act(tileview, ext->act_id.x, ext->act_id.y, false);\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Set the valid position's indices. The scrolling will be possible only to these positions.\n * @param tileview pointer to a Tileview object\n * @param valid_pos array width the indices. E.g. `lv_point_t p[] = {{0,0}, {1,0}, {1,1}`. Only the\n * pointer is saved so can't be a local variable.\n * @param valid_pos_cnt numner of elements in `valid_pos` array\n */\nvoid lv_tileview_set_valid_positions(lv_obj_t * tileview, const lv_point_t * valid_pos, uint16_t valid_pos_cnt)\n{\n    lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);\n    ext->valid_pos          = valid_pos;\n    ext->valid_pos_cnt      = valid_pos_cnt;\n\n    /*If valid pos. is selected do nothing*/\n    uint16_t i;\n    for(i = 0; i < valid_pos_cnt; i++) {\n        if(valid_pos->x == ext->act_id.x && valid_pos->y == ext->act_id.y) {\n            return;\n        }\n    }\n\n    /*Set a valid position if now an invalid is selected*/\n    if(valid_pos_cnt > 0) {\n        lv_tileview_set_tile_act(tileview, valid_pos[0].x, valid_pos[0].y, LV_ANIM_OFF);\n    }\n}\n\n/**\n * Set the tile to be shown\n * @param tileview pointer to a tileview object\n * @param x column id (0, 1, 2...)\n * @param y line id (0, 1, 2...)\n * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately\n */\nvoid lv_tileview_set_tile_act(lv_obj_t * tileview, lv_coord_t x, lv_coord_t y, lv_anim_enable_t anim)\n{\n#if LV_USE_ANIMATION == 0\n    anim = LV_ANIM_OFF;\n#endif\n\n    lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);\n\n    uint32_t tile_id;\n    bool valid = false;\n    for(tile_id = 0; tile_id < ext->valid_pos_cnt; tile_id++) {\n        if(ext->valid_pos[tile_id].x == x && ext->valid_pos[tile_id].y == y) {\n            valid = true;\n        }\n    }\n\n    if(valid == false) return; /*Don't load not valid tiles*/\n\n    ext->act_id.x = x;\n    ext->act_id.y = y;\n\n    lv_coord_t x_coord = -x * lv_obj_get_width(tileview);\n    lv_coord_t y_coord = -y * lv_obj_get_height(tileview);\n    lv_obj_t * scrl    = lv_page_get_scrl(tileview);\n    if(anim) {\n#if LV_USE_ANIMATION\n        lv_coord_t x_act = lv_obj_get_x(scrl);\n        lv_coord_t y_act = lv_obj_get_y(scrl);\n\n        lv_anim_t a;\n        a.var            = scrl;\n        a.exec_cb        = (lv_anim_exec_xcb_t)lv_obj_set_x;\n        a.path_cb        = lv_anim_path_linear;\n        a.ready_cb       = NULL;\n        a.act_time       = 0;\n        a.time           = ext->anim_time;\n        a.playback       = 0;\n        a.playback_pause = 0;\n        a.repeat         = 0;\n        a.repeat_pause   = 0;\n\n        if(x_coord != x_act) {\n            a.start = x_act;\n            a.end   = x_coord;\n            lv_anim_create(&a);\n        }\n\n        if(y_coord != y_act) {\n            a.start   = y_act;\n            a.end     = y_coord;\n            a.exec_cb = (lv_anim_exec_xcb_t)lv_obj_set_y;\n            lv_anim_create(&a);\n        }\n#endif\n    } else {\n        lv_obj_set_pos(scrl, x_coord, y_coord);\n    }\n\n    lv_res_t res = LV_RES_OK;\n    res          = lv_event_send(tileview, LV_EVENT_VALUE_CHANGED, &tile_id);\n    if(res != LV_RES_OK) return; /*Prevent the tile loading*/\n}\n\n/**\n * Set a style of a tileview.\n * @param tileview pointer to tileview object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_tileview_set_style(lv_obj_t * tileview, lv_tileview_style_t type, const lv_style_t * style)\n{\n\n    switch(type) {\n        case LV_TILEVIEW_STYLE_MAIN: lv_obj_set_style(tileview, style); break;\n    }\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/*\n * New object specific \"get\" functions come here\n */\n\n/**\n * Get style of a tileview.\n * @param tileview pointer to tileview object\n * @param type which style should be get\n * @return style pointer to the style\n */\nconst lv_style_t * lv_tileview_get_style(const lv_obj_t * tileview, lv_tileview_style_t type)\n{\n    const lv_style_t * style = NULL;\n    switch(type) {\n        case LV_TILEVIEW_STYLE_MAIN: style = lv_obj_get_style(tileview); break;\n        default: style = NULL;\n    }\n\n    return style;\n}\n\n/*=====================\n * Other functions\n *====================*/\n\n/*\n * New object specific \"other\" functions come here\n */\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Signal function of the tileview\n * @param tileview pointer to a tileview object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_tileview_signal(lv_obj_t * tileview, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(tileview, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    if(sign == LV_SIGNAL_CLEANUP) {\n        /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_tileview\";\n    }\n\n    return res;\n}\n\n/**\n * Signal function of the tileview scrollable\n * @param tileview pointer to the scrollable part of the tileview object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_tileview_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param)\n{\n\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_scrl_signal(scrl, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_obj_t * tileview         = lv_obj_get_parent(scrl);\n    const lv_style_t * style_bg = lv_tileview_get_style(tileview, LV_TILEVIEW_STYLE_MAIN);\n\n    /*Apply constraint on moving of the tileview*/\n    if(sign == LV_SIGNAL_CORD_CHG) {\n        lv_indev_t * indev = lv_indev_get_act();\n        if(indev) {\n            lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);\n\n            /*Set horizontal drag constraint if no vertical constraint an dragged to valid x\n             * direction */\n            if(ext->drag_ver == 0 &&\n               ((ext->drag_right_en && indev->proc.types.pointer.drag_sum.x <= -LV_INDEV_DEF_DRAG_LIMIT) ||\n                (ext->drag_left_en && indev->proc.types.pointer.drag_sum.x >= LV_INDEV_DEF_DRAG_LIMIT))) {\n                ext->drag_hor = 1;\n            }\n            /*Set vertical drag constraint if no horizontal constraint an dragged to valid y\n             * direction */\n            if(ext->drag_hor == 0 &&\n               ((ext->drag_bottom_en && indev->proc.types.pointer.drag_sum.y <= -LV_INDEV_DEF_DRAG_LIMIT) ||\n                (ext->drag_top_en && indev->proc.types.pointer.drag_sum.y >= LV_INDEV_DEF_DRAG_LIMIT))) {\n                ext->drag_ver = 1;\n            }\n\n#if LV_USE_ANIMATION\n            if(ext->drag_hor) {\n                ext->page.edge_flash.top_ip    = 0;\n                ext->page.edge_flash.bottom_ip = 0;\n            }\n\n            if(ext->drag_ver) {\n                ext->page.edge_flash.right_ip = 0;\n                ext->page.edge_flash.left_ip  = 0;\n            }\n#endif\n\n            lv_coord_t x = lv_obj_get_x(scrl);\n            lv_coord_t y = lv_obj_get_y(scrl);\n            lv_coord_t h = lv_obj_get_height(tileview);\n            lv_coord_t w = lv_obj_get_width(tileview);\n            if(ext->drag_top_en == 0) {\n                if(y > -(ext->act_id.y * h) && indev->proc.types.pointer.vect.y > 0 && ext->drag_hor == 0) {\n#if LV_USE_ANIMATION\n                    if(ext->page.edge_flash.enabled && ext->page.edge_flash.left_ip == 0 &&\n                       ext->page.edge_flash.right_ip == 0 && ext->page.edge_flash.top_ip == 0 &&\n                       ext->page.edge_flash.bottom_ip == 0) {\n                        ext->page.edge_flash.top_ip = 1;\n                        lv_page_start_edge_flash(tileview);\n                    }\n#endif\n\n                    lv_obj_set_y(scrl, -ext->act_id.y * h + style_bg->body.padding.top);\n                }\n            }\n            if(ext->drag_bottom_en == 0 && indev->proc.types.pointer.vect.y < 0 && ext->drag_hor == 0) {\n                if(y < -(ext->act_id.y * h)) {\n#if LV_USE_ANIMATION\n                    if(ext->page.edge_flash.enabled && ext->page.edge_flash.left_ip == 0 &&\n                       ext->page.edge_flash.right_ip == 0 && ext->page.edge_flash.top_ip == 0 &&\n                       ext->page.edge_flash.bottom_ip == 0) {\n                        ext->page.edge_flash.bottom_ip = 1;\n                        lv_page_start_edge_flash(tileview);\n                    }\n#endif\n                }\n\n                lv_obj_set_y(scrl, -ext->act_id.y * h + style_bg->body.padding.top);\n            }\n            if(ext->drag_left_en == 0) {\n                if(x > -(ext->act_id.x * w) && indev->proc.types.pointer.vect.x > 0 && ext->drag_ver == 0) {\n#if LV_USE_ANIMATION\n                    if(ext->page.edge_flash.enabled && ext->page.edge_flash.left_ip == 0 &&\n                       ext->page.edge_flash.right_ip == 0 && ext->page.edge_flash.top_ip == 0 &&\n                       ext->page.edge_flash.bottom_ip == 0) {\n                        ext->page.edge_flash.left_ip = 1;\n                        lv_page_start_edge_flash(tileview);\n                    }\n#endif\n\n                    lv_obj_set_x(scrl, -ext->act_id.x * w + style_bg->body.padding.left);\n                }\n            }\n            if(ext->drag_right_en == 0 && indev->proc.types.pointer.vect.x < 0 && ext->drag_ver == 0) {\n                if(x < -(ext->act_id.x * w)) {\n#if LV_USE_ANIMATION\n                    if(ext->page.edge_flash.enabled && ext->page.edge_flash.left_ip == 0 &&\n                       ext->page.edge_flash.right_ip == 0 && ext->page.edge_flash.top_ip == 0 &&\n                       ext->page.edge_flash.bottom_ip == 0) {\n                        ext->page.edge_flash.right_ip = 1;\n                        lv_page_start_edge_flash(tileview);\n                    }\n#endif\n                }\n\n                lv_obj_set_x(scrl, -ext->act_id.x * w + style_bg->body.padding.top);\n            }\n\n            /*Apply the drag constraints*/\n            if(ext->drag_ver == 0)\n                lv_obj_set_y(scrl, -ext->act_id.y * lv_obj_get_height(tileview) + style_bg->body.padding.top);\n            if(ext->drag_hor == 0)\n                lv_obj_set_x(scrl, -ext->act_id.x * lv_obj_get_width(tileview) + style_bg->body.padding.left);\n        }\n    }\n    return res;\n}\n\nstatic void tileview_scrl_event_cb(lv_obj_t * scrl, lv_event_t event)\n{\n    lv_obj_t * tileview = lv_obj_get_parent(scrl);\n\n    /*Initialize some variables on PRESS*/\n    if(event == LV_EVENT_PRESSED) {\n        lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);\n        ext->drag_hor           = 0;\n        ext->drag_ver           = 0;\n        set_valid_drag_dirs(tileview);\n    }\n    /*Animate the tabview to the correct location on RELEASE*/\n    else if(event == LV_EVENT_PRESS_LOST || event == LV_EVENT_RELEASED) {\n        /* If the element was dragged and it moved the tileview finish the drag manually to\n         * let the tileview to finish the move.*/\n        lv_indev_t * indev      = lv_indev_get_act();\n        lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);\n        if(lv_indev_is_dragging(indev) && (ext->drag_hor || ext->drag_ver)) {\n            indev->proc.types.pointer.drag_in_prog = 0;\n        }\n\n        drag_end_handler(tileview);\n    }\n}\n\n/**\n * Called when the user releases an element of the tileview after dragging it.\n * @param tileview pointer to a tileview object\n */\nstatic void drag_end_handler(lv_obj_t * tileview)\n{\n    lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);\n    lv_indev_t * indev      = lv_indev_get_act();\n    lv_point_t point_act;\n    lv_indev_get_point(indev, &point_act);\n    lv_obj_t * scrl = lv_page_get_scrl(tileview);\n    lv_point_t p;\n\n    p.x = -(scrl->coords.x1 - lv_obj_get_width(tileview) / 2);\n    p.y = -(scrl->coords.y1 - lv_obj_get_height(tileview) / 2);\n\n    /*From the drag vector (drag throw) predict the end position*/\n    if(ext->drag_hor) {\n        lv_point_t vect;\n        lv_indev_get_vect(indev, &vect);\n        lv_coord_t predict = 0;\n\n        while(vect.x != 0) {\n            predict += vect.x;\n            vect.x = vect.x * (100 - LV_INDEV_DEF_DRAG_THROW) / 100;\n        }\n\n        p.x -= predict;\n    } else if(ext->drag_ver) {\n        lv_point_t vect;\n        lv_indev_get_vect(indev, &vect);\n        lv_coord_t predict = 0;\n\n        while(vect.y != 0) {\n            predict += vect.y;\n            vect.y = vect.y * (100 - LV_INDEV_DEF_DRAG_THROW) / 100;\n        }\n\n        p.y -= predict;\n    }\n\n    /*Get the index of the tile*/\n    p.x = p.x / lv_obj_get_width(tileview);\n    p.y = p.y / lv_obj_get_height(tileview);\n\n    /*Max +- move*/\n    lv_coord_t x_move = p.x - ext->act_id.x;\n    lv_coord_t y_move = p.y - ext->act_id.y;\n    if(x_move < -1) x_move = -1;\n    if(x_move > 1) x_move = 1;\n    if(y_move < -1) y_move = -1;\n    if(y_move > 1) y_move = 1;\n\n    /*Set the new tile*/\n    lv_tileview_set_tile_act(tileview, ext->act_id.x + x_move, ext->act_id.y + y_move, true);\n}\n\nstatic bool set_valid_drag_dirs(lv_obj_t * tileview)\n{\n\n    lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);\n    if(ext->valid_pos == NULL) return false;\n\n    ext->drag_bottom_en = 0;\n    ext->drag_top_en    = 0;\n    ext->drag_left_en   = 0;\n    ext->drag_right_en  = 0;\n\n    uint16_t i;\n    for(i = 0; i < ext->valid_pos_cnt; i++) {\n        if(ext->valid_pos[i].x == ext->act_id.x && ext->valid_pos[i].y == ext->act_id.y - 1) ext->drag_top_en = 1;\n        if(ext->valid_pos[i].x == ext->act_id.x && ext->valid_pos[i].y == ext->act_id.y + 1) ext->drag_bottom_en = 1;\n        if(ext->valid_pos[i].x == ext->act_id.x - 1 && ext->valid_pos[i].y == ext->act_id.y) ext->drag_left_en = 1;\n        if(ext->valid_pos[i].x == ext->act_id.x + 1 && ext->valid_pos[i].y == ext->act_id.y) ext->drag_right_en = 1;\n    }\n\n    return true;\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_objx/lv_win.c",
    "content": "/**\n * @file lv_win.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_objx/lv_win.h\"\n#if LV_USE_WIN != 0\n\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_core/lv_disp.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\nstatic lv_res_t lv_win_signal(lv_obj_t * win, lv_signal_t sign, void * param);\nstatic void lv_win_realign(lv_obj_t * win);\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_signal_cb_t ancestor_signal;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Create a window objects\n * @param par pointer to an object, it will be the parent of the new window\n * @param copy pointer to a window object, if not NULL then the new object will be copied from it\n * @return pointer to the created window\n */\nlv_obj_t * lv_win_create(lv_obj_t * par, const lv_obj_t * copy)\n{\n    LV_LOG_TRACE(\"window create started\");\n\n    /*Create the ancestor object*/\n    lv_obj_t * new_win = lv_obj_create(par, copy);\n    lv_mem_assert(new_win);\n    if(new_win == NULL) return NULL;\n\n    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_win);\n\n    /*Allocate the object type specific extended data*/\n    lv_win_ext_t * ext = lv_obj_allocate_ext_attr(new_win, sizeof(lv_win_ext_t));\n    lv_mem_assert(ext);\n    if(ext == NULL) return NULL;\n\n    ext->page          = NULL;\n    ext->header        = NULL;\n    ext->title         = NULL;\n    ext->style_btn_rel = &lv_style_btn_rel;\n    ext->style_btn_pr  = &lv_style_btn_pr;\n    ext->btn_size      = (LV_DPI) / 2;\n\n    /*Init the new window object*/\n    if(copy == NULL) {\n        /* Set a size which fits into the parent.\n         * Don't use `par` directly because if the window is created on a page it is moved to the\n         * scrollable so the parent has changed */\n        lv_obj_set_size(new_win, lv_obj_get_width_fit(lv_obj_get_parent(new_win)),\n                        lv_obj_get_height_fit(lv_obj_get_parent(new_win)));\n\n        lv_obj_set_pos(new_win, 0, 0);\n        lv_obj_set_style(new_win, &lv_style_pretty);\n\n        ext->page = lv_page_create(new_win, NULL);\n        lv_obj_set_protect(ext->page, LV_PROTECT_PARENT);\n        lv_page_set_sb_mode(ext->page, LV_SB_MODE_AUTO);\n        lv_page_set_style(ext->page, LV_PAGE_STYLE_BG, &lv_style_transp_fit);\n\n        /*Create a holder for the header*/\n        ext->header = lv_obj_create(new_win, NULL);\n        /*Move back the header because it is automatically moved to the scrollable */\n        lv_obj_set_protect(ext->header, LV_PROTECT_PARENT);\n        lv_obj_set_parent(ext->header, new_win);\n\n        /*Create a title on the header*/\n        ext->title = lv_label_create(ext->header, NULL);\n        lv_label_set_text(ext->title, \"My title\");\n\n        /*Set the default styles*/\n        lv_theme_t * th = lv_theme_get_current();\n        if(th) {\n            lv_win_set_style(new_win, LV_WIN_STYLE_BG, th->style.win.bg);\n            lv_win_set_style(new_win, LV_WIN_STYLE_SB, th->style.win.sb);\n            lv_win_set_style(new_win, LV_WIN_STYLE_HEADER, th->style.win.header);\n            lv_win_set_style(new_win, LV_WIN_STYLE_CONTENT, th->style.win.content);\n            lv_win_set_style(new_win, LV_WIN_STYLE_BTN_REL, th->style.win.btn.rel);\n            lv_win_set_style(new_win, LV_WIN_STYLE_BTN_PR, th->style.win.btn.pr);\n        } else {\n            lv_win_set_style(new_win, LV_WIN_STYLE_BG, &lv_style_plain);\n            lv_win_set_style(new_win, LV_WIN_STYLE_CONTENT, &lv_style_transp);\n            lv_win_set_style(new_win, LV_WIN_STYLE_HEADER, &lv_style_plain_color);\n        }\n\n        lv_obj_set_signal_cb(new_win, lv_win_signal);\n    }\n    /*Copy an existing object*/\n    else {\n        lv_win_ext_t * copy_ext = lv_obj_get_ext_attr(copy);\n        /*Create the objects*/\n        ext->header   = lv_obj_create(new_win, copy_ext->header);\n        ext->title    = lv_label_create(ext->header, copy_ext->title);\n        ext->page     = lv_page_create(new_win, copy_ext->page);\n        ext->btn_size = copy_ext->btn_size;\n\n        /*Copy the control buttons*/\n        lv_obj_t * child;\n        lv_obj_t * cbtn;\n        child = lv_obj_get_child_back(copy_ext->header, NULL);\n        child = lv_obj_get_child_back(copy_ext->header, child); /*Sip the title*/\n        while(child != NULL) {\n            cbtn = lv_btn_create(ext->header, child);\n            lv_img_create(cbtn, lv_obj_get_child(child, NULL));\n            child = lv_obj_get_child_back(copy_ext->header, child);\n        }\n\n        lv_obj_set_signal_cb(new_win, lv_win_signal);\n    }\n\n    /*Refresh the style with new signal function*/\n    lv_obj_refresh_style(new_win);\n\n    lv_win_realign(new_win);\n\n    LV_LOG_INFO(\"window created\");\n\n    return new_win;\n}\n\n/**\n * Delete all children of the scrl object, without deleting scrl child.\n * @param obj pointer to an object\n */\nvoid lv_win_clean(lv_obj_t * obj)\n{\n    lv_obj_t * scrl = lv_page_get_scrl(obj);\n    lv_obj_clean(scrl);\n}\n\n/*======================\n * Add/remove functions\n *=====================*/\n\n/**\n * Add control button to the header of the window\n * @param win pointer to a window object\n * @param img_src an image source ('lv_img_t' variable, path to file or a symbol)\n * @return pointer to the created button object\n */\nlv_obj_t * lv_win_add_btn(lv_obj_t * win, const void * img_src)\n{\n    lv_win_ext_t * ext = lv_obj_get_ext_attr(win);\n\n    lv_obj_t * btn = lv_btn_create(ext->header, NULL);\n    lv_btn_set_style(btn, LV_BTN_STYLE_REL, ext->style_btn_rel);\n    lv_btn_set_style(btn, LV_BTN_STYLE_PR, ext->style_btn_pr);\n    lv_obj_set_size(btn, ext->btn_size, ext->btn_size);\n\n    lv_obj_t * img = lv_img_create(btn, NULL);\n    lv_obj_set_click(img, false);\n    lv_img_set_src(img, img_src);\n\n    lv_win_realign(win);\n\n    return btn;\n}\n\n/*=====================\n * Setter functions\n *====================*/\n\n/**\n * Can be assigned to a window control button to close the window\n * @param btn pointer to the control button on teh widows header\n * @param evet the event type\n */\nvoid lv_win_close_event_cb(lv_obj_t * btn, lv_event_t event)\n{\n    if(event == LV_EVENT_RELEASED) {\n        lv_obj_t * win = lv_win_get_from_btn(btn);\n\n        lv_obj_del(win);\n    }\n}\n\n/**\n * Set the title of a window\n * @param win pointer to a window object\n * @param title string of the new title\n */\nvoid lv_win_set_title(lv_obj_t * win, const char * title)\n{\n    lv_win_ext_t * ext = lv_obj_get_ext_attr(win);\n\n    lv_label_set_text(ext->title, title);\n    lv_win_realign(win);\n}\n\n/**\n * Set the control button size of a window\n * @param win pointer to a window object\n * @param size control button size\n */\nvoid lv_win_set_btn_size(lv_obj_t * win, lv_coord_t size)\n{\n    lv_win_ext_t * ext = lv_obj_get_ext_attr(win);\n    if(ext->btn_size == size) return;\n\n    ext->btn_size = size;\n\n    lv_win_realign(win);\n}\n\n/**\n * Set the layout of the window\n * @param win pointer to a window object\n * @param layout the layout from 'lv_layout_t'\n */\nvoid lv_win_set_layout(lv_obj_t * win, lv_layout_t layout)\n{\n    lv_win_ext_t * ext = lv_obj_get_ext_attr(win);\n    lv_page_set_scrl_layout(ext->page, layout);\n}\n\n/**\n * Set the scroll bar mode of a window\n * @param win pointer to a window object\n * @param sb_mode the new scroll bar mode from  'lv_sb_mode_t'\n */\nvoid lv_win_set_sb_mode(lv_obj_t * win, lv_sb_mode_t sb_mode)\n{\n    lv_win_ext_t * ext = lv_obj_get_ext_attr(win);\n    lv_page_set_sb_mode(ext->page, sb_mode);\n}\n/**\n * Set focus animation duration on `lv_win_focus()`\n * @param win pointer to a window object\n * @param anim_time duration of animation [ms]\n */\nvoid lv_win_set_anim_time(lv_obj_t * win, uint16_t anim_time)\n{\n    lv_page_set_anim_time(lv_win_get_content(win), anim_time);\n}\n\n/**\n * Set a style of a window\n * @param win pointer to a window object\n * @param type which style should be set\n * @param style pointer to a style\n */\nvoid lv_win_set_style(lv_obj_t * win, lv_win_style_t type, const lv_style_t * style)\n{\n    lv_win_ext_t * ext = lv_obj_get_ext_attr(win);\n\n    switch(type) {\n        case LV_WIN_STYLE_BG:\n            lv_obj_set_style(win, style);\n            lv_win_realign(win);\n            break;\n        case LV_WIN_STYLE_CONTENT: lv_page_set_style(ext->page, LV_PAGE_STYLE_SCRL, style); break;\n        case LV_WIN_STYLE_SB: lv_page_set_style(ext->page, LV_PAGE_STYLE_SB, style); break;\n        case LV_WIN_STYLE_HEADER:\n            lv_obj_set_style(ext->header, style);\n            lv_win_realign(win);\n            break;\n        case LV_WIN_STYLE_BTN_REL: ext->style_btn_rel = style; break;\n        case LV_WIN_STYLE_BTN_PR: ext->style_btn_pr = style; break;\n    }\n\n    /*Refresh the existing buttons*/\n    if(type == LV_WIN_STYLE_BTN_REL || type == LV_WIN_STYLE_BTN_PR) {\n        lv_obj_t * btn;\n        btn = lv_obj_get_child_back(ext->header, NULL);\n        btn = lv_obj_get_child_back(ext->header, btn); /*Skip the title*/\n        while(btn != NULL) {\n            if(type == LV_WIN_STYLE_BTN_REL)\n                lv_btn_set_style(btn, LV_BTN_STYLE_REL, style);\n            else\n                lv_btn_set_style(btn, LV_BTN_STYLE_PR, style);\n            btn = lv_obj_get_child_back(ext->header, btn);\n        }\n    }\n}\n\n/**\n * Set drag status of a window. If set to 'true' window can be dragged like on a PC.\n * @param win pointer to a window object\n * @param en whether dragging is enabled\n */\nvoid lv_win_set_drag(lv_obj_t * win, bool en)\n{\n    lv_win_ext_t * ext    = lv_obj_get_ext_attr(win);\n    lv_obj_t * win_header = ext->header;\n    lv_obj_set_drag_parent(win_header, en);\n    lv_obj_set_drag(win, en);\n}\n\n/*=====================\n * Getter functions\n *====================*/\n\n/**\n * Get the title of a window\n * @param win pointer to a window object\n * @return title string of the window\n */\nconst char * lv_win_get_title(const lv_obj_t * win)\n{\n    lv_win_ext_t * ext = lv_obj_get_ext_attr(win);\n    return lv_label_get_text(ext->title);\n}\n\n/**\n * Get the content holder object of window (`lv_page`) to allow additional customization\n * @param win pointer to a window object\n * @return the Page object where the window's content is\n */\nlv_obj_t * lv_win_get_content(const lv_obj_t * win)\n{\n    lv_win_ext_t * ext = lv_obj_get_ext_attr(win);\n    return ext->page;\n}\n\n/**\n * Get the control button size of a window\n * @param win pointer to a window object\n * @return control button size\n */\nlv_coord_t lv_win_get_btn_size(const lv_obj_t * win)\n{\n    lv_win_ext_t * ext = lv_obj_get_ext_attr(win);\n    return ext->btn_size;\n}\n\n/**\n * Get the pointer of a widow from one of  its control button.\n * It is useful in the action of the control buttons where only button is known.\n * @param ctrl_btn pointer to a control button of a window\n * @return pointer to the window of 'ctrl_btn'\n */\nlv_obj_t * lv_win_get_from_btn(const lv_obj_t * ctrl_btn)\n{\n    lv_obj_t * header = lv_obj_get_parent(ctrl_btn);\n    lv_obj_t * win    = lv_obj_get_parent(header);\n\n    return win;\n}\n\n/**\n * Get the layout of a window\n * @param win pointer to a window object\n * @return the layout of the window (from 'lv_layout_t')\n */\nlv_layout_t lv_win_get_layout(lv_obj_t * win)\n{\n    lv_win_ext_t * ext = lv_obj_get_ext_attr(win);\n    return lv_page_get_scrl_layout(ext->page);\n}\n\n/**\n * Get the scroll bar mode of a window\n * @param win pointer to a window object\n * @return the scroll bar mode of the window (from 'lv_sb_mode_t')\n */\nlv_sb_mode_t lv_win_get_sb_mode(lv_obj_t * win)\n{\n    lv_win_ext_t * ext = lv_obj_get_ext_attr(win);\n    return lv_page_get_sb_mode(ext->page);\n}\n\n/**\n * Get focus animation duration\n * @param win pointer to a window object\n * @return duration of animation [ms]\n */\nuint16_t lv_win_get_anim_time(const lv_obj_t * win)\n{\n    return lv_page_get_anim_time(lv_win_get_content(win));\n}\n\n/**\n * Get width of the content area (page scrollable) of the window\n * @param win pointer to a window object\n * @return the width of the content_bg area\n */\nlv_coord_t lv_win_get_width(lv_obj_t * win)\n{\n    lv_win_ext_t * ext            = lv_obj_get_ext_attr(win);\n    lv_obj_t * scrl               = lv_page_get_scrl(ext->page);\n    const lv_style_t * style_scrl = lv_obj_get_style(scrl);\n\n    return lv_obj_get_width(scrl) - style_scrl->body.padding.left - style_scrl->body.padding.right;\n}\n\n/**\n * Get a style of a window\n * @param win pointer to a button object\n * @param type which style window be get\n * @return style pointer to a style\n */\nconst lv_style_t * lv_win_get_style(const lv_obj_t * win, lv_win_style_t type)\n{\n    const lv_style_t * style = NULL;\n    lv_win_ext_t * ext       = lv_obj_get_ext_attr(win);\n\n    switch(type) {\n        case LV_WIN_STYLE_BG: style = lv_obj_get_style(win); break;\n        case LV_WIN_STYLE_CONTENT: style = lv_page_get_style(ext->page, LV_PAGE_STYLE_SCRL); break;\n        case LV_WIN_STYLE_SB: style = lv_page_get_style(ext->page, LV_PAGE_STYLE_SB); break;\n        case LV_WIN_STYLE_HEADER: style = lv_obj_get_style(ext->header); break;\n        case LV_WIN_STYLE_BTN_REL: style = ext->style_btn_rel; break;\n        case LV_WIN_STYLE_BTN_PR: style = ext->style_btn_pr; break;\n        default: style = NULL; break;\n    }\n\n    return style;\n}\n\n/*=====================\n * Other functions\n *====================*/\n\n/**\n * Focus on an object. It ensures that the object will be visible in the window.\n * @param win pointer to a window object\n * @param obj pointer to an object to focus (must be in the window)\n * @param anim_en LV_ANIM_ON focus with an animation; LV_ANIM_OFF focus without animation\n */\nvoid lv_win_focus(lv_obj_t * win, lv_obj_t * obj, lv_anim_enable_t anim_en)\n{\n    lv_win_ext_t * ext = lv_obj_get_ext_attr(win);\n    lv_page_focus(ext->page, obj, anim_en);\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n/**\n * Signal function of the window\n * @param win pointer to a window object\n * @param sign a signal type from lv_signal_t enum\n * @param param pointer to a signal specific variable\n * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted\n */\nstatic lv_res_t lv_win_signal(lv_obj_t * win, lv_signal_t sign, void * param)\n{\n    lv_res_t res;\n\n    /* Include the ancient signal function */\n    res = ancestor_signal(win, sign, param);\n    if(res != LV_RES_OK) return res;\n\n    lv_win_ext_t * ext = lv_obj_get_ext_attr(win);\n    if(sign == LV_SIGNAL_CHILD_CHG) { /*Move children to the page*/\n        lv_obj_t * page = ext->page;\n        if(page != NULL) {\n            lv_obj_t * child;\n            child = lv_obj_get_child(win, NULL);\n            while(child != NULL) {\n                if(lv_obj_is_protected(child, LV_PROTECT_PARENT) == false) {\n                    lv_obj_t * tmp = child;\n                    child          = lv_obj_get_child(win, child); /*Get the next child before move this*/\n                    lv_obj_set_parent(tmp, page);\n                } else {\n                    child = lv_obj_get_child(win, child);\n                }\n            }\n        }\n    } else if(sign == LV_SIGNAL_STYLE_CHG) {\n        lv_win_realign(win);\n    } else if(sign == LV_SIGNAL_CORD_CHG) {\n        /*If the size is changed refresh the window*/\n        if(lv_area_get_width(param) != lv_obj_get_width(win) || lv_area_get_height(param) != lv_obj_get_height(win)) {\n            lv_win_realign(win);\n        }\n    } else if(sign == LV_SIGNAL_CLEANUP) {\n        ext->header = NULL; /*These objects were children so they are already invalid*/\n        ext->page   = NULL;\n        ext->title  = NULL;\n    } else if(sign == LV_SIGNAL_CONTROL) {\n        /*Forward all the control signals to the page*/\n        ext->page->signal_cb(ext->page, sign, param);\n    } else if(sign == LV_SIGNAL_GET_TYPE) {\n        lv_obj_type_t * buf = param;\n        uint8_t i;\n        for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/\n            if(buf->type[i] == NULL) break;\n        }\n        buf->type[i] = \"lv_win\";\n    }\n\n    return res;\n}\n\n/**\n * Realign the building elements of a window\n * @param win pointer to window objectker\n */\nstatic void lv_win_realign(lv_obj_t * win)\n{\n    lv_win_ext_t * ext = lv_obj_get_ext_attr(win);\n\n    if(ext->page == NULL || ext->header == NULL || ext->title == NULL) return;\n\n    const lv_style_t * header_style = lv_win_get_style(win, LV_WIN_STYLE_HEADER);\n    lv_obj_set_size(ext->header, lv_obj_get_width(win),\n                    ext->btn_size + header_style->body.padding.top + header_style->body.padding.bottom);\n\n    bool first_btn = true;\n    lv_obj_t * btn;\n    lv_obj_t * btn_prev = NULL;\n    /*Refresh the size of all control buttons*/\n    btn = lv_obj_get_child_back(ext->header, NULL);\n    btn = lv_obj_get_child_back(ext->header, btn); /*Skip the title*/\n    while(btn != NULL) {\n        lv_obj_set_size(btn, ext->btn_size, ext->btn_size);\n        if(first_btn) {\n            lv_obj_align(btn, ext->header, LV_ALIGN_IN_RIGHT_MID, -header_style->body.padding.right, 0);\n            first_btn = false;\n        } else {\n            lv_obj_align(btn, btn_prev, LV_ALIGN_OUT_LEFT_MID, -header_style->body.padding.inner, 0);\n        }\n        btn_prev = btn;\n        btn      = lv_obj_get_child_back(ext->header, btn);\n    }\n\n    const lv_style_t * style_header = lv_win_get_style(win, LV_WIN_STYLE_HEADER);\n    lv_obj_align(ext->title, NULL, LV_ALIGN_IN_LEFT_MID, style_header->body.padding.left, 0);\n\n    lv_obj_set_pos(ext->header, 0, 0);\n\n    lv_obj_set_size(ext->page, lv_obj_get_width(win), lv_obj_get_height(win) - lv_obj_get_height(ext->header));\n    lv_obj_align(ext->page, ext->header, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);\n}\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_themes/lv_theme.c",
    "content": "/**\n * @file lv_theme.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n#include \"libs/lvgl/lv_core/lv_obj.h\"\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\n\n#if LV_THEME_LIVE_UPDATE == 0\nstatic lv_theme_t * current_theme;\n#else\n/* If live update is used then a big `lv_style_t` array is used to store the real styles of the\n * theme not only pointers. On `lv_theme_set_current` the styles of the theme are copied to this\n * array. The pointers in `current_theme` are initialized to point to the styles in the array. This\n * way the theme styles will always point to the same memory address even after theme is change.\n * (The pointers in the theme points to the styles declared by the theme itself) */\n\n/* Store the styles in this array. */\nstatic lv_style_t th_styles[LV_THEME_STYLE_COUNT];\nstatic bool inited = false;\nstatic lv_theme_t current_theme;\n#endif\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Set a theme for the system.\n * From now, all the created objects will use styles from this theme by default\n * @param th pointer to theme (return value of: 'lv_theme_init_xxx()')\n */\nvoid lv_theme_set_current(lv_theme_t * th)\n{\n#if LV_THEME_LIVE_UPDATE == 0\n    current_theme = th;\n\n#if LV_USE_GROUP\n    /*Copy group style modification callback functions*/\n    memcpy(&current_theme->group, &th->group, sizeof(th->group));\n#endif\n\n    /*Let the object know their style might change*/\n    lv_obj_report_style_mod(NULL);\n\n#else\n    uint32_t style_num = sizeof(th->style) / sizeof(lv_style_t *); /*Number of styles in a theme*/\n\n    if(!inited) {\n        /*Initialize the style pointers `current_theme` to point to the `th_styles` style array */\n        uint16_t i;\n        lv_style_t ** cur_th_style_p = (lv_style_t **)&current_theme.style;\n        for(i = 0; i < style_num; i++) {\n            uintptr_t adr = (uintptr_t)&th_styles[i];\n            memcpy(&cur_th_style_p[i], &adr, sizeof(lv_style_t *));\n        }\n        inited = true;\n    }\n\n    /*Copy the styles pointed by the new theme to the `th_styles` style array*/\n    uint16_t i;\n    lv_style_t ** th_style = (lv_style_t **)&th->style;\n    for(i = 0; i < style_num; i++) {\n        uintptr_t s = (uintptr_t)th_style[i];\n        if(s) memcpy(&th_styles[i], (void *)s, sizeof(lv_style_t));\n    }\n\n#if LV_USE_GROUP\n    /*Copy group style modification callback functions*/\n    memcpy(&current_theme.group, &th->group, sizeof(th->group));\n#endif\n\n    /*Let the object know their style might change*/\n    lv_obj_report_style_mod(NULL);\n\n#endif\n\n#if LV_USE_GROUP\n    lv_group_report_style_mod(NULL);\n#endif\n}\n\n/**\n * Get the current system theme.\n * @return pointer to the current system theme. NULL if not set.\n */\nlv_theme_t * lv_theme_get_current(void)\n{\n#if LV_THEME_LIVE_UPDATE == 0\n    return current_theme;\n#else\n    if(!inited)\n        return NULL;\n    else\n        return &current_theme;\n#endif\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_themes/lv_theme_argon.c",
    "content": "/**\n * @file lv_theme_argon.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n\n#if LV_USE_THEME_ARGON\n\n/*********************\n *      DEFINES\n *********************/\n#define DEF_RADIUS 4\n#define DEF_SHADOW_COLOR GUN_METAL\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_theme_t theme;\nstatic lv_style_t def;\n\n/*Static style definitions*/\nstatic lv_style_t sb;\n\n/*Saved input parameters*/\nstatic uint16_t _hue;\nstatic lv_font_t * _font;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\nstatic void basic_init(void)\n{\n    static lv_style_t bg, panel, scr;\n\n    lv_style_copy(&def, &lv_style_plain); /*Initialize the default style*/\n    def.text.font   = _font;\n    def.body.radius = DEF_RADIUS;\n\n    lv_style_copy(&bg, &def);\n    bg.body.main_color = GRAD_1;\n    bg.body.grad_color = GRAD_2;\n    bg.body.radius     = 0;\n\n    lv_style_copy(&scr, &bg);\n    scr.body.main_color = GRAD_1;\n    scr.body.grad_color = GRAD_2;\n    scr.body.padding.bottom = 0;\n    scr.body.padding.top    = 0;\n    scr.body.padding.left   = 0;\n    scr.body.padding.right  = 0;\n\n    lv_style_copy(&panel, &lv_style_transp);\n    panel.body.radius         = DEF_RADIUS;\n    panel.body.main_color     = GRAD_1;\n    panel.body.grad_color     = GRAD_2;\n    panel.body.border.width   = 0;\n    panel.body.shadow.color   = DEF_SHADOW_COLOR;\n    panel.body.shadow.type    = LV_SHADOW_BOTTOM;\n    panel.body.shadow.width   = 4;\n    panel.body.padding.left   = LV_DPI / 2;\n    panel.body.padding.right  = LV_DPI / 2;\n    panel.body.padding.top    = LV_DPI / 2;\n    panel.body.padding.bottom = LV_DPI / 2;\n    panel.body.padding.inner  = 15;\n    panel.text.color          = LV_COLOR_WHITE;\n    panel.image.color         = lv_color_hex3(0x333);\n\n    lv_style_copy(&sb, &def);\n    sb.body.main_color     = LV_COLOR_BLACK;\n    sb.body.grad_color     = LV_COLOR_BLACK;\n    sb.body.opa            = LV_OPA_40;\n    sb.body.padding.right  = LV_DPI / 25;\n    sb.body.padding.bottom = LV_DPI / 25;\n\n    theme.style.bg    = &bg;\n    theme.style.scr   = &scr;\n    theme.style.panel = &panel;\n}\n\nstatic void cont_init(void)\n{\n#if LV_USE_CONT != 0\n\n    theme.style.cont = theme.style.panel;\n#endif\n}\n\nstatic void btn_init(void)\n{\n#if LV_USE_BTN != 0\n    static lv_style_t rel, pr, tgl_rel, tgl_pr, ina;\n\n    lv_style_copy(&rel, &def);\n    rel.body.main_color     = ONYX;\n    rel.body.grad_color     = GUN_METAL;\n    rel.body.radius         = DEF_RADIUS;\n    rel.body.padding.left   = LV_DPI / 6;\n    rel.body.padding.right  = LV_DPI / 6;\n    rel.body.padding.top    = LV_DPI / 8;\n    rel.body.padding.bottom = LV_DPI / 8;\n    rel.body.padding.inner  = LV_DPI / 10;\n    rel.body.shadow.color   = DEF_SHADOW_COLOR;\n    rel.body.shadow.type    = LV_SHADOW_BOTTOM;\n    rel.body.shadow.width   = 20;\n    rel.text.color          = LV_COLOR_WHITE;\n    rel.image.color         = lv_color_hsv_to_rgb(_hue, 5, 95);\n    rel.text.font           = &lv_font_montserrat_alternate_20;\n    \n    lv_style_copy(&pr, &rel);\n    pr.body.main_color   = GUN_METAL;\n    pr.body.grad_color   = pr.body.main_color;\n    pr.body.shadow.width = 4;\n\n    lv_style_copy(&tgl_rel, &rel);\n    tgl_rel.body.main_color   = lv_color_hsv_to_rgb(_hue, 95, 50);\n    tgl_rel.body.grad_color   = tgl_rel.body.main_color;\n    tgl_rel.body.shadow.width = 4;\n\n    lv_style_copy(&tgl_pr, &tgl_rel);\n    tgl_pr.body.main_color   = lv_color_hsv_to_rgb(_hue, 95, 40);\n    tgl_pr.body.grad_color   = tgl_pr.body.main_color;\n    tgl_pr.body.shadow.width = 2;\n\n    lv_style_copy(&ina, &rel);\n    ina.body.main_color   = lv_color_hex3(0xccc);\n    ina.body.grad_color   = ina.body.main_color;\n    ina.body.shadow.width = 0;\n    ina.text.color        = LV_COLOR_WHITE;\n    ina.image.color       = lv_color_hsv_to_rgb(_hue, 95, 5);\n\n    theme.style.btn.rel     = &rel;\n    theme.style.btn.pr      = &pr;\n    theme.style.btn.tgl_rel = &tgl_rel;\n    theme.style.btn.tgl_pr  = &tgl_pr;\n    theme.style.btn.ina     = &ina;\n#endif\n}\n\nstatic void label_init(void)\n{\n#if LV_USE_LABEL != 0\n    static lv_style_t prim, sec, hint;\n\n    lv_style_copy(&prim, &def);\n    prim.text.font  = _font;\n    prim.text.color = LV_COLOR_WHITE;\n\n    lv_style_copy(&sec, &prim);\n    lv_style_copy(&hint, &prim);\n\n    theme.style.label.prim = &prim;\n    theme.style.label.sec  = &sec;\n    theme.style.label.hint = &hint;\n#endif\n}\n\nstatic void img_init(void)\n{\n#if LV_USE_IMG != 0\n    static lv_style_t img_light, img_dark;\n    lv_style_copy(&img_light, &def);\n    img_light.image.color   = lv_color_hsv_to_rgb(_hue, 15, 85);\n    img_light.image.intense = LV_OPA_80;\n\n    lv_style_copy(&img_dark, &def);\n    img_light.image.color   = lv_color_hsv_to_rgb(_hue, 85, 65);\n    img_light.image.intense = LV_OPA_80;\n\n    theme.style.img.light = &def;\n    theme.style.img.dark  = &def;\n#endif\n}\n\nstatic void line_init(void)\n{\n#if LV_USE_LINE != 0\n    static lv_style_t line_style;\n    lv_style_copy(&line_style, &def);\n    line_style.line.color = LV_COLOR_GRAY;\n    theme.style.line.decor = &line_style;\n#endif\n}\n\nstatic void led_init(void)\n{\n#if LV_USE_LED != 0\n    static lv_style_t led;\n    lv_style_copy(&led, &def);\n    led.body.shadow.width = LV_DPI / 10;\n    led.body.radius       = LV_RADIUS_CIRCLE;\n    led.body.border.width = LV_DPI / 30;\n    led.body.border.opa   = LV_OPA_30;\n    led.body.main_color   = lv_color_hsv_to_rgb(_hue, 100, 100);\n    led.body.grad_color   = lv_color_hsv_to_rgb(_hue, 100, 100);\n    led.body.border.color = lv_color_hsv_to_rgb(_hue, 60, 60);\n    led.body.shadow.color = lv_color_hsv_to_rgb(_hue, 100, 100);\n\n    theme.style.led = &led;\n#endif\n}\n\nstatic void bar_init(void)\n{\n#if LV_USE_BAR\n    static lv_style_t bar_bg, bar_indic;\n\n    lv_style_copy(&bar_bg, &def);\n    bar_bg.body.main_color     = ARGON_DARK_ORANGE;\n    bar_bg.body.grad_color     = ARGON_ORANGE;\n    bar_bg.body.radius         = 3;\n    bar_bg.body.border.width   = 0;\n    bar_bg.body.padding.left   = LV_DPI / 16;\n    bar_bg.body.padding.right  = LV_DPI / 16;\n    bar_bg.body.padding.top    = LV_DPI / 16;\n    bar_bg.body.padding.bottom = LV_DPI / 16;\n\n    lv_style_copy(&bar_indic, &bar_bg);\n    bar_indic.body.main_color     = ARGON_PINK;\n    bar_indic.body.grad_color     = bar_indic.body.main_color;\n    bar_indic.body.padding.left   = 0;\n    bar_indic.body.padding.right  = 0;\n    bar_indic.body.padding.top    = 0;\n    bar_indic.body.padding.bottom = 0;\n\n    theme.style.bar.bg    = &bar_bg;\n    theme.style.bar.indic = &bar_indic;\n#endif\n}\n\nstatic void slider_init(void)\n{\n#if LV_USE_SLIDER != 0\n    static lv_style_t knob;\n\n    lv_style_copy(&knob, &def);\n    knob.body.radius       = LV_RADIUS_CIRCLE;\n    knob.body.border.width = 0;\n    knob.body.main_color   = theme.style.bar.indic->body.main_color;\n    knob.body.grad_color   = knob.body.main_color;\n\n    theme.style.slider.bg    = theme.style.bar.bg;\n    theme.style.slider.indic = theme.style.bar.indic;\n    theme.style.slider.knob  = &knob;\n#endif\n}\n\nstatic void sw_init(void)\n{\n#if LV_USE_SW != 0\n    static lv_style_t sw_bg, sw_indic, sw_knob_off, sw_knob_on;\n    lv_style_copy(&sw_bg, theme.style.slider.bg);\n    sw_bg.body.radius = LV_RADIUS_CIRCLE;\n\n    lv_style_copy(&sw_indic, theme.style.slider.bg);\n    sw_indic.body.radius = LV_RADIUS_CIRCLE;\n\n    lv_style_copy(&sw_knob_on, theme.style.slider.knob);\n    sw_knob_on.body.shadow.width = 3;\n    sw_knob_on.body.shadow.type  = LV_SHADOW_BOTTOM;\n    sw_knob_on.body.shadow.color = DEF_SHADOW_COLOR;\n\n    lv_style_copy(&sw_knob_off, &sw_knob_on);\n    sw_knob_off.body.main_color   = lv_color_hex(0xfafafa);\n    sw_knob_off.body.grad_color   = sw_knob_off.body.main_color;\n    sw_knob_off.body.border.width = 1;\n    sw_knob_off.body.border.color = lv_color_hex3(0x999);\n    sw_knob_off.body.border.opa   = LV_OPA_COVER;\n\n    theme.style.sw.bg       = &sw_bg;\n    theme.style.sw.indic    = &sw_indic;\n    theme.style.sw.knob_off = &sw_knob_off;\n    theme.style.sw.knob_on  = &sw_knob_on;\n#endif\n}\n\nstatic void lmeter_init(void)\n{\n#if LV_USE_LMETER != 0\n    static lv_style_t lmeter;\n    lv_style_copy(&lmeter, &def);\n    lmeter.body.main_color   = lv_color_hsv_to_rgb(_hue, 75, 90);\n    lmeter.body.grad_color   = lmeter.body.main_color;\n    lmeter.body.padding.left = LV_DPI / 10; /*Scale line length*/\n    lmeter.line.color        = lv_color_hex3(0x999);\n    lmeter.line.width        = 2;\n\n    theme.style.lmeter = &lmeter;\n#endif\n}\n\nstatic void gauge_init(void)\n{\n#if LV_USE_GAUGE != 0\n\n    static lv_style_t gauge;\n    lv_style_copy(&gauge, &def);\n    gauge.body.main_color    = lv_color_hsv_to_rgb(_hue, 10, 60);\n    gauge.body.grad_color    = gauge.body.main_color;\n    gauge.body.padding.left  = LV_DPI / 16; /*Scale line length*/\n    gauge.body.padding.inner = LV_DPI / 8;\n    gauge.body.border.color  = lv_color_hex3(0x999);\n    gauge.text.color         = lv_color_hex3(0x333);\n    gauge.line.width         = 3;\n    gauge.line.color         = lv_color_hsv_to_rgb(_hue, 95, 70);\n\n    theme.style.gauge = &gauge;\n#endif\n}\n\nstatic void arc_init(void)\n{\n#if LV_USE_ARC != 0\n\n    static lv_style_t arc;\n    lv_style_copy(&arc, &def);\n    arc.line.width = 10;\n    arc.line.color = lv_color_hsv_to_rgb(_hue, 90, 90);\n\n    /*For prelaoder*/\n    arc.body.border.width   = 10;\n    arc.body.border.color   = lv_color_hsv_to_rgb(_hue, 30, 90);\n    arc.body.padding.left   = 0;\n    arc.body.padding.right  = 0;\n    arc.body.padding.top    = 0;\n    arc.body.padding.bottom = 0;\n\n    theme.style.arc = &arc;\n#endif\n}\n\nstatic void preload_init(void)\n{\n#if LV_USE_PRELOAD != 0\n\n    theme.style.preload = theme.style.arc;\n#endif\n}\n\nstatic void chart_init(void)\n{\n#if LV_USE_CHART\n    theme.style.chart = theme.style.panel;\n#endif\n}\n\nstatic void calendar_init(void)\n{\n#if LV_USE_CALENDAR\n    static lv_style_t ina_days;\n    lv_style_copy(&ina_days, &def);\n    ina_days.text.color = lv_color_hsv_to_rgb(_hue, 0, 70);\n\n    static lv_style_t high_days;\n    lv_style_copy(&high_days, &def);\n    high_days.text.color = lv_color_hsv_to_rgb(_hue, 80, 90);\n\n    static lv_style_t week_box;\n    lv_style_copy(&week_box, &def);\n    week_box.body.main_color     = lv_color_hsv_to_rgb(_hue, 40, 100);\n    week_box.body.grad_color     = lv_color_hsv_to_rgb(_hue, 40, 100);\n    week_box.body.padding.top    = LV_DPI / 20;\n    week_box.body.padding.bottom = LV_DPI / 20;\n    week_box.body.padding.left   = theme.style.panel->body.padding.left;\n    week_box.body.padding.right  = theme.style.panel->body.padding.right;\n    week_box.body.border.color   = theme.style.panel->body.border.color;\n    week_box.body.border.width   = theme.style.panel->body.border.width;\n    week_box.body.border.part    = LV_BORDER_LEFT | LV_BORDER_RIGHT;\n    week_box.body.radius         = 0;\n\n    static lv_style_t today_box;\n    lv_style_copy(&today_box, &def);\n    today_box.body.main_color     = LV_COLOR_WHITE;\n    today_box.body.grad_color     = LV_COLOR_WHITE;\n    today_box.body.padding.top    = LV_DPI / 20;\n    today_box.body.padding.bottom = LV_DPI / 20;\n    today_box.body.radius         = 0;\n\n    theme.style.calendar.bg               = theme.style.panel;\n    theme.style.calendar.header           = &lv_style_transp;\n    theme.style.calendar.inactive_days    = &ina_days;\n    theme.style.calendar.highlighted_days = &high_days;\n    theme.style.calendar.week_box         = &week_box;\n    theme.style.calendar.today_box        = &today_box;\n#endif\n}\n\nstatic void cb_init(void)\n{\n#if LV_USE_CB != 0\n    static lv_style_t rel, pr, tgl_rel, tgl_pr, ina;\n    lv_style_copy(&rel, theme.style.panel);\n    rel.body.shadow.type  = LV_SHADOW_BOTTOM;\n    rel.body.shadow.width = 3;\n\n    lv_style_copy(&pr, &rel);\n    pr.body.main_color   = lv_color_hex3(0xccc);\n    pr.body.grad_color   = pr.body.main_color;\n    pr.body.shadow.width = 0;\n\n    lv_style_copy(&tgl_rel, &rel);\n    tgl_rel.body.main_color   = lv_color_hsv_to_rgb(_hue, 75, 85);\n    tgl_rel.body.grad_color   = tgl_rel.body.main_color;\n    tgl_rel.body.shadow.type  = LV_SHADOW_FULL;\n    tgl_rel.body.shadow.width = 0;\n\n    lv_style_copy(&tgl_pr, &tgl_rel);\n    tgl_pr.body.main_color   = lv_color_hsv_to_rgb(_hue, 75, 65);\n    tgl_pr.body.grad_color   = tgl_pr.body.main_color;\n    tgl_pr.body.shadow.width = 0;\n\n    lv_style_copy(&ina, theme.style.btn.ina);\n\n    theme.style.cb.bg          = &lv_style_transp;\n    theme.style.cb.box.rel     = &rel;\n    theme.style.cb.box.pr      = &pr;\n    theme.style.cb.box.tgl_rel = &tgl_rel;\n    theme.style.cb.box.tgl_pr  = &tgl_pr;\n    theme.style.cb.box.ina     = &ina;\n#endif\n}\n\nstatic void btnm_init(void)\n{\n#if LV_USE_BTNM\n    static lv_style_t bg, rel, pr, tgl_rel, tgl_pr, ina;\n\n    lv_style_copy(&bg, theme.style.panel);\n    bg.body.padding.left   = 0;\n    bg.body.padding.right  = 0;\n    bg.body.padding.top    = 0;\n    bg.body.padding.bottom = 0;\n    bg.body.padding.inner  = 0;\n    bg.text.color          = LV_COLOR_WHITE;\n\n    lv_style_copy(&rel, theme.style.panel);\n    rel.body.border.part  = LV_BORDER_FULL | LV_BORDER_INTERNAL;\n    rel.body.border.width = 1;\n    rel.body.border.color = lv_color_hex3(0xbbb);\n    rel.body.opa          = LV_OPA_TRANSP;\n    rel.body.shadow.width = 0;\n\n    lv_style_copy(&pr, &rel);\n    pr.glass             = 0;\n    pr.body.main_color   = lv_color_hex3(0xddd);\n    pr.body.grad_color   = pr.body.main_color;\n    pr.body.border.width = 0;\n    pr.body.opa          = LV_OPA_COVER;\n\n    lv_style_copy(&tgl_rel, &pr);\n    tgl_rel.body.main_color = lv_color_hsv_to_rgb(_hue, 90, 70);\n    tgl_rel.body.grad_color = tgl_rel.body.main_color;\n    tgl_rel.text.color      = lv_color_hsv_to_rgb(_hue, 5, 95);\n\n    lv_style_copy(&tgl_pr, &tgl_rel);\n    tgl_pr.body.main_color   = lv_color_hsv_to_rgb(_hue, 95, 65);\n    tgl_pr.body.grad_color   = tgl_pr.body.main_color;\n    tgl_pr.body.border.width = 0;\n\n    lv_style_copy(&ina, &pr);\n    ina.body.main_color = lv_color_hex3(0xccc);\n    ina.body.grad_color = ina.body.main_color;\n\n    theme.style.btnm.bg          = &bg;\n    theme.style.btnm.btn.rel     = &rel;\n    theme.style.btnm.btn.pr      = &pr;\n    theme.style.btnm.btn.tgl_rel = &tgl_rel;\n    theme.style.btnm.btn.tgl_pr  = &tgl_pr;\n    theme.style.btnm.btn.ina     = &def;\n#endif\n}\n\nstatic void kb_init(void)\n{\n#if LV_USE_KB\n\n    static lv_style_t rel;\n    lv_style_copy(&rel, &lv_style_transp);\n    rel.text.font = _font;\n\n    theme.style.kb.bg          = theme.style.btnm.bg;\n    theme.style.kb.btn.rel     = &rel;\n    theme.style.kb.btn.pr      = theme.style.btnm.btn.pr;\n    theme.style.kb.btn.tgl_rel = theme.style.btnm.btn.tgl_rel;\n    theme.style.kb.btn.tgl_pr  = theme.style.btnm.btn.tgl_pr;\n    theme.style.kb.btn.ina     = theme.style.btnm.btn.ina;\n#endif\n}\n\nstatic void mbox_init(void)\n{\n#if LV_USE_MBOX\n    static lv_style_t pr, rel;\n\n    lv_style_copy(&rel, &lv_style_transp);\n    rel.glass      = 0;\n    rel.text.font  = _font;\n    rel.text.color = LV_COLOR_WHITE;\n\n    lv_style_copy(&pr, theme.style.btnm.btn.pr);\n    pr.text.color = LV_COLOR_GRAY;\n\n    theme.style.mbox.bg = theme.style.panel;\n    theme.style.mbox.btn.bg  = &lv_style_transp;\n    theme.style.mbox.btn.rel = &rel;\n    theme.style.mbox.btn.pr  = &pr;\n#endif\n}\n\nstatic void page_init(void)\n{\n#if LV_USE_PAGE\n\n    theme.style.page.bg   = &lv_style_transp;\n    theme.style.page.scrl = &lv_style_transp;\n    theme.style.page.sb   = &sb;\n#endif\n}\n\nstatic void ta_init(void)\n{\n#if LV_USE_TA\n    static lv_style_t oneline;\n\n    lv_style_copy(&oneline, &def);\n    oneline.body.opa          = LV_OPA_TRANSP;\n    oneline.body.radius       = 0;\n    oneline.body.border.part  = LV_BORDER_BOTTOM;\n    oneline.body.border.width = 3;\n    oneline.body.border.color = lv_color_hex3(0x333);\n    oneline.body.border.opa   = LV_OPA_COVER;\n    oneline.text.color        = lv_color_hex3(0x333);\n\n    theme.style.ta.area    = theme.style.panel;\n    theme.style.ta.oneline = &oneline;\n    theme.style.ta.cursor  = NULL; /*Let library to calculate the cursor's style*/\n    theme.style.ta.sb      = &sb;\n#endif\n}\n\nstatic void spinbox_init(void)\n{\n#if LV_USE_SPINBOX\n    theme.style.spinbox.bg     = theme.style.panel;\n    theme.style.spinbox.cursor = theme.style.ta.cursor;\n    theme.style.spinbox.sb     = theme.style.ta.sb;\n#endif\n}\n\nstatic void list_init(void)\n{\n#if LV_USE_LIST != 0\n\n    static lv_style_t list_bg, rel, pr, tgl_rel, tgl_pr, ina;\n\n    lv_style_copy(&list_bg, theme.style.panel);\n    list_bg.body.padding.left   = 0;\n    list_bg.body.padding.right  = 0;\n    list_bg.body.padding.top    = 0;\n    list_bg.body.padding.bottom = 0;\n    list_bg.body.padding.inner  = 0;\n\n    lv_style_copy(&rel, &lv_style_transp);\n    rel.body.padding.left   = LV_DPI / 8;\n    rel.body.padding.right  = LV_DPI / 8;\n    rel.body.padding.top    = LV_DPI / 6;\n    rel.body.padding.bottom = LV_DPI / 6;\n    rel.body.radius         = 10;\n    rel.body.border.color   = lv_color_hex3(0xbbb);\n    rel.body.border.width   = 1;\n    rel.body.border.part    = LV_BORDER_BOTTOM;\n\n    lv_style_copy(&pr, &rel);\n    pr.glass             = 0;\n    pr.body.main_color   = lv_color_hex3(0xddd);\n    pr.body.grad_color   = pr.body.main_color;\n    pr.body.border.width = 0;\n    pr.body.opa          = LV_OPA_COVER;\n    pr.body.radius       = DEF_RADIUS;\n    pr.text.font         = _font;\n\n    lv_style_copy(&tgl_rel, &pr);\n    tgl_rel.body.main_color = lv_color_hsv_to_rgb(_hue, 90, 70);\n    tgl_rel.body.grad_color = tgl_rel.body.main_color;\n    tgl_rel.text.color      = lv_color_hsv_to_rgb(_hue, 5, 95);\n\n    lv_style_copy(&tgl_pr, &tgl_rel);\n    tgl_pr.body.main_color   = lv_color_hsv_to_rgb(_hue, 90, 60);\n    tgl_pr.body.grad_color   = tgl_pr.body.main_color;\n    tgl_pr.body.border.width = 0;\n\n    lv_style_copy(&ina, &pr);\n    ina.body.main_color = lv_color_hex3(0xccc);\n    ina.body.grad_color = ina.body.main_color;\n\n    theme.style.list.sb          = &sb;\n    theme.style.list.bg          = &list_bg;\n    theme.style.list.scrl        = &lv_style_transp_tight;\n    theme.style.list.btn.rel     = &rel;\n    theme.style.list.btn.pr      = &pr;\n    theme.style.list.btn.tgl_rel = &tgl_rel;\n    theme.style.list.btn.tgl_pr  = &tgl_pr;\n    theme.style.list.btn.ina     = &ina;\n#endif\n}\n\nstatic void ddlist_init(void)\n{\n#if LV_USE_DDLIST != 0\n    static lv_style_t bg, sel;\n    lv_style_copy(&bg, theme.style.panel);\n    bg.body.padding.left   = LV_DPI / 6;\n    bg.body.padding.right  = LV_DPI / 6;\n    bg.body.padding.top    = LV_DPI / 6;\n    bg.body.padding.bottom = LV_DPI / 6;\n    bg.text.line_space     = LV_DPI / 8;\n\n    lv_style_copy(&sel, &bg);\n    sel.body.main_color   = lv_color_hsv_to_rgb(_hue, 90, 70);\n    sel.body.grad_color   = sel.body.main_color;\n    sel.body.border.width = 0;\n    sel.body.shadow.width = 0;\n    sel.text.color        = lv_color_hsv_to_rgb(_hue, 5, 95);\n\n    theme.style.ddlist.bg  = &bg;\n    theme.style.ddlist.sel = &sel;\n    theme.style.ddlist.sb  = &sb;\n#endif\n}\n\nstatic void roller_init(void)\n{\n#if LV_USE_ROLLER != 0\n    static lv_style_t roller_bg, roller_sel;\n\n    lv_style_copy(&roller_bg, &lv_style_transp);\n    roller_bg.body.padding.left   = LV_DPI / 6;\n    roller_bg.body.padding.right  = LV_DPI / 6;\n    roller_bg.body.padding.top    = LV_DPI / 6;\n    roller_bg.body.padding.bottom = LV_DPI / 6;\n    roller_bg.text.line_space     = LV_DPI / 8;\n    roller_bg.text.font           = _font;\n    roller_bg.glass               = 0;\n\n    lv_style_copy(&roller_sel, &roller_bg);\n    roller_sel.text.color = lv_color_hsv_to_rgb(_hue, 90, 70);\n\n    theme.style.roller.bg  = &roller_bg;\n    theme.style.roller.sel = &roller_sel;\n#endif\n}\n\nstatic void tabview_init(void)\n{\n#if LV_USE_TABVIEW != 0\n    static lv_style_t indic, btn_bg, rel, pr, tgl_rel, tgl_pr;\n\n    lv_style_copy(&indic, &def);\n    indic.body.main_color    = ARGON_ORANGE;\n    indic.body.grad_color    = indic.body.main_color;\n    indic.body.radius        = 0;\n    indic.body.border.width  = 0;\n    indic.body.padding.inner = LV_DPI / 20;\n\n    lv_style_copy(&btn_bg, &def);\n    btn_bg.body.main_color     = GUN_METAL;\n    btn_bg.body.grad_color     = ONYX;\n    btn_bg.body.radius         = 0;\n    btn_bg.body.border.width   = 1;\n    btn_bg.body.border.color   = ONYX;\n    btn_bg.body.border.part    = LV_BORDER_BOTTOM;\n    btn_bg.body.border.opa     = LV_OPA_COVER;\n    btn_bg.body.shadow.width   = 5;\n    btn_bg.body.shadow.color   = DEF_SHADOW_COLOR;\n    btn_bg.body.shadow.type    = LV_SHADOW_BOTTOM;\n    btn_bg.body.padding.inner  = 0;\n    btn_bg.body.padding.left   = 0;\n    btn_bg.body.padding.right  = 0;\n    btn_bg.body.padding.top    = 5;\n    btn_bg.body.padding.bottom = 5;\n    btn_bg.text.color          = ARGON_ORANGE;\n    btn_bg.text.font          = &lv_font_montserrat_alternate_30;\n\n    lv_style_copy(&rel, &lv_style_transp);\n    rel.body.padding.top    = LV_DPI / 8;\n    rel.body.padding.bottom = LV_DPI / 8;\n    rel.text.font           = &lv_font_montserrat_alternate_30;\n\n    lv_style_copy(&pr, &def);\n    pr.body.main_color   = LV_COLOR_BLACK;\n    pr.body.grad_color   = pr.body.main_color;\n    pr.body.border.width = 0;\n    pr.body.opa          = LV_OPA_10;\n    pr.body.radius       = 0;\n    pr.text.color        = LV_COLOR_GRAY;\n    pr.text.font         = rel.text.font;\n\n    lv_style_copy(&tgl_rel, &lv_style_transp);\n    tgl_rel.glass      = 0;\n    tgl_rel.text.font   = &lv_font_montserrat_alternate_30;\n    tgl_rel.text.color = ARGON_ORANGE;\n\n    lv_style_copy(&tgl_pr, &def);\n    tgl_pr.body.main_color   = ARGON_ORANGE;\n    tgl_pr.body.grad_color   = tgl_pr.body.main_color;\n    tgl_pr.body.border.width = 0;\n    tgl_pr.body.opa          = LV_OPA_10;\n    tgl_pr.body.radius       = 0;\n    tgl_pr.text.color        = ARGON_DARK_ORANGE;\n\n    lv_style_copy(theme.style.tabview.bg, &lv_style_transp);\n    \n    theme.style.tabview.indic       = &indic;\n    theme.style.tabview.btn.bg      = &btn_bg;\n    theme.style.tabview.btn.rel     = &rel;\n    theme.style.tabview.btn.pr      = &pr;\n    theme.style.tabview.btn.tgl_rel = &tgl_rel;\n    theme.style.tabview.btn.tgl_pr  = &tgl_pr;\n#endif\n}\n\nstatic void tileview_init(void)\n{\n#if LV_USE_TILEVIEW != 0\n    theme.style.tileview.bg   = &lv_style_transp_tight;\n    theme.style.tileview.scrl = &lv_style_transp_tight;\n    theme.style.tileview.sb   = theme.style.page.sb;\n#endif\n}\n\nstatic void table_init(void)\n{\n#if LV_USE_TABLE != 0\n    static lv_style_t cell;\n    lv_style_copy(&cell, theme.style.panel);\n    cell.body.radius         = 0;\n    cell.body.border.width   = 1;\n    cell.body.padding.left   = LV_DPI / 12;\n    cell.body.padding.right  = LV_DPI / 12;\n    cell.body.padding.top    = LV_DPI / 12;\n    cell.body.padding.bottom = LV_DPI / 12;\n\n    theme.style.table.bg   = &lv_style_transp_tight;\n    theme.style.table.cell = &cell;\n#endif\n}\n\nstatic void win_init(void)\n{\n#if LV_USE_WIN != 0\n    static lv_style_t header, pr;\n\n    lv_style_copy(&header, &def);\n    header.body.main_color     = lv_color_hex3(0xccc);\n    header.body.grad_color     = header.body.main_color;\n    header.body.radius         = 0;\n    header.body.border.width   = 1;\n    header.body.border.color   = lv_color_hex3(0xbbb);\n    header.body.border.part    = LV_BORDER_BOTTOM;\n    header.body.border.opa     = LV_OPA_COVER;\n    header.body.padding.inner  = 0;\n    header.body.padding.left   = 0;\n    header.body.padding.right  = 0;\n    header.body.padding.top    = 0;\n    header.body.padding.bottom = 0;\n    header.text.color          = lv_color_hex3(0x333);\n    header.image.color         = lv_color_hex3(0x333);\n\n    lv_style_copy(&pr, &def);\n    pr.body.main_color   = lv_color_hex3(0xbbb);\n    pr.body.grad_color   = pr.body.main_color;\n    pr.body.border.width = 0;\n    pr.body.opa          = LV_OPA_COVER;\n    pr.body.radius       = 0;\n    pr.text.color        = lv_color_hex3(0x111);\n    pr.image.color       = lv_color_hex3(0x111);\n\n    theme.style.win.bg      = theme.style.panel;\n    theme.style.win.sb      = &sb;\n    theme.style.win.header  = &header;\n    theme.style.win.content = &lv_style_transp;\n    theme.style.win.btn.rel = &lv_style_transp;\n    theme.style.win.btn.pr  = &pr;\n#endif\n}\n\n#if LV_USE_GROUP\n\nstatic void style_mod(lv_group_t * group, lv_style_t * style)\n{\n    (void)group; /*Unused*/\n#if LV_COLOR_DEPTH != 1\n    uint16_t hue2 = (_hue + 60) % 360;\n\n    /*Make the style to be a little bit orange*/\n    style->body.border.opa   = LV_OPA_COVER;\n    style->body.border.color = lv_color_hsv_to_rgb(hue2, 90, 70);\n\n    /*If not empty or has border then emphasis the border*/\n    if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 30;\n\n    style->body.main_color   = lv_color_mix(style->body.main_color, lv_color_hsv_to_rgb(hue2, 90, 70), LV_OPA_70);\n    style->body.grad_color   = lv_color_mix(style->body.grad_color, lv_color_hsv_to_rgb(hue2, 90, 70), LV_OPA_70);\n    style->body.shadow.color = lv_color_mix(style->body.shadow.color, lv_color_hsv_to_rgb(hue2, 90, 70), LV_OPA_60);\n\n    style->text.color = lv_color_mix(style->text.color, lv_color_hsv_to_rgb(hue2, 90, 70), LV_OPA_70);\n#else\n    style->body.border.opa   = LV_OPA_COVER;\n    style->body.border.color = LV_COLOR_BLACK;\n    style->body.border.width = 2;\n#endif\n}\n\nstatic void style_mod_edit(lv_group_t * group, lv_style_t * style)\n{\n    (void)group; /*Unused*/\n#if LV_COLOR_DEPTH != 1\n    uint16_t hue2 = (_hue + 300) % 360;\n\n    /*Make the style to be a little bit orange*/\n    style->body.border.opa   = LV_OPA_COVER;\n    style->body.border.color = LV_COLOR_GREEN;\n\n    /*If not empty or has border then emphasis the border*/\n    if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 30;\n\n\n    style->body.main_color   = lv_color_mix(style->body.main_color, lv_color_hsv_to_rgb(hue2, 90, 70), LV_OPA_70);\n    style->body.grad_color   = lv_color_mix(style->body.grad_color, lv_color_hsv_to_rgb(hue2, 90, 70), LV_OPA_70);\n    style->body.shadow.color = lv_color_mix(style->body.shadow.color, lv_color_hsv_to_rgb(hue2, 90, 70), LV_OPA_60);\n\n    style->text.color = lv_color_mix(style->text.color, lv_color_hsv_to_rgb(hue2, 90, 70), LV_OPA_70);\n#else\n    style->body.border.opa   = LV_OPA_COVER;\n    style->body.border.color = LV_COLOR_BLACK;\n    style->body.border.width = 3;\n#endif\n}\n\n#endif /*LV_USE_GROUP*/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Initialize the argon theme\n * @param hue [0..360] hue value from HSV color space to define the theme's base color\n * @param font pointer to a font (NULL to use the default)\n * @return pointer to the initialized theme\n */\nlv_theme_t * lv_theme_argon_init(uint16_t hue, lv_font_t * font)\n{\n    if(font == NULL) font = LV_FONT_DEFAULT;\n\n    _hue  = hue;\n    _font = font;\n\n    /*For backward compatibility initialize all theme elements with a default style */\n    uint16_t i;\n    lv_style_t ** style_p = (lv_style_t **)&theme.style;\n    for(i = 0; i < LV_THEME_STYLE_COUNT; i++) {\n        *style_p = &def;\n        style_p++;\n    }\n\n    basic_init();\n    cont_init();\n    btn_init();\n    label_init();\n    img_init();\n    line_init();\n    led_init();\n    bar_init();\n    slider_init();\n    sw_init();\n    lmeter_init();\n    gauge_init();\n    chart_init();\n    arc_init();\n    preload_init();\n    calendar_init();\n    cb_init();\n    btnm_init();\n    kb_init();\n    mbox_init();\n    page_init();\n    ta_init();\n    spinbox_init();\n    list_init();\n    ddlist_init();\n    roller_init();\n    tabview_init();\n    tileview_init();\n    table_init();\n    win_init();\n\n#if LV_USE_GROUP\n    theme.group.style_mod_xcb      = style_mod;\n    theme.group.style_mod_edit_xcb = style_mod_edit;\n#endif\n\n    return &theme;\n}\n\n/**\n * Get a pointer to the theme\n * @return pointer to the theme\n */\nlv_theme_t * lv_theme_get_argon(void)\n{\n    return &theme;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_themes/lv_theme_default.c",
    "content": "/**\n * @file lv_theme_default.c\n *\n */\n\n/*********************\n *      INCLUDES\n *********************/\n#include \"libs/lvgl/lv_themes/lv_theme.h\"\n\n#if LV_USE_THEME_DEFAULT\n\n/*********************\n *      DEFINES\n *********************/\n\n/**********************\n *      TYPEDEFS\n **********************/\n\n/**********************\n *  STATIC PROTOTYPES\n **********************/\n\n/**********************\n *  STATIC VARIABLES\n **********************/\nstatic lv_theme_t theme;\nstatic lv_style_t def;\nstatic lv_style_t scr;\n\n/*Static style definitions*/\nstatic lv_style_t sb;\nstatic lv_style_t plain_bordered;\nstatic lv_style_t label_prim;\nstatic lv_style_t label_sec;\nstatic lv_style_t label_hint;\n\n/*Saved input parameters*/\nstatic uint16_t _hue;\nstatic lv_font_t * _font;\n\n/**********************\n *      MACROS\n **********************/\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\nstatic void basic_init(void)\n{\n    lv_style_copy(&def, &lv_style_pretty); /*Initialize the default style*/\n\n    lv_style_copy(&scr, &def);\n    scr.body.padding.bottom = 0;\n    scr.body.padding.top    = 0;\n    scr.body.padding.left   = 0;\n    scr.body.padding.right  = 0;\n\n    lv_style_copy(&sb, &lv_style_pretty_color);\n    sb.body.grad_color     = sb.body.main_color;\n    sb.body.padding.right  = sb.body.padding.right / 2; /*Make closer to the edges*/\n    sb.body.padding.bottom = sb.body.padding.bottom / 2;\n\n    lv_style_copy(&plain_bordered, &lv_style_plain);\n    plain_bordered.body.border.width = 2;\n    plain_bordered.body.border.color = lv_color_hex3(0xbbb);\n\n    theme.style.bg    = &lv_style_plain;\n    theme.style.scr   = &scr;\n    theme.style.panel = &lv_style_pretty;\n}\n\nstatic void btn_init(void)\n{\n#if LV_USE_BTN != 0\n    theme.style.btn.rel     = &lv_style_btn_rel;\n    theme.style.btn.pr      = &lv_style_btn_pr;\n    theme.style.btn.tgl_rel = &lv_style_btn_tgl_rel;\n    theme.style.btn.tgl_pr  = &lv_style_btn_tgl_pr;\n    theme.style.btn.ina     = &lv_style_btn_ina;\n#endif\n}\n\nstatic void label_init(void)\n{\n#if LV_USE_LABEL != 0\n\n    lv_style_copy(&label_prim, &lv_style_plain);\n    lv_style_copy(&label_sec, &lv_style_plain);\n    lv_style_copy(&label_hint, &lv_style_plain);\n\n    label_prim.text.color = lv_color_hex3(0x111);\n    label_sec.text.color  = lv_color_hex3(0x888);\n    label_hint.text.color = lv_color_hex3(0xaaa);\n\n    theme.style.label.prim = &label_prim;\n    theme.style.label.sec  = &label_sec;\n    theme.style.label.hint = &label_hint;\n#endif\n}\n\nstatic void img_init(void)\n{\n#if LV_USE_IMG != 0\n\n    theme.style.img.light = &def;\n    theme.style.img.dark  = &def;\n#endif\n}\n\nstatic void line_init(void)\n{\n#if LV_USE_LINE != 0\n\n    theme.style.line.decor = &def;\n#endif\n}\n\nstatic void led_init(void)\n{\n#if LV_USE_LED != 0\n    static lv_style_t led;\n\n    lv_style_copy(&led, &lv_style_pretty_color);\n    led.body.shadow.width = LV_DPI / 10;\n    led.body.radius       = LV_RADIUS_CIRCLE;\n    led.body.border.width = LV_DPI / 30;\n    led.body.border.opa   = LV_OPA_30;\n    led.body.shadow.color = led.body.main_color;\n\n    theme.style.led = &led;\n#endif\n}\n\nstatic void bar_init(void)\n{\n#if LV_USE_BAR\n\n    theme.style.bar.bg    = &lv_style_pretty;\n    theme.style.bar.indic = &lv_style_pretty_color;\n#endif\n}\n\nstatic void slider_init(void)\n{\n#if LV_USE_SLIDER != 0\n\tstatic lv_style_t slider_bg;\n    lv_style_copy(&slider_bg, &lv_style_pretty);\n    slider_bg.body.padding.left   = LV_DPI / 20;\n    slider_bg.body.padding.right  = LV_DPI / 20;\n    slider_bg.body.padding.top    = LV_DPI / 20;\n    slider_bg.body.padding.bottom = LV_DPI / 20;\n\n    theme.style.slider.bg    = &slider_bg;\n    theme.style.slider.indic = &lv_style_pretty_color;\n    theme.style.slider.knob  = &lv_style_pretty;\n#endif\n}\n\nstatic void sw_init(void)\n{\n#if LV_USE_SW != 0\n\tstatic lv_style_t sw_bg;\n    lv_style_copy(&sw_bg, &lv_style_pretty);\n    sw_bg.body.padding.left   = 3;\n    sw_bg.body.padding.right  = 3;\n    sw_bg.body.padding.top    = 3;\n    sw_bg.body.padding.bottom = 3;\n\n    theme.style.sw.bg       = &sw_bg;\n    theme.style.sw.indic    = &lv_style_pretty_color;\n    theme.style.sw.knob_off = &lv_style_pretty;\n    theme.style.sw.knob_on  = &lv_style_pretty;\n#endif\n}\n\nstatic void lmeter_init(void)\n{\n#if LV_USE_LMETER != 0\n\tstatic lv_style_t lmeter;\n    lv_style_copy(&lmeter, &lv_style_pretty_color);\n    lmeter.line.color      = lv_color_hex3(0xddd);\n    lmeter.line.width      = 2;\n    lmeter.body.main_color = lv_color_mix(lmeter.body.main_color, LV_COLOR_WHITE, LV_OPA_50);\n    lmeter.body.grad_color = lv_color_mix(lmeter.body.grad_color, LV_COLOR_BLACK, LV_OPA_50);\n\n    theme.style.lmeter = &lmeter;\n#endif\n}\n\nstatic void gauge_init(void)\n{\n#if LV_USE_GAUGE != 0\n    static lv_style_t gauge;\n    lv_style_copy(&gauge, theme.style.lmeter);\n    gauge.line.color      = theme.style.lmeter->body.grad_color;\n    gauge.line.width      = 2;\n    gauge.body.main_color = lv_color_hex3(0x888);\n    gauge.body.grad_color = theme.style.lmeter->body.main_color;\n    gauge.text.color      = lv_color_hex3(0x888);\n\n    theme.style.gauge = &gauge;\n#endif\n}\n\nstatic void chart_init(void)\n{\n#if LV_USE_CHART\n\n    theme.style.chart = &lv_style_pretty;\n#endif\n}\n\nstatic void cb_init(void)\n{\n#if LV_USE_CB != 0\n\n    theme.style.cb.bg          = &lv_style_transp;\n    theme.style.cb.box.rel     = &lv_style_pretty;\n    theme.style.cb.box.pr      = &lv_style_btn_pr;\n    theme.style.cb.box.tgl_rel = &lv_style_btn_tgl_rel;\n    theme.style.cb.box.tgl_pr  = &lv_style_btn_tgl_pr;\n    theme.style.cb.box.ina     = &lv_style_btn_ina;\n#endif\n}\n\nstatic void btnm_init(void)\n{\n#if LV_USE_BTNM\n\n    theme.style.btnm.bg          = &lv_style_pretty;\n    theme.style.btnm.btn.rel     = &lv_style_btn_rel;\n    theme.style.btnm.btn.pr      = &lv_style_btn_pr;\n    theme.style.btnm.btn.tgl_rel = &lv_style_btn_tgl_rel;\n    theme.style.btnm.btn.tgl_pr  = &lv_style_btn_tgl_pr;\n    theme.style.btnm.btn.ina     = &lv_style_btn_ina;\n#endif\n}\n\nstatic void kb_init(void)\n{\n#if LV_USE_KB\n\n    theme.style.kb.bg          = &lv_style_pretty;\n    theme.style.kb.btn.rel     = &lv_style_btn_rel;\n    theme.style.kb.btn.pr      = &lv_style_btn_pr;\n    theme.style.kb.btn.tgl_rel = &lv_style_btn_tgl_rel;\n    theme.style.kb.btn.tgl_pr  = &lv_style_btn_tgl_pr;\n    theme.style.kb.btn.ina     = &lv_style_btn_ina;\n#endif\n}\n\nstatic void mbox_init(void)\n{\n#if LV_USE_MBOX\n\n    theme.style.mbox.bg      = &lv_style_pretty;\n    theme.style.mbox.btn.bg  = &lv_style_transp;\n    theme.style.mbox.btn.rel = &lv_style_btn_rel;\n    theme.style.mbox.btn.pr  = &lv_style_btn_tgl_pr;\n#endif\n}\n\nstatic void page_init(void)\n{\n#if LV_USE_PAGE\n\n    theme.style.page.bg   = &lv_style_pretty;\n    theme.style.page.scrl = &lv_style_transp_tight;\n    theme.style.page.sb   = &sb;\n#endif\n}\n\nstatic void ta_init(void)\n{\n#if LV_USE_TA\n\n    theme.style.ta.area    = &lv_style_pretty;\n    theme.style.ta.oneline = &lv_style_pretty;\n    theme.style.ta.cursor  = NULL;\n    theme.style.ta.sb      = &sb;\n#endif\n}\n\nstatic void list_init(void)\n{\n#if LV_USE_LIST != 0\n\n    theme.style.list.bg          = &lv_style_pretty;\n    theme.style.list.scrl        = &lv_style_transp_fit;\n    theme.style.list.sb          = &sb;\n    theme.style.list.btn.rel     = &lv_style_btn_rel;\n    theme.style.list.btn.pr      = &lv_style_btn_pr;\n    theme.style.list.btn.tgl_rel = &lv_style_btn_tgl_rel;\n    theme.style.list.btn.tgl_pr  = &lv_style_btn_tgl_pr;\n    theme.style.list.btn.ina     = &lv_style_btn_ina;\n#endif\n}\n\nstatic void ddlist_init(void)\n{\n#if LV_USE_DDLIST != 0\n\n    theme.style.ddlist.bg  = &lv_style_pretty;\n    theme.style.ddlist.sel = &lv_style_plain_color;\n    theme.style.ddlist.sb  = &sb;\n#endif\n}\n\nstatic void roller_init(void)\n{\n#if LV_USE_ROLLER != 0\n\n    theme.style.roller.bg  = &lv_style_pretty;\n    theme.style.roller.sel = &lv_style_plain_color;\n#endif\n}\n\nstatic void tabview_init(void)\n{\n#if LV_USE_TABVIEW != 0\n\n    theme.style.tabview.bg          = &plain_bordered;\n    theme.style.tabview.indic       = &lv_style_plain_color;\n    theme.style.tabview.btn.bg      = &lv_style_transp;\n    theme.style.tabview.btn.rel     = &lv_style_btn_rel;\n    theme.style.tabview.btn.pr      = &lv_style_btn_pr;\n    theme.style.tabview.btn.tgl_rel = &lv_style_btn_tgl_rel;\n    theme.style.tabview.btn.tgl_pr  = &lv_style_btn_tgl_pr;\n#endif\n}\n\nstatic void table_init(void)\n{\n#if LV_USE_TABLE != 0\n    theme.style.table.bg   = &lv_style_transp_tight;\n    theme.style.table.cell = &lv_style_plain;\n#endif\n}\n\nstatic void win_init(void)\n{\n#if LV_USE_WIN != 0\n\n    theme.style.win.bg      = &plain_bordered;\n    theme.style.win.sb      = &sb;\n    theme.style.win.header  = &lv_style_plain_color;\n    theme.style.win.content = &lv_style_transp;\n    theme.style.win.btn.rel = &lv_style_btn_rel;\n    theme.style.win.btn.pr  = &lv_style_btn_pr;\n#endif\n}\n\n#if LV_USE_GROUP\n\nstatic void style_mod(lv_group_t * group, lv_style_t * style)\n{\n    (void)group; /*Unused*/\n#if LV_COLOR_DEPTH != 1\n    /*Make the style to be a little bit orange*/\n    style->body.border.opa   = LV_OPA_COVER;\n    style->body.border.color = LV_COLOR_ORANGE;\n\n    /*If not empty or has border then emphasis the border*/\n    if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20;\n\n    style->body.main_color   = lv_color_mix(style->body.main_color, LV_COLOR_ORANGE, LV_OPA_70);\n    style->body.grad_color   = lv_color_mix(style->body.grad_color, LV_COLOR_ORANGE, LV_OPA_70);\n    style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_ORANGE, LV_OPA_60);\n\n    style->text.color = lv_color_mix(style->text.color, LV_COLOR_ORANGE, LV_OPA_70);\n#else\n    style->body.border.opa   = LV_OPA_COVER;\n    style->body.border.color = LV_COLOR_BLACK;\n    style->body.border.width = 2;\n#endif\n}\n\nstatic void style_mod_edit(lv_group_t * group, lv_style_t * style)\n{\n    (void)group; /*Unused*/\n#if LV_COLOR_DEPTH != 1\n    /*Make the style to be a little bit orange*/\n    style->body.border.opa   = LV_OPA_COVER;\n    style->body.border.color = LV_COLOR_GREEN;\n\n    /*If not empty or has border then emphasis the border*/\n    if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20;\n\n    style->body.main_color   = lv_color_mix(style->body.main_color, LV_COLOR_GREEN, LV_OPA_70);\n    style->body.grad_color   = lv_color_mix(style->body.grad_color, LV_COLOR_GREEN, LV_OPA_70);\n    style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_GREEN, LV_OPA_60);\n\n    style->text.color = lv_color_mix(style->text.color, LV_COLOR_GREEN, LV_OPA_70);\n#else\n    style->body.border.opa   = LV_OPA_COVER;\n    style->body.border.color = LV_COLOR_BLACK;\n    style->body.border.width = 3;\n#endif\n}\n\n#endif /*LV_USE_GROUP*/\n\n/**********************\n *   GLOBAL FUNCTIONS\n **********************/\n\n/**\n * Initialize the default theme\n * @param hue [0..360] hue value from HSV color space to define the theme's base color\n * @param font pointer to a font (NULL to use the default)\n * @return pointer to the initialized theme\n */\nlv_theme_t * lv_theme_default_init(uint16_t hue, lv_font_t * font)\n{\n    if(font == NULL) font = LV_FONT_DEFAULT;\n\n    _hue  = hue;\n    _font = font;\n\n    /*For backward compatibility initialize all theme elements with a default style */\n    uint16_t i;\n    lv_style_t ** style_p = (lv_style_t **)&theme.style;\n    for(i = 0; i < LV_THEME_STYLE_COUNT; i++) {\n        *style_p = &def;\n        style_p++;\n    }\n\n    basic_init();\n    btn_init();\n    label_init();\n    img_init();\n    line_init();\n    led_init();\n    bar_init();\n    slider_init();\n    sw_init();\n    lmeter_init();\n    gauge_init();\n    chart_init();\n    cb_init();\n    btnm_init();\n    kb_init();\n    mbox_init();\n    page_init();\n    ta_init();\n    list_init();\n    ddlist_init();\n    roller_init();\n    tabview_init();\n    table_init();\n    win_init();\n\n#if LV_USE_GROUP\n    theme.group.style_mod_xcb      = style_mod;\n    theme.group.style_mod_edit_xcb = style_mod_edit;\n#endif\n\n    return &theme;\n}\n\n/**\n * Get a pointer to the theme\n * @return pointer to the theme\n */\nlv_theme_t * lv_theme_get_default(void)\n{\n    return &theme;\n}\n\n/**********************\n *   STATIC FUNCTIONS\n **********************/\n\n#endif\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lv_themes/lv_themes.mk",
    "content": "CSRCS += lv_theme.c\nCSRCS += lv_theme_default.c\nCSRCS += lv_theme_argon.c\n\nDEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_themes\nVPATH += :$(LVGL_DIR)/lvgl/src/lv_themes\n\nCFLAGS += \"-I$(LVGL_DIR)/lvgl/src/lv_themes\"\n"
  },
  {
    "path": "argon-nx-gui/src/libs/lvgl/lvgl.mk",
    "content": "include $(LVGL_DIR)/lvgl/src/lv_core/lv_core.mk\ninclude $(LVGL_DIR)/lvgl/src/lv_hal/lv_hal.mk\ninclude $(LVGL_DIR)/lvgl/src/lv_objx/lv_objx.mk\ninclude $(LVGL_DIR)/lvgl/src/lv_font/lv_font.mk\ninclude $(LVGL_DIR)/lvgl/src/lv_misc/lv_misc.mk\ninclude $(LVGL_DIR)/lvgl/src/lv_themes/lv_themes.mk\ninclude $(LVGL_DIR)/lvgl/src/lv_draw/lv_draw.mk\n\n"
  },
  {
    "path": "argon-nx-gui/src/link.ld",
    "content": "ENTRY(_start)\n\nSECTIONS {\n\tPROVIDE(__ipl_start = 0x40003000);\n\t. = __ipl_start;\n\t.text : {\n\t\t*(.text*);\n\t}\n\t.data : {\n\t\t*(.data*);\n\t\t*(.rodata*);\n\t}\n\t. = ALIGN(0x10);\n\t__ipl_end = .;\n\t.bss : {\n\t\t__bss_start = .;\n\t\t*(COMMON)\n\t\t*(.bss*)\n\t\t__bss_end = .;\n\t}\n}\n"
  },
  {
    "path": "argon-nx-gui/src/main.c",
    "content": "/*\n * Copyright (c) 2018 Guillem96\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"gfx/di.h\"\n#include \"gfx/gfx.h\"\n#include \"gfx/lvgl_adapter.h\"\n\n#include \"mem/heap.h\"\n\n#include \"soc/hw_init.h\"\n#include \"soc/bpmp.h\"\n\n#include \"core/argon-resources.h\"\n#include \"core/argon-ctxt.h\"\n#include \"core/launcher.h\"\n\n#include \"menu/gui/gui_menu.h\"\n\n#include \"utils/util.h\"\n#include \"utils/fs_utils.h\"\n#include \"utils/touch.h\"\n#include \"utils/btn.h\"\n\n#include \"power/battery.h\"\n#include \"power/max17050.h\"\n\n#include \"minerva/minerva.h\"\n\n\nextern void pivot_stack(u32 stack_top);\n\nstatic inline void setup_gfx()\n{\n    gfx_init_ctxt((u32 *)FB_ADDRESS, 720, 1280, 720);\n\tgfx_con_init();\n}\n\n\nvoid ipl_main()\n{\n    /* Load needed hw*/\n    bpmp_mmu_enable();\n\n    heap_init(0x90020000);\n\n    /* Init display and gfx module */\n    setup_gfx();\n    \n    /* Initialize ArgonNX context */\n    argon_ctxt_t argon_ctxt;\n    argon_ctxt_init(&argon_ctxt);\n\n    /* Train DRAM */\n    g_gfx_con.mute = 0; /* Silence minerva, comment for debug */\n    minerva(argon_ctxt.mtc_conf);\n    minerva_change_freq(argon_ctxt.mtc_conf, FREQ_1600);\n    g_gfx_con.mute = 0;\n    \n    bpmp_clk_rate_set(BPMP_CLK_SUPER_BOOST);\n\n    /* Cofigure touch input */\n    touch_power_on();\n    \n    /* Mount Sd card and launch payload */\n    if (sd_mount())\n    {\n        bool cancel_auto_chainloading = btn_read() & BTN_VOL_DOWN;\n        bool load_menu = cancel_auto_chainloading || launch_payload(&argon_ctxt, \"argon/payload.bin\");\n        \n        if (load_menu)\n        {\n            argon_resources_init();\n            lvgl_adapter_init(&argon_ctxt);\n            gui_menu_draw(&argon_ctxt);\n            gui_menu_open(&argon_ctxt);\n            gui_menu_destroy(&argon_ctxt);\n        }\n        wait_for_button_and_reboot();\n\n    } else {\n        gfx_printf(\"No sd card found...\\n\");\n    }\n\n    /* If payload launch fails wait for user input to reboot the switch */\n    gfx_printf(\"Press power button to reboot into RCM...\\n\\n\");\n    wait_for_button_and_reboot();\n}"
  },
  {
    "path": "argon-nx-gui/src/mem/heap.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 M4xw\n * Copyright (c) 2018 Guillem96\n * \n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n#include \"mem/heap.h\"\n\nstatic void _heap_create(heap_t *heap, u32 start)\n{\n\theap->start = start;\n\theap->first = NULL;\n}\n\nstatic u32 _heap_alloc(heap_t *heap, u32 size, u32 alignment)\n{\n\thnode_t *node, *new;\n\tint search = 1;\n\n\tsize = ALIGN(size, alignment);\n\n\tif (!heap->first)\n\t{\n\t\tnode = (hnode_t *)heap->start;\n\t\tnode->used = 1;\n\t\tnode->size = size;\n\t\tnode->prev = NULL;\n\t\tnode->next = NULL;\n\t\theap->first = node;\n\n\t\treturn (u32)node + sizeof(hnode_t);\n\t}\n\n\tnode = heap->first;\n\twhile (search)\n\t{\n\t\tif (!node->used && size + sizeof(hnode_t) < node->size)\n\t\t{\n\t\t\tnew = (hnode_t *)((u32)node + sizeof(hnode_t) + size);\n\n\t\t\tnew->size = node->size - sizeof(hnode_t) - size;\n\t\t\tnode->size = size;\n\t\t\tnode->used = 1;\n\t\t\tnew->used = 0;\n\t\t\tnew->next = node->next;\n\t\t\tnew->prev = node;\n\t\t\tnode->next = new;\n\n\t\t\treturn (u32)node + sizeof(hnode_t);\n\t\t}\n\t\tif (node->next)\n\t\t\tnode = node->next;\n\t\telse\n\t\t\tsearch = 0;\n\t}\n\n\tnew = (hnode_t *)((u32)node + sizeof(hnode_t) + node->size);\n\tnew->used = 1;\n\tnew->size = size;\n\tnew->prev = node;\n\tnew->next = NULL;\n\tnode->next = new;\n\n\treturn (u32)new + sizeof(hnode_t);\n}\n\nstatic void _heap_free(heap_t *heap, u32 addr)\n{\n\thnode_t *node = (hnode_t *)(addr - sizeof(hnode_t));\n\tnode->used = 0;\n\tnode = heap->first;\n\twhile (node)\n\t{\n\t\tif (!node->used)\n\t\t{\n\t\t\tif (node->prev && !node->prev->used)\n\t\t\t{\n\t\t\t\tnode->prev->size += node->size + sizeof(hnode_t);\n\t\t\t\tnode->prev->next = node->next;\n\t\t\t\tif (node->next)\n\t\t\t\t\tnode->next->prev = node->prev;\n\t\t\t}\n\t\t}\n\t\tnode = node->next;\n\t}\n}\n\nheap_t _heap;\n\nvoid heap_init(u32 base)\n{\n\t_heap_create(&_heap, base);\n}\n\nvoid *malloc(u32 size)\n{\n\treturn (void *)_heap_alloc(&_heap, size, 0x10);\n}\n\nvoid *memalign(u32 align, u32 size)\n{\n\treturn (void *)_heap_alloc(&_heap, size, align);\n}\n\nvoid *calloc(u32 num, u32 size)\n{\n\tvoid *res = (void *)_heap_alloc(&_heap, num * size, 0x10);\n\tmemset(res, 0, num * size);\n\treturn res;\n}\n\nvoid free(void *buf)\n{\n\tif ((buf != NULL) || ((u32)buf > (_heap.start - 1)))\n\t\t_heap_free(&_heap, (u32)buf);\n}\n\nvoid *m_realloc(void* ptr, u32 current_size, u32 new_size)\n{\n    if (new_size == 0)\n    {\n      free(ptr);\n      return NULL;\n    }\n    else if (!ptr)\n    {\n        return malloc(new_size);\n    }\n    else if (new_size <= current_size)\n    {\n        return ptr;\n    }\n    else\n    {\n        if ((ptr) && (new_size > current_size))\n        {\n            void *ptrNew = malloc(new_size);\n            if (ptrNew)\n            {\n                memcpy(ptrNew, ptr, current_size);\n                free(ptr);\n            }\n            return ptrNew;\n        }\n        return NULL;\n    }\n}\n"
  },
  {
    "path": "argon-nx-gui/src/mem/mc.c",
    "content": "#include \"mem/mc.h\"\n#include \"soc/t210.h\"\n#include \"soc/clock.h\"\n#include \"utils/util.h\"\n\nvoid mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock)\n{\n\tMC(MC_SEC_CARVEOUT_BOM) = bom;\n\tMC(MC_SEC_CARVEOUT_SIZE_MB) = size1mb;\n\tif (lock)\n\t\tMC(MC_SEC_CARVEOUT_REG_CTRL) = 1;\n}\n\nvoid mc_config_carveout()\n{\n\t*(vu32 *)0x8005FFFC = 0xC0EDBBCC;\n\tMC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1;\n\tMC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;\n\tMC(MC_VIDEO_PROTECT_BOM) = 0;\n\tMC(MC_VIDEO_PROTECT_SIZE_MB) = 0;\n\tMC(MC_VIDEO_PROTECT_REG_CTRL) = 1;\n\n\t// Configure TSEC carveout @ 0x90000000, 1MB.\n\t//mc_config_tsec_carveout(0x90000000, 1, false);\n\tmc_config_tsec_carveout(0, 0, true);\n\n\tMC(MC_MTS_CARVEOUT_BOM) = 0;\n\tMC(MC_MTS_CARVEOUT_SIZE_MB) = 0;\n\tMC(MC_MTS_CARVEOUT_ADR_HI) = 0;\n\tMC(MC_MTS_CARVEOUT_REG_CTRL) = 1;\n\n\tMC(MC_SECURITY_CARVEOUT1_BOM) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_BOM_HI) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_SIZE_128KB) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;\n\tMC(MC_SECURITY_CARVEOUT1_CFG0) = 0x4000006;\n\n\tMC(MC_SECURITY_CARVEOUT2_BOM) = 0x80020000;\n\tMC(MC_SECURITY_CARVEOUT2_BOM_HI) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_SIZE_128KB) = 2;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = 0x3100000;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4) = 0x300;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;\n\tMC(MC_SECURITY_CARVEOUT2_CFG0) = 0x440167E;\n\n\tMC(MC_SECURITY_CARVEOUT3_BOM) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_BOM_HI) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_SIZE_128KB) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2) = 0x3000000;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4) = 0x300;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;\n\tMC(MC_SECURITY_CARVEOUT3_CFG0) = 0x4401E7E;\n\n\tMC(MC_SECURITY_CARVEOUT4_BOM) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_BOM_HI) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_SIZE_128KB) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;\n\tMC(MC_SECURITY_CARVEOUT4_CFG0) = 0x8F;\n\n\tMC(MC_SECURITY_CARVEOUT5_BOM) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_BOM_HI) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_SIZE_128KB) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;\n\tMC(MC_SECURITY_CARVEOUT5_CFG0) = 0x8F;\n}\n\nvoid mc_enable_ahb_redirect()\n{\n\t// Enable ARC_CLK_OVR_ON.\n\tCLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) = (CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) & 0xFFF7FFFF) | 0x80000;\n\t//MC(MC_IRAM_REG_CTRL) &= 0xFFFFFFFE;\n\tMC(MC_IRAM_BOM) = 0x40000000;\n\tMC(MC_IRAM_TOM) = 0x4003F000;\n}\n\nvoid mc_disable_ahb_redirect()\n{\n\tMC(MC_IRAM_BOM) = 0xFFFFF000;\n\tMC(MC_IRAM_TOM) = 0;\n\t// Disable IRAM_CFG_WRITE_ACCESS (sticky).\n\t//MC(MC_IRAM_REG_CTRL) = MC(MC_IRAM_REG_CTRL) & 0xFFFFFFFE | 1;\n\t// Disable ARC_CLK_OVR_ON.\n\tCLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) &= 0xFFF7FFFF;\n}\n\nvoid mc_enable()\n{\n\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | 0x40000000;\n\t// Enable MIPI CAL clock.\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFDFFFFFF) | 0x2000000;\n\t// Enable MC clock.\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFFFFFFFE) | 1;\n\t// Enable EMC DLL clock.\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) & 0xFFFFBFFF) | 0x4000;\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x2000001; //Clear EMC and MC reset.\n\tusleep(5);\n\n\t//#ifdef CONFIG_ENABLE_AHB_REDIRECT\n\tmc_disable_ahb_redirect();\n\t//mc_enable_ahb_redirect();\n\t//#endif\n}\n"
  },
  {
    "path": "argon-nx-gui/src/mem/sdram.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"soc/i2c.h\"\n#include \"soc/t210.h\"\n#include \"mem/mc.h\"\n#include \"mem/emc.h\"\n#include \"soc/pmc.h\"\n#include \"utils/util.h\"\n#include \"soc/fuse.h\"\n#include \"power/max77620.h\"\n#include \"mem/sdram_param_t210.h\"\n#include \"soc/clock.h\"\n\n#define CONFIG_SDRAM_COMPRESS_CFG\n\n#ifdef CONFIG_SDRAM_COMPRESS_CFG\n#include \"libs/compr/lz.h\"\n#include \"mem/sdram_config_lz.inl\"\n#else\n#include \"mem/sdram_config.inl\"\n#endif\n\nu32 get_sdram_id()\n{\n\treturn (fuse_read_odm(4) & 0x1F) >> 3;\n}\n\nstatic void _sdram_config(const sdram_params_t *params)\n{\n\tPMC(APBDEV_PMC_IO_DPD3_REQ) = (((4 * params->emc_pmc_scratch1 >> 2) + 0x80000000) ^ 0xFFFF) & 0xC000FFFF;\n\tusleep(params->pmc_io_dpd3_req_wait);\n\n\tu32 req = (4 * params->emc_pmc_scratch2 >> 2) + 0x80000000;\n\tPMC(APBDEV_PMC_IO_DPD4_REQ) = (req >> 16 << 16) ^ 0x3FFF0000;\n\tusleep(params->pmc_io_dpd4_req_wait);\n\tPMC(APBDEV_PMC_IO_DPD4_REQ) = (req ^ 0xFFFF) & 0xC000FFFF;\n\tusleep(params->pmc_io_dpd4_req_wait);\n\tPMC(APBDEV_PMC_WEAK_BIAS) = 0;\n\tusleep(1);\n\n\tCLOCK(CLK_RST_CONTROLLER_PLLM_MISC1) = params->pllm_setup_control;\n\tCLOCK(CLK_RST_CONTROLLER_PLLM_MISC2) = 0;\n\tCLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = (params->pllm_feedback_divider << 8) | params->pllm_input_divider | 0x40000000 | ((params->pllm_post_divider & 0xFFFF) << 20);\n\n\tu32 wait_end = get_tmr_us() + 300;\n\twhile (!(CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) & 0x8000000))\n\t{\n\t\tif (get_tmr_us() >= wait_end)\n\t\t\tgoto break_nosleep;\n\t}\n\tusleep(10);\nbreak_nosleep:\n\n\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = ((params->mc_emem_arb_misc0 >> 11) & 0x10000) | (params->emc_clock_source & 0xFFFEFFFF);\n\tif (params->emc_clock_source_dll)\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll;\n\tif (params->clear_clock2_mc1)\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = 0x40000000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x2000001;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x4000;\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x2000001;\n\tEMC(EMC_PMACRO_VTTGEN_CTRL_0) = params->emc_pmacro_vttgen_ctrl0;\n\tEMC(EMC_PMACRO_VTTGEN_CTRL_1) = params->emc_pmacro_vttgen_ctrl1;\n\tEMC(EMC_PMACRO_VTTGEN_CTRL_2) = params->emc_pmacro_vttgen_ctrl2;\n\tEMC(EMC_TIMING_CONTROL) = 1;\n\tusleep(1);\n\tEMC(EMC_DBG) = (params->emc_dbg_write_mux << 1) | params->emc_dbg;\n\tif (params->emc_bct_spare2)\n\t\t*(vu32 *)params->emc_bct_spare2 = params->emc_bct_spare3;\n\tEMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;\n\tEMC(EMC_CMD_MAPPING_CMD0_0) = params->emc_cmd_mapping_cmd0_0;\n\tEMC(EMC_CMD_MAPPING_CMD0_1) = params->emc_cmd_mapping_cmd0_1;\n\tEMC(EMC_CMD_MAPPING_CMD0_2) = params->emc_cmd_mapping_cmd0_2;\n\tEMC(EMC_CMD_MAPPING_CMD1_0) = params->emc_cmd_mapping_cmd1_0;\n\tEMC(EMC_CMD_MAPPING_CMD1_1) = params->emc_cmd_mapping_cmd1_1;\n\tEMC(EMC_CMD_MAPPING_CMD1_2) = params->emc_cmd_mapping_cmd1_2;\n\tEMC(EMC_CMD_MAPPING_CMD2_0) = params->emc_cmd_mapping_cmd2_0;\n\tEMC(EMC_CMD_MAPPING_CMD2_1) = params->emc_cmd_mapping_cmd2_1;\n\tEMC(EMC_CMD_MAPPING_CMD2_2) = params->emc_cmd_mapping_cmd2_2;\n\tEMC(EMC_CMD_MAPPING_CMD3_0) = params->emc_cmd_mapping_cmd3_0;\n\tEMC(EMC_CMD_MAPPING_CMD3_1) = params->emc_cmd_mapping_cmd3_1;\n\tEMC(EMC_CMD_MAPPING_CMD3_2) = params->emc_cmd_mapping_cmd3_2;\n\tEMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;\n\tEMC(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0;\n\tEMC(EMC_PMACRO_BRICK_MAPPING_1) = params->emc_pmacro_brick_mapping1;\n\tEMC(EMC_PMACRO_BRICK_MAPPING_2) = params->emc_pmacro_brick_mapping2;\n\tEMC(EMC_PMACRO_BRICK_CTRL_RFU1) = (params->emc_pmacro_brick_ctrl_rfu1 & 0x1120112) | 0x1EED1EED;\n\tEMC(EMC_CONFIG_SAMPLE_DELAY) = params->emc_config_sample_delay;\n\tEMC(EMC_FBIO_CFG8) = params->emc_fbio_cfg8;\n\tEMC(EMC_SWIZZLE_RANK0_BYTE0) = params->emc_swizzle_rank0_byte0;\n\tEMC(EMC_SWIZZLE_RANK0_BYTE1) = params->emc_swizzle_rank0_byte1;\n\tEMC(EMC_SWIZZLE_RANK0_BYTE2) = params->emc_swizzle_rank0_byte2;\n\tEMC(EMC_SWIZZLE_RANK0_BYTE3) = params->emc_swizzle_rank0_byte3;\n\tEMC(EMC_SWIZZLE_RANK1_BYTE0) = params->emc_swizzle_rank1_byte0;\n\tEMC(EMC_SWIZZLE_RANK1_BYTE1) = params->emc_swizzle_rank1_byte1;\n\tEMC(EMC_SWIZZLE_RANK1_BYTE2) = params->emc_swizzle_rank1_byte2;\n\tEMC(EMC_SWIZZLE_RANK1_BYTE3) = params->emc_swizzle_rank1_byte3;\n\tif (params->emc_bct_spare6)\n\t\t*(vu32 *)params->emc_bct_spare6 = params->emc_bct_spare7;\n\tEMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl;\n\tEMC(EMC_XM2COMPPADCTRL2) = params->emc_xm2_comp_pad_ctrl2;\n\tEMC(EMC_XM2COMPPADCTRL3) = params->emc_xm2_comp_pad_ctrl3;\n\tEMC(EMC_AUTO_CAL_CONFIG2) = params->emc_auto_cal_config2;\n\tEMC(EMC_AUTO_CAL_CONFIG3) = params->emc_auto_cal_config3;\n\tEMC(EMC_AUTO_CAL_CONFIG4) = params->emc_auto_cal_config4;\n\tEMC(EMC_AUTO_CAL_CONFIG5) = params->emc_auto_cal_config5;\n\tEMC(EMC_AUTO_CAL_CONFIG6) = params->emc_auto_cal_config6;\n\tEMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7;\n\tEMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8;\n\tEMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;\n\tEMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;\n\tEMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;\n\tEMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive;\n\tEMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = params->emc_pmacro_auto_cal_common;\n\tEMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;\n\tEMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;\n\tEMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0;\n\tEMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1;\n\tEMC(EMC_CFG_DIG_DLL_1) = params->emc_cfg_dig_dll_1;\n\tEMC(EMC_DATA_BRLSHFT_0) = params->emc_data_brlshft0;\n\tEMC(EMC_DATA_BRLSHFT_1) = params->emc_data_brlshft1;\n\tEMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0;\n\tEMC(EMC_DQS_BRLSHFT_1) = params->emc_dqs_brlshft1;\n\tEMC(EMC_CMD_BRLSHFT_0) = params->emc_cmd_brlshft0;\n\tEMC(EMC_CMD_BRLSHFT_1) = params->emc_cmd_brlshft1;\n\tEMC(EMC_CMD_BRLSHFT_2) = params->emc_cmd_brlshft2;\n\tEMC(EMC_CMD_BRLSHFT_3) = params->emc_cmd_brlshft3;\n\tEMC(EMC_QUSE_BRLSHFT_0) = params->emc_quse_brlshft0;\n\tEMC(EMC_QUSE_BRLSHFT_1) = params->emc_quse_brlshft1;\n\tEMC(EMC_QUSE_BRLSHFT_2) = params->emc_quse_brlshft2;\n\tEMC(EMC_QUSE_BRLSHFT_3) = params->emc_quse_brlshft3;\n\tEMC(EMC_PMACRO_BRICK_CTRL_RFU1) = (params->emc_pmacro_brick_ctrl_rfu1 & 0x1BF01BF) | 0x1E401E40;\n\tEMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl;\n\tEMC(EMC_PMACRO_CMD_BRICK_CTRL_FDPD) = params->emc_pmacro_cmd_brick_ctrl_fdpd;\n\tEMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2 & 0xFF7FFF7F;\n\tEMC(EMC_PMACRO_DATA_BRICK_CTRL_FDPD) = params->emc_pmacro_data_brick_ctrl_fdpd;\n\tEMC(EMC_PMACRO_BG_BIAS_CTRL_0) = params->emc_pmacro_bg_bias_ctrl0;\n\tEMC(EMC_PMACRO_DATA_PAD_RX_CTRL) = params->emc_pmacro_data_pad_rx_ctrl;\n\tEMC(EMC_PMACRO_CMD_PAD_RX_CTRL) = params->emc_pmacro_cmd_pad_rx_ctrl;\n\tEMC(EMC_PMACRO_DATA_PAD_TX_CTRL) = params->emc_pmacro_data_pad_tx_ctrl;\n\tEMC(EMC_PMACRO_DATA_RX_TERM_MODE) = params->emc_pmacro_data_rx_term_mode;\n\tEMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;\n\tEMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl;\n\tEMC(EMC_CFG_3) = params->emc_cfg3;\n\tEMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;\n\tEMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;\n\tEMC(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2;\n\tEMC(EMC_PMACRO_TX_PWRD_3) = params->emc_pmacro_tx_pwrd3;\n\tEMC(EMC_PMACRO_TX_PWRD_4) = params->emc_pmacro_tx_pwrd4;\n\tEMC(EMC_PMACRO_TX_PWRD_5) = params->emc_pmacro_tx_pwrd5;\n\tEMC(EMC_PMACRO_TX_SEL_CLK_SRC_0) = params->emc_pmacro_tx_sel_clk_src0;\n\tEMC(EMC_PMACRO_TX_SEL_CLK_SRC_1) = params->emc_pmacro_tx_sel_clk_src1;\n\tEMC(EMC_PMACRO_TX_SEL_CLK_SRC_2) = params->emc_pmacro_tx_sel_clk_src2;\n\tEMC(EMC_PMACRO_TX_SEL_CLK_SRC_3) = params->emc_pmacro_tx_sel_clk_src3;\n\tEMC(EMC_PMACRO_TX_SEL_CLK_SRC_4) = params->emc_pmacro_tx_sel_clk_src4;\n\tEMC(EMC_PMACRO_TX_SEL_CLK_SRC_5) = params->emc_pmacro_tx_sel_clk_src5;\n\tEMC(EMC_PMACRO_DDLL_BYPASS) = params->emc_pmacro_ddll_bypass;\n\tEMC(EMC_PMACRO_DDLL_PWRD_0) = params->emc_pmacro_ddll_pwrd0;\n\tEMC(EMC_PMACRO_DDLL_PWRD_1) = params->emc_pmacro_ddll_pwrd1;\n\tEMC(EMC_PMACRO_DDLL_PWRD_2) = params->emc_pmacro_ddll_pwrd2;\n\tEMC(EMC_PMACRO_CMD_CTRL_0) = params->emc_pmacro_cmd_ctrl0;\n\tEMC(EMC_PMACRO_CMD_CTRL_1) = params->emc_pmacro_cmd_ctrl1;\n\tEMC(EMC_PMACRO_CMD_CTRL_2) = params->emc_pmacro_cmd_ctrl2;\n\tEMC(EMC_PMACRO_IB_VREF_DQ_0) = params->emc_pmacro_ib_vref_dq_0;\n\tEMC(EMC_PMACRO_IB_VREF_DQ_1) = params->emc_pmacro_ib_vref_dq_1;\n\tEMC(EMC_PMACRO_IB_VREF_DQS_0) = params->emc_pmacro_ib_vref_dqs_0;\n\tEMC(EMC_PMACRO_IB_VREF_DQS_1) = params->emc_pmacro_ib_vref_dqs_1;\n\tEMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK0_0) = params->emc_pmacro_quse_ddll_rank0_0;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK0_1) = params->emc_pmacro_quse_ddll_rank0_1;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK0_2) = params->emc_pmacro_quse_ddll_rank0_2;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK0_3) = params->emc_pmacro_quse_ddll_rank0_3;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK0_4) = params->emc_pmacro_quse_ddll_rank0_4;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK0_5) = params->emc_pmacro_quse_ddll_rank0_5;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK1_0) = params->emc_pmacro_quse_ddll_rank1_0;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK1_1) = params->emc_pmacro_quse_ddll_rank1_1;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK1_2) = params->emc_pmacro_quse_ddll_rank1_2;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK1_3) = params->emc_pmacro_quse_ddll_rank1_3;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK1_4) = params->emc_pmacro_quse_ddll_rank1_4;\n\tEMC(EMC_PMACRO_QUSE_DDLL_RANK1_5) = params->emc_pmacro_quse_ddll_rank1_5;\n\tEMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0) = params->emc_pmacro_ob_ddll_long_dq_rank0_0;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1) = params->emc_pmacro_ob_ddll_long_dq_rank0_1;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2) = params->emc_pmacro_ob_ddll_long_dq_rank0_2;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3) = params->emc_pmacro_ob_ddll_long_dq_rank0_3;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4) = params->emc_pmacro_ob_ddll_long_dq_rank0_4;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5) = params->emc_pmacro_ob_ddll_long_dq_rank0_5;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0) = params->emc_pmacro_ob_ddll_long_dq_rank1_0;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1) = params->emc_pmacro_ob_ddll_long_dq_rank1_1;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2) = params->emc_pmacro_ob_ddll_long_dq_rank1_2;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3) = params->emc_pmacro_ob_ddll_long_dq_rank1_3;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4) = params->emc_pmacro_ob_ddll_long_dq_rank1_4;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5) = params->emc_pmacro_ob_ddll_long_dq_rank1_5;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0) = params->emc_pmacro_ob_ddll_long_dqs_rank0_0;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1) = params->emc_pmacro_ob_ddll_long_dqs_rank0_1;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2) = params->emc_pmacro_ob_ddll_long_dqs_rank0_2;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3) = params->emc_pmacro_ob_ddll_long_dqs_rank0_3;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4) = params->emc_pmacro_ob_ddll_long_dqs_rank0_4;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5) = params->emc_pmacro_ob_ddll_long_dqs_rank0_5;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0) = params->emc_pmacro_ob_ddll_long_dqs_rank1_0;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1) = params->emc_pmacro_ob_ddll_long_dqs_rank1_1;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ob_ddll_long_dqs_rank1_2;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ob_ddll_long_dqs_rank1_3;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4) = params->emc_pmacro_ob_ddll_long_dqs_rank1_4;\n\tEMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5) = params->emc_pmacro_ob_ddll_long_dqs_rank1_5;\n\tEMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0) = params->emc_pmacro_ib_ddll_long_dqs_rank0_0;\n\tEMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1) = params->emc_pmacro_ib_ddll_long_dqs_rank0_1;\n\tEMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2) = params->emc_pmacro_ib_ddll_long_dqs_rank0_2;\n\tEMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3) = params->emc_pmacro_ib_ddll_long_dqs_rank0_3;\n\tEMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0) = params->emc_pmacro_ib_ddll_long_dqs_rank1_0;\n\tEMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1) = params->emc_pmacro_ib_ddll_long_dqs_rank1_1;\n\tEMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ib_ddll_long_dqs_rank1_2;\n\tEMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ib_ddll_long_dqs_rank1_3;\n\tEMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0;\n\tEMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1;\n\tEMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2;\n\tEMC(EMC_PMACRO_DDLL_LONG_CMD_3) = params->emc_pmacro_ddll_long_cmd_3;\n\tEMC(EMC_PMACRO_DDLL_LONG_CMD_4) = params->emc_pmacro_ddll_long_cmd_4;\n\tEMC(EMC_PMACRO_DDLL_SHORT_CMD_0) = params->emc_pmacro_ddll_short_cmd_0;\n\tEMC(EMC_PMACRO_DDLL_SHORT_CMD_1) = params->emc_pmacro_ddll_short_cmd_1;\n\tEMC(EMC_PMACRO_DDLL_SHORT_CMD_2) = params->emc_pmacro_ddll_short_cmd_2;\n\tEMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = (params->emc_pmacro_common_pad_tx_ctrl & 1) | 0xE;\n\tif (params->emc_bct_spare4)\n\t\t*(vu32 *)params->emc_bct_spare4 = params->emc_bct_spare5;\n\tEMC(EMC_TIMING_CONTROL) = 1;\n\tMC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom;\n\tMC(MC_VIDEO_PROTECT_BOM_ADR_HI) = params->mc_video_protect_bom_adr_hi;\n\tMC(MC_VIDEO_PROTECT_SIZE_MB) = params->mc_video_protect_size_mb;\n\tMC(MC_VIDEO_PROTECT_VPR_OVERRIDE) = params->mc_video_protect_vpr_override;\n\tMC(MC_VIDEO_PROTECT_VPR_OVERRIDE1) = params->mc_video_protect_vpr_override1;\n\tMC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = params->mc_video_protect_gpu_override0;\n\tMC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = params->mc_video_protect_gpu_override1;\n\tMC(MC_EMEM_ADR_CFG) = params->mc_emem_adr_cfg;\n\tMC(MC_EMEM_ADR_CFG_DEV0) = params->mc_emem_adr_cfg_dev0;\n\tMC(MC_EMEM_ADR_CFG_DEV1) = params->mc_emem_adr_cfg_dev1;\n\tMC(MC_EMEM_ADR_CFG_CHANNEL_MASK) = params->mc_emem_adr_cfg_channel_mask;\n\tMC(MC_EMEM_ADR_CFG_BANK_MASK_0) = params->mc_emem_adr_cfg_bank_mask0;\n\tMC(MC_EMEM_ADR_CFG_BANK_MASK_1) = params->mc_emem_adr_cfg_bank_mask1;\n\tMC(MC_EMEM_ADR_CFG_BANK_MASK_2) = params->mc_emem_adr_cfg_bank_mask2;\n\tMC(MC_EMEM_CFG) = params->mc_emem_cfg;\n\tMC(MC_SEC_CARVEOUT_BOM) = params->mc_sec_carveout_bom;\n\tMC(MC_SEC_CARVEOUT_ADR_HI) = params->mc_sec_carveout_adr_hi;\n\tMC(MC_SEC_CARVEOUT_SIZE_MB) = params->mc_sec_carveout_size_mb;\n\tMC(MC_MTS_CARVEOUT_BOM) = params->mc_mts_carveout_bom;\n\tMC(MC_MTS_CARVEOUT_ADR_HI) = params->mc_mts_carveout_adr_hi;\n\tMC(MC_MTS_CARVEOUT_SIZE_MB) = params->mc_mts_carveout_size_mb;\n\tMC(MC_EMEM_ARB_CFG) = params->mc_emem_arb_cfg;\n\tMC(MC_EMEM_ARB_OUTSTANDING_REQ) = params->mc_emem_arb_outstanding_req;\n\tMC(MC_EMEM_ARB_REFPB_HP_CTRL) = params->emc_emem_arb_refpb_hp_ctrl;\n\tMC(MC_EMEM_ARB_REFPB_BANK_CTRL) = params->emc_emem_arb_refpb_bank_ctrl;\n\tMC(MC_EMEM_ARB_TIMING_RCD) = params->mc_emem_arb_timing_rcd;\n\tMC(MC_EMEM_ARB_TIMING_RP) = params->mc_emem_arb_timing_rp;\n\tMC(MC_EMEM_ARB_TIMING_RC) = params->mc_emem_arb_timing_rc;\n\tMC(MC_EMEM_ARB_TIMING_RAS) = params->mc_emem_arb_timing_ras;\n\tMC(MC_EMEM_ARB_TIMING_FAW) = params->mc_emem_arb_timing_faw;\n\tMC(MC_EMEM_ARB_TIMING_RRD) = params->mc_emem_arb_timing_rrd;\n\tMC(MC_EMEM_ARB_TIMING_RAP2PRE) = params->mc_emem_arb_timing_rap2pre;\n\tMC(MC_EMEM_ARB_TIMING_WAP2PRE) = params->mc_emem_arb_timing_wap2pre;\n\tMC(MC_EMEM_ARB_TIMING_R2R) = params->mc_emem_arb_timing_r2r;\n\tMC(MC_EMEM_ARB_TIMING_W2W) = params->mc_emem_arb_timing_w2w;\n\tMC(MC_EMEM_ARB_TIMING_CCDMW) = params->mc_emem_arb_timing_ccdmw;\n\tMC(MC_EMEM_ARB_TIMING_R2W) = params->mc_emem_arb_timing_r2w;\n\tMC(MC_EMEM_ARB_TIMING_W2R) = params->mc_emem_arb_timing_w2r;\n\tMC(MC_EMEM_ARB_TIMING_RFCPB) = params->mc_emem_arb_timing_rfcpb;\n\tMC(MC_EMEM_ARB_DA_TURNS) = params->mc_emem_arb_da_turns;\n\tMC(MC_EMEM_ARB_DA_COVERS) = params->mc_emem_arb_da_covers;\n\tMC(MC_EMEM_ARB_MISC0) = params->mc_emem_arb_misc0;\n\tMC(MC_EMEM_ARB_MISC1) = params->mc_emem_arb_misc1;\n\tMC(MC_EMEM_ARB_MISC2) = params->mc_emem_arb_misc2;\n\tMC(MC_EMEM_ARB_RING1_THROTTLE) = params->mc_emem_arb_ring1_throttle;\n\tMC(MC_EMEM_ARB_OVERRIDE) = params->mc_emem_arb_override;\n\tMC(MC_EMEM_ARB_OVERRIDE_1) = params->mc_emem_arb_override1;\n\tMC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv;\n\tMC(MC_DA_CONFIG0) = params->mc_da_cfg0;\n\tMC(MC_TIMING_CONTROL) = 1;\n\tMC(MC_CLKEN_OVERRIDE) = params->mc_clken_override;\n\tMC(MC_STAT_CONTROL) = params->mc_stat_control;\n\tEMC(EMC_ADR_CFG) = params->emc_adr_cfg;\n\tEMC(EMC_CLKEN_OVERRIDE) = params->emc_clken_override;\n\tEMC(EMC_PMACRO_AUTOCAL_CFG_0) = params->emc_pmacro_auto_cal_cfg0;\n\tEMC(EMC_PMACRO_AUTOCAL_CFG_1) = params->emc_pmacro_auto_cal_cfg1;\n\tEMC(EMC_PMACRO_AUTOCAL_CFG_2) = params->emc_pmacro_auto_cal_cfg2;\n\tEMC(EMC_AUTO_CAL_VREF_SEL_0) = params->emc_auto_cal_vref_sel0;\n\tEMC(EMC_AUTO_CAL_VREF_SEL_1) = params->emc_auto_cal_vref_sel1;\n\tEMC(EMC_AUTO_CAL_INTERVAL) = params->emc_auto_cal_interval;\n\tEMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config;\n\tusleep(params->emc_auto_cal_wait);\n\tif (params->emc_bct_spare8)\n\t\t*(vu32 *)params->emc_bct_spare8 = params->emc_bct_spare9;\n\tEMC(EMC_CFG_2) = params->emc_cfg2;\n\tEMC(EMC_CFG_PIPE) = params->emc_cfg_pipe;\n\tEMC(EMC_CFG_PIPE_1) = params->emc_cfg_pipe1;\n\tEMC(EMC_CFG_PIPE_2) = params->emc_cfg_pipe2;\n\tEMC(EMC_CMDQ) = params->emc_cmd_q;\n\tEMC(EMC_MC2EMCQ) = params->emc_mc2emc_q;\n\tEMC(EMC_MRS_WAIT_CNT) = params->emc_mrs_wait_cnt;\n\tEMC(EMC_MRS_WAIT_CNT2) = params->emc_mrs_wait_cnt2;\n\tEMC(EMC_FBIO_CFG5) = params->emc_fbio_cfg5;\n\tEMC(EMC_RC) = params->emc_rc;\n\tEMC(EMC_RFC) = params->emc_rfc;\n\tEMC(EMC_RFCPB) = params->emc_rfc_pb;\n\tEMC(EMC_REFCTRL2) = params->emc_ref_ctrl2;\n\tEMC(EMC_RFC_SLR) = params->emc_rfc_slr;\n\tEMC(EMC_RAS) = params->emc_ras;\n\tEMC(EMC_RP) = params->emc_rp;\n\tEMC(EMC_TPPD) = params->emc_tppd;\n\tEMC(EMC_R2R) = params->emc_r2r;\n\tEMC(EMC_W2W) = params->emc_w2w;\n\tEMC(EMC_R2W) = params->emc_r2w;\n\tEMC(EMC_W2R) = params->emc_w2r;\n\tEMC(EMC_R2P) = params->emc_r2p;\n\tEMC(EMC_W2P) = params->emc_w2p;\n\tEMC(EMC_CCDMW) = params->emc_ccdmw;\n\tEMC(EMC_RD_RCD) = params->emc_rd_rcd;\n\tEMC(EMC_WR_RCD) = params->emc_wr_rcd;\n\tEMC(EMC_RRD) = params->emc_rrd;\n\tEMC(EMC_REXT) = params->emc_rext;\n\tEMC(EMC_WEXT) = params->emc_wext;\n\tEMC(EMC_WDV) = params->emc_wdv;\n\tEMC(EMC_WDV_CHK) = params->emc_wdv_chk;\n\tEMC(EMC_WSV) = params->emc_wsv;\n\tEMC(EMC_WEV) = params->emc_wev;\n\tEMC(EMC_WDV_MASK) = params->emc_wdv_mask;\n\tEMC(EMC_WS_DURATION) = params->emc_ws_duration;\n\tEMC(EMC_WE_DURATION) = params->emc_we_duration;\n\tEMC(EMC_QUSE) = params->emc_quse;\n\tEMC(EMC_QUSE_WIDTH) = params->emc_quse_width;\n\tEMC(EMC_IBDLY) = params->emc_ibdly;\n\tEMC(EMC_OBDLY) = params->emc_obdly;\n\tEMC(EMC_EINPUT) = params->emc_einput;\n\tEMC(EMC_EINPUT_DURATION) = params->emc_einput_duration;\n\tEMC(EMC_PUTERM_EXTRA) = params->emc_puterm_extra;\n\tEMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width;\n\tEMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = params->emc_pmacro_common_pad_tx_ctrl;\n\tEMC(EMC_DBG) = params->emc_dbg;\n\tEMC(EMC_QRST) = params->emc_qrst;\n\tEMC(EMC_ISSUE_QRST) = 0;\n\tEMC(EMC_QSAFE) = params->emc_qsafe;\n\tEMC(EMC_RDV) = params->emc_rdv;\n\tEMC(EMC_RDV_MASK) = params->emc_rdv_mask;\n\tEMC(EMC_RDV_EARLY) = params->emc_rdv_early;\n\tEMC(EMC_RDV_EARLY_MASK) = params->emc_rdv_early_mask;\n\tEMC(EMC_QPOP) = params->emc_qpop;\n\tEMC(EMC_REFRESH) = params->emc_refresh;\n\tEMC(EMC_BURST_REFRESH_NUM) = params->emc_burst_refresh_num;\n\tEMC(EMC_PRE_REFRESH_REQ_CNT) = params->emc_prerefresh_req_cnt;\n\tEMC(EMC_PDEX2WR) = params->emc_pdex2wr;\n\tEMC(EMC_PDEX2RD) = params->emc_pdex2rd;\n\tEMC(EMC_PCHG2PDEN) = params->emc_pchg2pden;\n\tEMC(EMC_ACT2PDEN) = params->emc_act2pden;\n\tEMC(EMC_AR2PDEN) = params->emc_ar2pden;\n\tEMC(EMC_RW2PDEN) = params->emc_rw2pden;\n\tEMC(EMC_CKE2PDEN) = params->emc_cke2pden;\n\tEMC(EMC_PDEX2CKE) = params->emc_pdex2che;\n\tEMC(EMC_PDEX2MRR) = params->emc_pdex2mrr;\n\tEMC(EMC_TXSR) = params->emc_txsr;\n\tEMC(EMC_TXSRDLL) = params->emc_txsr_dll;\n\tEMC(EMC_TCKE) = params->emc_tcke;\n\tEMC(EMC_TCKESR) = params->emc_tckesr;\n\tEMC(EMC_TPD) = params->emc_tpd;\n\tEMC(EMC_TFAW) = params->emc_tfaw;\n\tEMC(EMC_TRPAB) = params->emc_trpab;\n\tEMC(EMC_TCLKSTABLE) = params->emc_tclkstable;\n\tEMC(EMC_TCLKSTOP) = params->emc_tclkstop;\n\tEMC(EMC_TREFBW) = params->emc_trefbw;\n\tEMC(EMC_ODT_WRITE) = params->emc_odt_write;\n\tEMC(EMC_CFG_DIG_DLL) = params->emc_cfg_dig_dll;\n\tEMC(EMC_CFG_DIG_DLL_PERIOD) = params->emc_cfg_dig_dll_period;\n\tEMC(EMC_FBIO_SPARE) = params->emc_fbio_spare & 0xFFFFFFFD;\n\tEMC(EMC_CFG_RSV) = params->emc_cfg_rsv;\n\tEMC(EMC_PMC_SCRATCH1) = params->emc_pmc_scratch1;\n\tEMC(EMC_PMC_SCRATCH2) = params->emc_pmc_scratch2;\n\tEMC(EMC_PMC_SCRATCH3) = params->emc_pmc_scratch3;\n\tEMC(EMC_ACPD_CONTROL) = params->emc_acpd_control;\n\tEMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen;\n\tEMC(EMC_CFG) = (params->emc_cfg & 0xE) | 0x3C00000;\n\tif (params->boot_rom_patch_control & 0x80000000)\n\t{\n\t\t*(vu32 *)(4 * (params->boot_rom_patch_control + 0x1C000000)) = params->boot_rom_patch_data;\n\t\tMC(MC_TIMING_CONTROL) = 1;\n\t}\n\tPMC(APBDEV_PMC_IO_DPD3_REQ) = ((4 * params->emc_pmc_scratch1 >> 2) + 0x40000000) & 0xCFFF0000;\n\tusleep(params->pmc_io_dpd3_req_wait);\n\tif (!params->emc_auto_cal_interval)\n\t\tEMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config | 0x200;\n\tEMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2;\n\tif (params->emc_zcal_warm_cold_boot_enables & 1)\n\t{\n\t\tif (params->memory_type == 2)\n\t\t\tEMC(EMC_ZCAL_WAIT_CNT) = 8 * params->emc_zcal_wait_cnt;\n\t\tif (params->memory_type == 3)\n\t\t{\n\t\t\tEMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;\n\t\t\tEMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;\n\t\t}\n\t}\n\tEMC(EMC_TIMING_CONTROL) = 1;\n\tusleep(params->emc_timing_control_wait);\n\tPMC(APBDEV_PMC_DDR_CNTRL) &= 0xFFF8007F;\n\tusleep(params->pmc_ddr_ctrl_wait);\n\tif (params->memory_type == 2)\n\t{\n\t\tEMC(EMC_PIN) = (params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12);\n\t\tusleep(params->emc_pin_extra_wait + 200);\n\t\tEMC(EMC_PIN) = ((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 256;\n\t\tusleep(params->emc_pin_extra_wait + 500);\n\t}\n\tif (params->memory_type == 3)\n\t{\n\t\tEMC(EMC_PIN) = (params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12);\n\t\tusleep(params->emc_pin_extra_wait + 200);\n\t\tEMC(EMC_PIN) = ((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 256;\n\t\tusleep(params->emc_pin_extra_wait + 2000);\n\t}\n\tEMC(EMC_PIN) = ((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 0x101;\n\tusleep(params->emc_pin_program_wait);\n\tif (params->memory_type != 3)\n\t\tEMC(EMC_NOP) = (params->emc_dev_select << 30) + 1;\n\tif (params->memory_type == 1)\n\t\tusleep(params->emc_pin_extra_wait + 200);\n\tif (params->memory_type == 3)\n\t{\n\t\tif (params->emc_bct_spare10)\n\t\t\t*(vu32 *)params->emc_bct_spare10 = params->emc_bct_spare11;\n\t\tEMC(EMC_MRW2) = params->emc_mrw2;\n\t\tEMC(EMC_MRW) = params->emc_mrw1;\n\t\tEMC(EMC_MRW3) = params->emc_mrw3;\n\t\tEMC(EMC_MRW4) = params->emc_mrw4;\n\t\tEMC(EMC_MRW6) = params->emc_mrw6;\n\t\tEMC(EMC_MRW14) = params->emc_mrw14;\n\t\tEMC(EMC_MRW8) = params->emc_mrw8;\n\t\tEMC(EMC_MRW12) = params->emc_mrw12;\n\t\tEMC(EMC_MRW9) = params->emc_mrw9;\n\t\tEMC(EMC_MRW13) = params->emc_mrw13;\n\t\tif (params->emc_zcal_warm_cold_boot_enables & 1)\n\t\t{\n\t\t\tEMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0;\n\t\t\tusleep(params->emc_zcal_init_wait);\n\t\t\tEMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0 ^ 3;\n\t\t\tif (!(params->emc_dev_select & 2))\n\t\t\t{\n\t\t\t\tEMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1;\n\t\t\t\tusleep(params->emc_zcal_init_wait);\n\t\t\t\tEMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1 ^ 3;\n\t\t\t}\n\t\t}\n\t}\n\tPMC(APBDEV_PMC_DDR_CFG) = params->pmc_ddr_cfg;\n\tif (params->memory_type - 1 <= 2)\n\t{\n\t\tEMC(EMC_ZCAL_INTERVAL) = params->emc_zcal_interval;\n\t\tEMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;\n\t\tEMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;\n\t}\n\tif (params->emc_bct_spare12)\n\t\t*(vu32 *)params->emc_bct_spare12 = params->emc_bct_spare13;\n\tEMC(EMC_TIMING_CONTROL) = 1;\n\tif (params->emc_extra_refresh_num)\n\t\tEMC(EMC_REF) = ((1 << params->emc_extra_refresh_num << 8) - 0xFD) | (params->emc_pin_gpio << 30);\n\tEMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000;\n\tEMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;\n\tEMC(EMC_CFG_UPDATE) = params->emc_cfg_update;\n\tEMC(EMC_CFG) = params->emc_cfg;\n\tEMC(EMC_FDPD_CTRL_DQ) = params->emc_fdpd_ctrl_dq;\n\tEMC(EMC_FDPD_CTRL_CMD) = params->emc_fdpd_ctrl_cmd;\n\tEMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;\n\tEMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2;\n\tEMC(EMC_TIMING_CONTROL) = 1;\n\tEMC(EMC_CFG_PIPE_CLK) = params->emc_cfg_pipe_clk;\n\tEMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = params->emc_fdpd_ctrl_cmd_no_ramp;\n\tSYSREG(AHB_ARBITRATION_XBAR_CTRL) = (SYSREG(AHB_ARBITRATION_XBAR_CTRL) & 0xFFFEFFFF) | ((params->ahb_arbitration_xbar_ctrl_meminit_done & 0xFFFF) << 16);\n\tMC(MC_VIDEO_PROTECT_REG_CTRL) = params->mc_video_protect_write_access;\n\tMC(MC_SEC_CARVEOUT_REG_CTRL) = params->mc_sec_carveout_protect_write_access;\n\tMC(MC_MTS_CARVEOUT_REG_CTRL) = params->mc_mts_carveout_reg_ctrl;\n\tMC(MC_EMEM_CFG_ACCESS_CTRL) = 1; //Disable write access to a bunch of EMC registers.\n}\n\nconst void *sdram_get_params()\n{\n\t//TODO: sdram_id should be in [0, 7].\n\n#ifdef CONFIG_SDRAM_COMPRESS_CFG\n\tu8 *buf = (u8 *)0x40030000;\n\tLZ_Uncompress(_dram_cfg_lz, buf, sizeof(_dram_cfg_lz));\n\treturn (const void *)&buf[sizeof(sdram_params_t) * get_sdram_id()];\n#else\n\treturn _dram_cfgs[get_sdram_id()];\n#endif\n}\n\nvoid sdram_init()\n{\n\t//TODO: sdram_id should be in [0,4].\n\tconst sdram_params_t *params = (const sdram_params_t *)sdram_get_params();\n\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, 0x05);\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD1, 40); //40 = (1000 * 1100 - 600000) / 12500 -> 1.1V\n\n\tPMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel;\n\tusleep(params->pmc_vddp_sel_wait);\n\tPMC(APBDEV_PMC_DDR_PWR) = PMC(APBDEV_PMC_DDR_PWR);\n\tPMC(APBDEV_PMC_NO_IOPOWER) = params->pmc_no_io_power;\n\tPMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short;\n\tPMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl;\n\n\tif (params->emc_bct_spare0)\n\t\t*(vu32 *)params->emc_bct_spare0 = params->emc_bct_spare1;\n\n\t_sdram_config(params);\n}\n"
  },
  {
    "path": "argon-nx-gui/src/menu/gui/gui_menu.c",
    "content": "/*  \n * Copyright (c) 2018 Guillem96\n *\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"menu/gui/gui_menu.h\"\n#include \"menu/gui/gui_menu_pool.h\"\n#include \"menu/gui/gui_menu_controllers.h\"\n\n#include \"power/battery.h\"\n\n#include \"core/custom-gui.h\"\n#include \"core/payloads.h\"\n\n#include \"utils/util.h\"\n#include \"utils/dirlist.h\"\n\n#include \"gfx/gfx.h\"\n#include \"gfx/lvgl_adapter.h\"\n\n#include <string.h>\n\n\n/* Render functions */\nstatic bool render_title(argon_ctxt_t *);\n\nstatic bool render_tabs(argon_ctxt_t *);\n\nstatic bool render_payloads_tab(lv_obj_t *, argon_ctxt_t *);\nstatic bool render_single_payload_tab(lv_obj_t *, argon_ctxt_t *, char*, u32);\nstatic bool render_payloads_entries(lv_obj_t *, argon_ctxt_t *, char*, u32);\n\nstatic bool render_tools_tab(lv_obj_t *, argon_ctxt_t *);\n\nvoid gui_menu_draw(argon_ctxt_t *argon_ctxt)\n{   \n    custom_gui_t *cg = custom_gui_load();\n\n    /* Deafult background is a beautiful gradient */\n    lv_style_scr.body.main_color = GRAD_1;\n    lv_style_scr.body.grad_color = GRAD_2;\n       \n    render_custom_background(cg, lv_scr_act());\n    render_title(argon_ctxt);\n    render_tabs(argon_ctxt);\n}\n\nvoid gui_menu_open(argon_ctxt_t *argon_ctxt)\n{\n    g_argon_ctxt = argon_ctxt;\n\n    while (true)\n    {\n        lv_tick_inc(1);\n        lv_task_handler();\n        msleep(1);\n    }\n}\n\nvoid gui_menu_destroy(argon_ctxt_t *argon_ctxt)\n{\n    argon_ctxt_destroy(argon_ctxt);\n}\n\nstatic bool render_tabs(argon_ctxt_t *argon_ctxt)\n{\n    /* Create tabview container */\n    lv_obj_t *base_tabs = lv_tabview_create(lv_scr_act(), NULL);\n    lv_obj_set_pos(base_tabs, 0, 0);\n    lv_tabview_set_btns_pos(base_tabs, LV_TABVIEW_BTNS_POS_BOTTOM);\n    lv_tabview_set_style(base_tabs, LV_TABVIEW_STYLE_BG, &lv_style_transp_tight);\n\n    /* Disable animations */\n    lv_tabview_set_anim_time(base_tabs, 0);\n    lv_tabview_set_sliding(base_tabs, false);\n\n    /* Render all tabs */\n    render_payloads_tab(base_tabs, argon_ctxt);\n    render_tools_tab(base_tabs, argon_ctxt);\n\n    return true;\n}\n\nstatic bool render_payloads_tab(lv_obj_t *par, argon_ctxt_t *ctxt)\n{\n    char* payloads = dirlist(PAYLOADS_DIR, \"*.bin\", false);\n    u32 i = 0;\n    u32 group = 0;\n    \n    while(payloads[i * 256])\n    {\n        if (i % 4 == 0)\n        {\n            render_single_payload_tab(par, ctxt, payloads, group);\n            group++;\n        }\n        i++;\n    }\n\n    if (group == 0)\n        render_single_payload_tab(par, ctxt, payloads, group);\n\n    return true;\n}\n\nstatic bool render_single_payload_tab(lv_obj_t *par, argon_ctxt_t * ctxt, char* payloads, u32 group)\n{\n    /* Setting scrollable view */\n    lv_obj_t* payloads_tab = lv_tabview_add_tab(par,\n                                    LV_SYMBOL_DIRECTORY \" Payloads\");\n    lv_page_set_sb_mode(payloads_tab, LV_SB_MODE_OFF);\n\n    lv_obj_t*  page = lv_page_create(payloads_tab, NULL);\n    lv_obj_set_size(page, lv_obj_get_width(payloads_tab), 400);\n    lv_obj_align(page, payloads_tab, LV_ALIGN_CENTER, 0, 50);\n    lv_page_set_scrl_width(page, 0);\n    \n    /* Horizontal grid layout */\n    lv_obj_t*  cnr = lv_page_get_scrl(page);\n    lv_cont_set_layout(cnr, LV_LAYOUT_PRETTY);\n    lv_obj_set_size(cnr, LV_HOR_RES_MAX * .95, lv_obj_get_height(page));\n\n    lv_cont_set_style(cnr, \n                    LV_CONT_STYLE_MAIN, \n                    lv_theme_get_argon()->style.panel);\n    render_payloads_entries(cnr, ctxt, payloads, group);\n    \n    gui_menu_pool_push(ctxt->pool, page);\n    gui_menu_pool_push(ctxt->pool, cnr);\n    gui_menu_pool_push(ctxt->pool, payloads_tab);\n    return true;\n}\n\nstatic bool render_payloads_entries(lv_obj_t *par_tabview, argon_ctxt_t *argon_ctxt, char* payloads, u32 group)\n{\n    lv_obj_t *btn = NULL;\n    lv_obj_t *label = NULL;\n    lv_img_dsc_t* img = NULL;\n\n    u32 i = 4 * group;\n    \n    /* Declare styles for payloads */\n    static lv_style_t style_pr;\n    lv_style_copy(&style_pr, &lv_style_plain);\n    style_pr.image.color = LV_COLOR_BLACK;\n    style_pr.image.intense = LV_OPA_50;\n    style_pr.text.color = lv_color_hex3(0xaaa);\n\n    static lv_style_t rel_norm_btn;\n    lv_style_copy(&rel_norm_btn, lv_theme_get_argon()->style.btn.rel);\n    rel_norm_btn.body.padding.inner = 25;\n\n    static lv_style_t pr_norm_btn;\n    lv_style_copy(&pr_norm_btn, lv_theme_get_argon()->style.btn.pr);\n    pr_norm_btn.body.padding.inner = 25;\n\n    static lv_style_t inv_label;\n    lv_style_copy(&inv_label, &lv_style_transp);\n    inv_label.text.font = NULL;\n\n    static lv_style_t no_img_label;\n    lv_style_copy(&no_img_label, &lv_style_plain);\n    no_img_label.text.font = &lv_font_montserrat_alternate_110;\n    no_img_label.text.color = LV_COLOR_WHITE;\n\n    while (payloads[i * 256] && i < 4 * (group + 1))\n    {\n        char payload_path[256];\n        char payload_logo[256];\n        \n        payload_full_path(&payloads[i * 256], payload_path);\n        payload_logo_path(&payloads[i * 256], payload_logo);\n        \n        /* Try to get payload logo */\n        img = bmp_to_lvimg_obj((const char*)payload_logo);\n\n        if (!img)\n        {\n            /* If user has not defined a logo for the payload */\n            btn = lv_btn_create(par_tabview, NULL);\n            lv_obj_set_size(btn, 280, 280);\n            lv_btn_set_style(btn, LV_BTN_STYLE_PR, &pr_norm_btn);\n            lv_btn_set_style(btn, LV_BTN_STYLE_REL, &rel_norm_btn);\n\n            label = lv_label_create(btn, NULL);\n            lv_obj_set_style(label, &no_img_label);\n            lv_label_set_text(label, LV_SYMBOL_ROCKET);\n\n            label = lv_label_create(btn, NULL);\n            lv_label_set_text(label, &payloads[i * 256]);\n        }\n        else\n        {   \n            /* If user has defined a logo */\n            btn = lv_imgbtn_create(par_tabview, NULL);\n            lv_imgbtn_set_style(btn, LV_BTN_STATE_PR, &style_pr);\n            lv_imgbtn_set_src(btn, LV_BTN_STATE_REL, img);\n            lv_imgbtn_set_src(btn, LV_BTN_STATE_PR, img);            \n        }\n        \n        /* Workaround: Payload path as invisible label so later we can get the path on the callback */\n        label = lv_label_create(btn, NULL);\n        lv_label_set_text(label, payload_path);\n        lv_obj_set_style(label, &inv_label);\n        \n        lv_obj_set_event_cb(btn, ctrl_lauch_payload);\n        \n        i++;\n    }\n    \n    gui_menu_pool_push(argon_ctxt->pool, btn);\n    gui_menu_pool_push(argon_ctxt->pool, label);\n\n    return true;\n}\n\n\nstatic bool render_tools_tab(lv_obj_t* par, argon_ctxt_t* ctxt)\n{\n    static lv_style_t labels_style;\n\n    lv_obj_t *settings_tab = lv_tabview_add_tab(par,\n                                                LV_SYMBOL_SETTINGS \" Tools\");\n\n    lv_style_copy(&labels_style, lv_theme_get_current()->style.label.prim);\n    labels_style.text.color = LV_COLOR_WHITE;\n    \n    u32 labels_y = 180;\n\n    lv_obj_t* more_to_come = lv_label_create(settings_tab, NULL);\n    lv_label_set_text(more_to_come, \"More tools comming soon...\");\n    lv_obj_set_pos(more_to_come, LV_HOR_RES_MAX / 2 + 80, LV_VER_RES_MAX / 2 - 20);\n    lv_label_set_style(more_to_come, LV_LABEL_STYLE_MAIN, &labels_style);\n\n    // Power off tools\n    lv_obj_t* power_label = lv_label_create(settings_tab, NULL);\n    lv_label_set_text(power_label, LV_SYMBOL_POWER\" Power tools\");\n    lv_obj_set_pos(power_label, 80, labels_y);\n    lv_label_set_style(power_label, LV_LABEL_STYLE_MAIN, &labels_style);\n\n    lv_obj_t* btn_cont = lv_cont_create(settings_tab, NULL);\n    lv_obj_set_pos(btn_cont, 80, labels_y + 20);\n    lv_obj_set_size(btn_cont, LV_HOR_RES / 2.5, 400);\n    lv_cont_set_layout(btn_cont, LV_LAYOUT_CENTER);\n\n    lv_obj_t *btn = lv_btn_create(btn_cont, NULL);\n    lv_obj_set_size(btn, 220, 80);\n    lv_obj_set_event_cb(btn, ctrl_reboot_rcm);\n\n    lv_obj_t* label = lv_label_create(btn, NULL);\n    lv_label_set_text(label, \"Reboot RCM\");\n\n    btn = lv_btn_create(btn_cont, NULL);\n    lv_obj_set_size(btn, 220, 80);\n    lv_obj_set_event_cb(btn, ctrl_power_off);\n\n    label = lv_label_create(btn, NULL);\n    lv_label_set_text(label, \"Power Off\");\n\n    btn = lv_btn_create(btn_cont, NULL);\n    lv_obj_set_size(btn, 220, 80);\n    lv_obj_set_event_cb(btn, ctrl_reboot_ofw);\n\n    label = lv_label_create(btn, NULL);\n    lv_label_set_text(label, \"Reboot OFW\");\n    \n    lv_obj_t* line = lv_line_create(settings_tab, NULL);\n\n    static lv_point_t line_points[] = { {LV_HOR_RES_MAX / 2., 200}, {LV_HOR_RES_MAX / 2., LV_VER_RES_MAX - 100} };\n    lv_line_set_points(line, line_points, 2);\n    lv_line_set_style(line, LV_LINE_STYLE_MAIN, lv_theme_get_current()->style.line.decor);\n    \n    gui_menu_pool_push(ctxt->pool, settings_tab);\n    gui_menu_pool_push(ctxt->pool, power_label);\n    gui_menu_pool_push(ctxt->pool, btn_cont);\n    gui_menu_pool_push(ctxt->pool, btn);\n    gui_menu_pool_push(ctxt->pool, label);\n    gui_menu_pool_push(ctxt->pool, line);\n\n    return true;\n}\n\nstatic bool render_title(argon_ctxt_t * ctxt)\n{\n    lv_obj_t* title = lv_label_create(lv_scr_act(), NULL);\n    lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 50);\n    lv_label_set_text(title, \"Arg\"LV_SYMBOL_METEOR\"nnx\");\n    lv_obj_set_auto_realign(title, true);\n    \n    static lv_style_t label_style;\n    lv_style_copy(&label_style, &lv_style_plain);\n    label_style.text.color = LV_COLOR_WHITE;\n    label_style.text.font = &lv_font_montserrat_alternate_110;\n    lv_obj_set_style(title, &label_style);\n\n    gui_menu_pool_push(ctxt->pool, title);\n    return true;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/menu/gui/gui_menu_controllers.c",
    "content": "#include \"menu/gui/gui_menu_controllers.h\"\n#include \"utils/util.h\"\n#include \"menu/gui/gui_menu_pool.h\"\n#include \"core/launcher.h\"\n\nvoid ctrl_reboot_rcm(lv_obj_t *obj, lv_event_t event)\n{\n    if (event == LV_EVENT_CLICKED)\n    {\n        argon_ctxt_destroy(g_argon_ctxt);\n        reboot_rcm();\n    }\n}\n\nvoid ctrl_reboot_ofw(lv_obj_t *obj, lv_event_t event)\n{\n    if (event == LV_EVENT_CLICKED)\n    {\n        argon_ctxt_destroy(g_argon_ctxt);\n        reboot_normal();\n    }\n}\n\nvoid ctrl_power_off(lv_obj_t *obj, lv_event_t event)\n{\n    if (event == LV_EVENT_CLICKED)\n    {\n        argon_ctxt_destroy(g_argon_ctxt);\n        power_off();\n    }\n}\n\nvoid ctrl_lauch_payload(lv_obj_t *obj, lv_event_t event)\n{\n    if (event == LV_EVENT_CLICKED)\n    {\n        lv_obj_t label = lv_obj_get_child(obj, NULL)[0];\n        char* path = lv_label_get_text(&label);\n        launch_payload(g_argon_ctxt, path);\n    }\n}\n"
  },
  {
    "path": "argon-nx-gui/src/menu/gui/gui_menu_pool.c",
    "content": "/*  \n * Copyright (c) 2018 Guillem96\n *\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n#include \"menu/gui/gui_menu_pool.h\"\n#include \"mem/heap.h\"\n\nvoid gui_menu_pool_init(gui_menu_pool_t* pool)\n{\n    pool->max_items = 0x16;\n    pool->current_items = 0;\n    pool->menus = (lv_obj_t **)malloc(sizeof(lv_obj_t *) * pool->max_items);\n}\n\nvoid gui_menu_pool_push(gui_menu_pool_t* pool, lv_obj_t *obj)\n{\n    if (obj != NULL)\n    {\n        if (pool->current_items == pool->max_items - 1)\n        {\n            // Resize the pool\n            u32 new_size = pool->max_items << 1;\n            pool->menus = (lv_obj_t **)m_realloc(pool->menus, sizeof(lv_obj_t *) * pool->max_items, new_size);\n            pool->max_items = new_size;\n        }\n        pool->menus[pool->current_items] = obj;\n        pool->current_items++;\n    }\n}\n\nvoid gui_menu_pool_cleanup(gui_menu_pool_t* pool)\n{\n    for (int i = 0; i < pool->current_items; ++i)\n        free(pool->menus[i]);\n    free(pool->menus);\n    free(pool);\n}"
  },
  {
    "path": "argon-nx-gui/src/minerva/minerva.c",
    "content": "#include \"minerva/minerva.h\"\n\n#include \"utils/types.h\"\n#include \"utils/util.h\"\n#include \"utils/fs_utils.h\"\n\n#include \"soc/fuse.h\"\n#include \"soc/t210.h\"\n#include \"soc/clock.h\"\n\n#include \"gfx/gfx.h\"\n\n#include \"mem/sdram.h\"\n\n#include \"ianos/ianos.h\"\n\n\nvoid minerva(mtc_config_t *mtc_cfg)\n{\n    /* Mount sd card */\n    if (!sd_mount())\n    {\n        gfx_printf(\"Error mounting sd card\\n\");\n        return;\n    }\n\n    gfx_printf(\"-- Minerva Training Cell --\\n\");\n    \n    // Set table to ram.\n    mtc_cfg->mtc_table = NULL;\n    mtc_cfg->sdram_id = (fuse_read_odm(4) >> 3) & 0x1F;\n    u32 ep_addr = ianos_loader(false, \"argon/sys/minerva.bso\", DRAM_LIB, (void *)mtc_cfg);\n    minerva_cfg = (void *)ep_addr;\n\n    if (!minerva_cfg)\n    {\n        gfx_printf(\"Abort Minerva Training Cell\\n\");\n        return;\n    }\n\n    gfx_printf(\"Starting training process.. \\n\");\n\n\n    u32 curr_ram_idx;\n    for (curr_ram_idx = 0; curr_ram_idx < 10; curr_ram_idx++)\n\t{\n\t\tif (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) == mtc_cfg->mtc_table[curr_ram_idx].clk_src_emc)\n\t\t\tbreak;\n\t}\n\n    mtc_cfg->rate_from = mtc_cfg->mtc_table[curr_ram_idx].rate_khz;\n    mtc_cfg->rate_to = 204000;\n    mtc_cfg->train_mode = OP_TRAIN;\n    minerva_cfg(mtc_cfg, NULL);\n    mtc_cfg->rate_to = 800000;\n    minerva_cfg(mtc_cfg, NULL);\n    mtc_cfg->rate_to = 1600000;\n    minerva_cfg(mtc_cfg, NULL);\n    gfx_printf(\"-- Finished Minerva Training Cell --\\n\");\n}\n\nvoid minerva_change_freq(mtc_config_t *mtc_cfg, minerva_freq_t freq)\n{\n\tif (!minerva_cfg)\n\t\treturn;\n\n\tif (minerva_cfg && (mtc_cfg->rate_from != freq))\n\t{\n\t\tmtc_cfg->rate_to = freq;\n\t\tmtc_cfg->train_mode = OP_SWITCH;\n\t\tminerva_cfg(mtc_cfg, NULL);\n\t}\n}\n\nvoid minerva_periodic_training(lv_task_t * task)\n{\n    mtc_config_t* mtc_cfg = task->user_data;\n\n    if (minerva_cfg && mtc_cfg->rate_from == FREQ_1600)\n    {\n        mtc_cfg->train_mode = OP_PERIODIC_TRAIN;\n        minerva_cfg(mtc_cfg, NULL);\n    }\n}"
  },
  {
    "path": "argon-nx-gui/src/power/battery.c",
    "content": "/*\n * Battery charger driver for Nintendo Switch's TI BQ24193\n *\n * Copyright (C) 2018 CTCaer\n * Copyright (C) 2019 Guillem96\n * \n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"power/battery.h\"\n#include \"power/bq24193.h\"\n#include \"power/max17050.h\"\n#include \"utils/types.h\"\n\n\nvoid battery_get_status(battery_status_t* battery_status)\n{\n    battery_status->charge_status = battery_charge_status();\n    battery_percent((int*)&(battery_status->percent));\n    battery_status->percent = (battery_status->percent >> 8) & 0xFF;\n}\n\ncharge_status_t battery_charge_status()\n{\n    int value = 0;\n\n    bq24193_get_property(BQ24193_ChargeStatus, &value);\n\tswitch (value)\n\t{\n\tcase 0:\n        return NOT_CHARGING; \n\tcase 1:\n\t\treturn CHARGING;\n\tcase 2:\n\t\treturn FAST_CHARGING;\n\tcase 3:\n\t\treturn TERMINATED;\n\tdefault:\n\t\treturn UNKNOWN;\n    }\n}\n\nvoid battery_percent(int* percent) \n{\n    max17050_get_property(MAX17050_RepSOC, percent);\n}\n\nconst char* battery_str_charge_status(charge_status_t charge_status)\n{\n    const char *values[] = \n    { \n        \"Not Charging\", \n        \"Charging\", \n        \"Fast Charging\", \n        \"Full\",\n        \"Unknown\"\n    };\n\n    return values[charge_status];\n}\n"
  },
  {
    "path": "argon-nx-gui/src/power/bq24193.c",
    "content": "/*\n * Battery charger driver for Nintendo Switch's TI BQ24193\n *\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"power/bq24193.h\"\n#include \"soc/i2c.h\"\n#include \"utils/util.h\"\n\nint bq24193_get_property(enum BQ24193_reg_prop prop, int *value)\n{\n\tu8 data;\n\n\tswitch (prop) {\n\t\tcase BQ24193_InputVoltageLimit: // Input voltage limit (mV).\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_InputSource);\n\t\t\tdata = (data & BQ24193_INCONFIG_VINDPM_MASK) >> 3;\n\t\t\t*value += ((data >> 0) & 1) ? 80 : 0;\n\t\t\t*value += ((data >> 1) & 1) ? 160 : 0;\n\t\t\t*value += ((data >> 2) & 1) ? 320 : 0;\n\t\t\t*value += ((data >> 3) & 1) ? 640 : 0;\n\t\t\t*value += 3880;\n\t\t\tbreak;\n\t\tcase BQ24193_InputCurrentLimit: // Input current limit (mA).\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_InputSource);\n\t\t\tdata &= BQ24193_INCONFIG_INLIMIT_MASK;\n\t\t\tswitch (data)\n\t\t\t{\n\t\t\tcase 0:\n\t\t\t\t*value = 100;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\t*value = 150;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\t*value = 500;\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\t*value = 900;\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\t*value = 1200;\n\t\t\t\tbreak;\n\t\t\tcase 5:\n\t\t\t\t*value = 1500;\n\t\t\t\tbreak;\n\t\t\tcase 6:\n\t\t\t\t*value = 2000;\n\t\t\t\tbreak;\n\t\t\tcase 7:\n\t\t\t\t*value = 3000;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase BQ24193_SystemMinimumVoltage: // Minimum system voltage limit (mV).\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_PORConfig);\n\t\t\t*value = (data & BQ24193_PORCONFIG_SYSMIN_MASK) >> 1;\n\t\t\t*value *= 100;\n\t\t\t*value += 3000;\n\t\t\tbreak;\n\t\tcase BQ24193_FastChargeCurrentLimit: // Fast charge current limit (mA).\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgCurr);\n\t\t\tdata = (data & BQ24193_CHRGCURR_ICHG_MASK) >> 2;\n\t\t\t*value += ((data >> 0) & 1) ? 64 : 0;\n\t\t\t*value += ((data >> 1) & 1) ? 128 : 0;\n\t\t\t*value += ((data >> 2) & 1) ? 256 : 0;\n\t\t\t*value += ((data >> 3) & 1) ? 512 : 0;\n\t\t\t*value += ((data >> 4) & 1) ? 1024 : 0;\n\t\t\t*value += ((data >> 5) & 1) ? 2048 : 0;\n\t\t\t*value += 512;\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgCurr);\n\t\t\tdata &= BQ24193_CHRGCURR_20PCT_MASK;\n\t\t\tif (data)\n\t\t\t\t*value = *value * 20 / 100; // Fast charge current limit is 20%.\n\t\t\tbreak;\n\t\tcase BQ24193_ChargeVoltageLimit: // Charge voltage limit (mV).\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgVolt);\n\t\t\tdata = (data & BQ24193_CHRGVOLT_VREG) >> 2; \n\t\t\t*value += ((data >> 0) & 1) ? 16 : 0;\n\t\t\t*value += ((data >> 1) & 1) ? 32 : 0;\n\t\t\t*value += ((data >> 2) & 1) ? 64 : 0;\n\t\t\t*value += ((data >> 3) & 1) ? 128 : 0;\n\t\t\t*value += ((data >> 4) & 1) ? 256 : 0;\n\t\t\t*value += ((data >> 5) & 1) ? 512 : 0;\n\t\t\t*value += 3504;\n\t\t\tbreak;\n\t\tcase BQ24193_RechargeThreshold: // Recharge voltage threshold less than voltage limit (mV).\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgVolt);\n\t\t\tdata &= BQ24193_IRTHERMAL_THERM_MASK;\n\t\t\tif (data)\n\t\t\t\t*value = 300;\n\t\t\telse\n\t\t\t\t*value = 100;\n\t\t\tbreak;\n\t\tcase BQ24193_ThermalRegulation: // Thermal regulation threshold (oC).\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_IRCompThermal);\n\t\t\tdata &= BQ24193_IRTHERMAL_THERM_MASK;\n\t\t\tswitch (data)\n\t\t\t{\n\t\t\tcase 0:\n\t\t\t\t*value = 60;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\t*value = 80;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\t*value = 100;\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\t*value = 120;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase BQ24193_ChargeStatus: // 0: Not charging, 1: Pre-charge, 2: Fast charging, 3: Charge termination done\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_Status);\n\t\t\t*value = (data & BQ24193_STATUS_CHRG_MASK) >> 4;\n\t\t\tbreak;\n\t\tcase BQ24193_TempStatus: // 0: Normal, 2: Warm, 3: Cool, 5: Cold, 6: Hot.\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_FaultReg);\n\t\t\t*value = data & BQ24193_FAULT_THERM_MASK;\n\t\t\tbreak;\n\t\tcase BQ24193_DevID: // Dev ID.\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_VendorPart);\n\t\t\t*value = data & BQ24193_VENDORPART_DEV_MASK;\n\t\t\tbreak;\n\t\tcase BQ24193_ProductNumber: // Product number.\n\t\t\tdata = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_VendorPart);\n\t\t\t*value = (data & BQ24193_VENDORPART_PN_MASK) >> 3;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nvoid bq24193_fake_battery_removal()\n{\n\tu8  value;\n\n\t// Disable watchdog to keep BATFET disabled.\n\tvalue = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgTermTimer);\n\tvalue &= ~BQ24193_CHRGTERM_WATCHDOG_MASK;\n\ti2c_send_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgTermTimer, value);\n\n\t// Force BATFET to disabled state. This disconnects the battery from the system.\n\tvalue = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_Misc);\n\tvalue |= BQ24193_MISC_BATFET_DI_MASK;\n\ti2c_send_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_Misc, value);\n}"
  },
  {
    "path": "argon-nx-gui/src/power/max17050.c",
    "content": "/*\n * Fuel gauge driver for Nintendo Switch's Maxim 17050\n *\n * Copyright (C) 2011 Samsung Electronics\n * MyungJoo Ham <myungjoo.ham@samsung.com>\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n *\n * This driver is based on max17040_battery.c\n */\n\n#include \"power/max17050.h\"\n#include \"soc/i2c.h\"\n#include \"utils/util.h\"\n\n/* Status register bits */\n#define STATUS_POR_BIT (1 << 1)\n#define STATUS_BST_BIT (1 << 3)\n#define STATUS_VMN_BIT (1 << 8)\n#define STATUS_TMN_BIT (1 << 9)\n#define STATUS_SMN_BIT (1 << 10)\n#define STATUS_BI_BIT  (1 << 11)\n#define STATUS_VMX_BIT (1 << 12)\n#define STATUS_TMX_BIT (1 << 13)\n#define STATUS_SMX_BIT (1 << 14)\n#define STATUS_BR_BIT  (1 << 15)\n\n#define VFSOC0_LOCK   0x0000\n#define VFSOC0_UNLOCK 0x0080\n\n#define MAX17050_VMAX_TOLERANCE 50 /* 50 mV */\n\nint max17050_get_property(enum MAX17050_reg reg, int *value)\n{\n\tu16 data;\n\n\tswitch (reg)\n\t{\n\tcase MAX17050_Age: // Age (percent). Based on 100% x (FullCAP Register/DesignCap).\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_Age);\n\t\t*value = data >> 8; /* Show MSB. 1% increments */\n\t\tbreak;\n\tcase MAX17050_Cycles: // Cycle count.\n\t\ti2c_recv_buf_small((u8 *)value, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_Cycles);\n\t\tbreak;\n\tcase MAX17050_MinVolt: // Voltage max/min\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MinMaxVolt);\n\t\t*value = (data & 0xff) * 20; /* Voltage MIN. Units of 20mV */\n\t\tbreak;\n\tcase MAX17050_MaxVolt: // Voltage max/min\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MinMaxVolt);\n\t\t*value = (data >> 8) * 20; /* Voltage MAX. Units of LSB = 20mV */\n\t\tbreak;\n\tcase MAX17050_V_empty: // Voltage min design.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_V_empty);\n\t\t*value = (data >> 7) * 10; /* Units of LSB = 10mV */\n\t\tbreak;\n\tcase MAX17050_VCELL: // Voltage now.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_VCELL);\n\t\t*value = data * 625 / 8 / 1000;\n\t\tbreak;\n\tcase MAX17050_AvgVCELL: // Voltage avg.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_AvgVCELL);\n\t\t*value = data * 625 / 8 / 1000;\n\t\tbreak;\n\tcase MAX17050_OCVInternal: // Voltage ocv.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_OCVInternal);\n\t\t*value = data * 625 / 8 / 1000;\n\t\tbreak;\n\tcase MAX17050_RepSOC: // Capacity %.\n\t\ti2c_recv_buf_small((u8 *)value, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_RepSOC);\n\t\tbreak;\n\tcase MAX17050_DesignCap: // Charge full design.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_DesignCap);\n\t\tdata = data * 5 / 10;\n\t\t*value = data;\n\t\tbreak;\n\tcase MAX17050_FullCAP: // Charge full.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_FullCAP);\n\t\tdata = data * 5 / 10;\n\t\t*value = data;\n\t\tbreak;\n\tcase MAX17050_RepCap: // Charge now.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_RepCap);\n\t\tdata = data * 5 / 10;\n\t\t*value = data;\n\t\tbreak;\n\tcase MAX17050_TEMP: // Temp.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_TEMP);\n\t\t*value = (s16)data;\n\t\t*value = *value * 10 / 256;\n\t\tbreak;\n\tcase MAX17050_Current: // Current now.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_Current);\n\t\t*value = (s16)data;\n\t\t*value *= 1562500 / MAX17050_DEFAULT_SNS_RESISTOR;\n\t\tbreak;\n\tcase MAX17050_AvgCurrent: // Current avg.\n\t\ti2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_AvgCurrent);\n\t\t*value = (s16)data;\n\t\t*value *= 1562500 / MAX17050_DEFAULT_SNS_RESISTOR;\n\t\tbreak;\n\tdefault:\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nstatic int _max17050_write_verify_reg(u8 reg, u16 value)\n{\n\tint retries = 8;\n\tint ret;\n\tu16 read_value;\n\n\tdo\n\t{\n\t\tret = i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, reg, (u8 *)&value, 2);\n\t\ti2c_recv_buf_small((u8 *)&read_value, 2, I2C_1, MAXIM17050_I2C_ADDR, reg);\n\t\tif (read_value != value)\n\t\t{\n\t\t\tret = -1;\n\t\t\tretries--;\n\t\t}\n\t} while (retries && read_value != value);\n\n\treturn ret;\n}\n\nstatic void _max17050_override_por(u8 reg, u16 value)\n{\n\tif (value)\n\t\ti2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, reg, (u8 *)&value, 2);\n}\n\nstatic void _max17050_load_new_capacity_params()\n{\n\tu16 fullcap, repSoc, dq_acc, dp_acc;\n\n\tfullcap = 0x2476; // 4667mAh design capacity.\n\tdq_acc = 0x10bc;  // From a healthy fuel gauge.\n\tdp_acc = 0x5e09;  //          =||=\n\trepSoc = 0x6400;  // 100%.\n\n\t_max17050_write_verify_reg(MAX17050_RemCap, fullcap);\n\t_max17050_write_verify_reg(MAX17050_RepCap, fullcap);\n\n\t_max17050_write_verify_reg(MAX17050_dQacc, dq_acc);\n\t_max17050_write_verify_reg(MAX17050_dPacc, dp_acc);\n\n\t_max17050_write_verify_reg(MAX17050_FullCAP, fullcap);\n\t//i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_DesignCap, (u8 *)&fullcap, 2);\n\t_max17050_write_verify_reg(MAX17050_FullCAPNom, fullcap);\n\t/* Update SOC register with new SOC */\n\ti2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_RepSOC, (u8 *)&repSoc, 2);\n}\n\nstatic void _max17050_reset_vfsoc0_reg()\n{\n\tu16 lockVal = 0;\n\tu16 vfSoc = 0x6440; // >100% for fully charged battery\n\n\tlockVal = VFSOC0_UNLOCK;\n\ti2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_VFSOC0Enable, (u8 *)&lockVal, 2);\n\n\t_max17050_write_verify_reg(MAX17050_VFSOC0, vfSoc);\n\n\tlockVal = VFSOC0_LOCK;\n\ti2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_VFSOC0Enable, (u8 *)&lockVal, 2);\n}\n\nstatic void _max17050_update_capacity_regs()\n{\n\tu16 value = 0x2476; // Set to 4667mAh design capacity.\n\t_max17050_write_verify_reg(MAX17050_FullCAP, value);\n\t_max17050_write_verify_reg(MAX17050_FullCAPNom, value);\n\t//i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_DesignCap, config->design_cap, 2);\n}\n\nstatic void _max17050_write_config_regs()\n{\n\tu16 value = 0;\n\n\tvalue = 0x7254;\n\ti2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_CONFIG, (u8 *)&value, 2);\n\tvalue = 0x2473;\n\ti2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_LearnCFG, (u8 *)&value, 2);\n\t//i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_FilterCFG, (u8 *)&value, 2)\n\t//i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_RelaxCFG, (u8 *)&value, 2)\n\t//i2c_send_buf_small(I2C_1, MAXIM17050_I2C_ADDR, MAX17050_FullSOCThr, (u8 *)&value, 2)\n}\n\n/*\n * Block write all the override values coming from platform data.\n * This function MUST be called before the POR initialization proceedure\n * specified by maxim.\n */\nstatic void _max17050_override_por_values()\n{\n\tu16 dq_acc = 0x10bc; // From a healthy fuel gauge.\n\tu16 dp_acc = 0x5e09; //           =||=\n\n\t_max17050_override_por(MAX17050_dQacc, dq_acc);\n\t_max17050_override_por(MAX17050_dPacc, dp_acc);\n\n\t//_max17050_override_por(MAX17050_RCOMP0, config->rcomp0);  //0x58\n\t//_max17050_override_por(MAX17050_TempCo, config->tcompc0); //0x1b22\n\n\t//u16 k_empty0 = 0x439;\n\t//_max17050_override_por(map, MAX17050_K_empty0, k_empty0); // Unknown cell data\n}\n\nstatic void _max17050_set_por_bit(u16 value)\n{\n\t_max17050_write_verify_reg(MAX17050_STATUS, value);\n}\n\nint max17050_fix_configuration()\n{\n\t/* Init phase, set the POR bit */\n\t_max17050_set_por_bit(STATUS_POR_BIT);\n\n\t/* Override POR values */\n\t_max17050_override_por_values();\n\t/* After Power up, the MAX17050 requires 500ms in order\n\t * to perform signal debouncing and initial SOC reporting\n\t */\n\tmsleep(500);\n\n\t/* Initialize configaration */\n\t_max17050_write_config_regs();\n\n\t/* update capacity params */\n\t_max17050_update_capacity_regs();\n\n\t/* delay must be atleast 350mS to allow VFSOC\n\t * to be calculated from the new configuration\n\t */\n\tmsleep(350);\n\n\t/* reset vfsoc0 reg */\n\t_max17050_reset_vfsoc0_reg();\n\n\t/* load new capacity params */\n\t_max17050_load_new_capacity_params();\n\n\t/* Init complete, Clear the POR bit */\n\t//_max17050_set_por_bit(0); // Should we? Or let the switch to reconfigure POR?\n\n\t// Sets POR, BI, BR. \n\t_max17050_set_por_bit(0x8801);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/power/max7762x.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2019 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"power/max7762x.h\"\n#include \"power/max77620.h\"\n#include \"soc/i2c.h\"\n#include \"utils/util.h\"\n\n#define REGULATOR_SD 0\n#define REGULATOR_LDO 1\n\ntypedef struct _max77620_regulator_t\n{\n\tu8 type;\n\tconst char *name;\n\tu8 reg_sd;\n\n\tu32 mv_step;\n\tu32 mv_min;\n\tu32 mv_default;\n\tu32 mv_max;\n\n\tu8 volt_addr;\n\tu8 cfg_addr;\n\n\tu8 volt_mask;\n\tu8 enable_mask;\n\tu8 enable_shift;\n\tu8 status_mask;\n\n\tu8 fps_addr;\n\tu8 fps_src;\n\tu8 pd_period;\n\tu8 pu_period;\n} max77620_regulator_t;\n\nstatic const max77620_regulator_t _pmic_regulators[] = {\n\t{  REGULATOR_SD,  \"sd0\", 0x16,  12500, 600000,  625000, 1400000,      MAX77620_REG_SD0,   MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK,  MAX77620_SD_POWER_MODE_SHIFT,  0x80,  MAX77620_REG_FPS_SD0,  1, 7, 1 },\n\t{  REGULATOR_SD,  \"sd1\", 0x17,  12500, 600000, 1125000, 1125000,      MAX77620_REG_SD1,   MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK,  MAX77620_SD_POWER_MODE_SHIFT,  0x40,  MAX77620_REG_FPS_SD1,  0, 1, 5 },\n\t{  REGULATOR_SD,  \"sd2\", 0x18,  12500, 600000, 1325000, 1350000,      MAX77620_REG_SD2,   MAX77620_REG_SD2_CFG, MAX77620_SDX_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK,  MAX77620_SD_POWER_MODE_SHIFT,  0x20,  MAX77620_REG_FPS_SD2,  1, 5, 2 },\n\t{  REGULATOR_SD,  \"sd3\", 0x19,  12500, 600000, 1800000, 1800000,      MAX77620_REG_SD3,   MAX77620_REG_SD3_CFG, MAX77620_SDX_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK,  MAX77620_SD_POWER_MODE_SHIFT,  0x10,  MAX77620_REG_FPS_SD3,  0, 3, 3 },\n\t{ REGULATOR_LDO, \"ldo0\", 0x00,  25000, 800000, 1200000, 1200000, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO0, 3, 7, 0 },\n\t{ REGULATOR_LDO, \"ldo1\", 0x00,  25000, 800000, 1050000, 1050000, MAX77620_REG_LDO1_CFG, MAX77620_REG_LDO1_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO1, 3, 7, 0 },\n\t{ REGULATOR_LDO, \"ldo2\", 0x00,  50000, 800000, 1800000, 3300000, MAX77620_REG_LDO2_CFG, MAX77620_REG_LDO2_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO2, 3, 7, 0 },\n\t{ REGULATOR_LDO, \"ldo3\", 0x00,  50000, 800000, 3100000, 3100000, MAX77620_REG_LDO3_CFG, MAX77620_REG_LDO3_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO3, 3, 7, 0 },\n\t{ REGULATOR_LDO, \"ldo4\", 0x00,  12500, 800000,  850000,  850000, MAX77620_REG_LDO4_CFG, MAX77620_REG_LDO4_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO4, 0, 7, 1 },\n\t{ REGULATOR_LDO, \"ldo5\", 0x00,  50000, 800000, 1800000, 1800000, MAX77620_REG_LDO5_CFG, MAX77620_REG_LDO5_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO5, 3, 7, 0 },\n\t{ REGULATOR_LDO, \"ldo6\", 0x00,  50000, 800000, 2900000, 2900000, MAX77620_REG_LDO6_CFG, MAX77620_REG_LDO6_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO6, 3, 7, 0 },\n\t{ REGULATOR_LDO, \"ldo7\", 0x00,  50000, 800000, 1050000, 1050000, MAX77620_REG_LDO7_CFG, MAX77620_REG_LDO7_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO7, 1, 4, 3 },\n\t{ REGULATOR_LDO, \"ldo8\", 0x00,  50000, 800000, 1050000, 1050000, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00,  MAX77620_REG_FPS_LDO8, 3, 7, 0 }\n};\n\nint max77620_regulator_get_status(u32 id)\n{\n\tif (id > REGULATOR_MAX)\n\t\treturn 0;\n\n\tconst max77620_regulator_t *reg = &_pmic_regulators[id];\n\n\tif (reg->type == REGULATOR_SD)\n\t\treturn (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_STATSD) & reg->status_mask) ? 0 : 1;\n\treturn (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg->cfg_addr) & 8) ? 1 : 0;\n}\n\nint max77620_regulator_config_fps(u32 id)\n{\n\tif (id > REGULATOR_MAX)\n\t\treturn 0;\n\n\tconst max77620_regulator_t *reg = &_pmic_regulators[id];\n\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->fps_addr,\n\t\t(reg->fps_src << MAX77620_FPS_SRC_SHIFT) | (reg->pu_period << MAX77620_FPS_PU_PERIOD_SHIFT) | (reg->pd_period));\n\n\treturn 1;\n}\n\nint max77620_regulator_set_voltage(u32 id, u32 mv)\n{\n\tif (id > REGULATOR_MAX)\n\t\treturn 0;\n\n\tconst max77620_regulator_t *reg = &_pmic_regulators[id];\n\n\tif (mv < reg->mv_min || mv > reg->mv_max)\n\t\treturn 0;\n\n\tu32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;\n\tu8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr);\n\tval = (val & ~reg->volt_mask) | (mult & reg->volt_mask);\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr, val);\n\tusleep(1000);\n\n\treturn 1;\n}\n\nint max77620_regulator_enable(u32 id, int enable)\n{\n\tif (id > REGULATOR_MAX)\n\t\treturn 0;\n\n\tconst max77620_regulator_t *reg = &_pmic_regulators[id];\n\n\tu32 addr = reg->type == REGULATOR_SD ? reg->cfg_addr : reg->volt_addr;\n\tu8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, addr);\n\tif (enable)\n\t\tval = (val & ~reg->enable_mask) | ((MAX77620_POWER_MODE_NORMAL << reg->enable_shift) & reg->enable_mask);\n\telse\n\t\tval &= ~reg->enable_mask;\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, addr, val);\n\tusleep(1000);\n\n\treturn 1;\n}\n\nint max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags)\n{\n\tif (id > REGULATOR_MAX)\n\t\treturn 0;\n\n\tconst max77620_regulator_t *reg = &_pmic_regulators[id];\n\n\tif (mv < reg->mv_min || mv > reg->mv_max)\n\t\treturn 0;\n\n\tu32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;\n\tu8 val = ((flags << reg->enable_shift) & ~reg->volt_mask) | (mult & reg->volt_mask);\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr, val);\n\tusleep(1000);\n\n\treturn 1;\n}\n\nvoid max77620_config_default()\n{\n\tfor (u32 i = 1; i <= REGULATOR_MAX; i++)\n\t{\n\t\ti2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CID4);\n\t\tmax77620_regulator_config_fps(i);\n\t\tmax77620_regulator_set_voltage(i, _pmic_regulators[i].mv_default);\n\t\tif (_pmic_regulators[i].fps_src != MAX77620_FPS_SRC_NONE)\n\t\t\tmax77620_regulator_enable(i, 1);\n\t}\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, 4);\n}\n\nvoid max77620_low_battery_monitor_config()\n{\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGGLBL1,\n\t\tMAX77620_CNFGGLBL1_LBDAC_EN | MAX77620_CNFGGLBL1_LBHYST_N | MAX77620_CNFGGLBL1_LBDAC_N);\n}\n"
  },
  {
    "path": "argon-nx-gui/src/sec/se.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 CTCaer\n * Copyright (c) 2018 Atmosphère-NX\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"sec/se.h\"\n#include \"mem/heap.h\"\n#include \"soc/t210.h\"\n#include \"sec/se_t210.h\"\n#include \"utils/util.h\"\n\ntypedef struct _se_ll_t\n{\n\tvu32 num;\n\tvu32 addr;\n\tvu32 size;\n} se_ll_t;\n\nstatic void _gf256_mul_x(void *block)\n{\n\tu8 *pdata = (u8 *)block;\n\tu32 carry = 0;\n\n\tfor (u32 i = 0xF; i >= 0; i--)\n\t{\n\t\tu8 b = pdata[i];\n\t\tpdata[i] = (b << 1) | carry;\n\t\tcarry = b >> 7;\n\t}\n\n\tif (carry)\n\t\tpdata[0xF] ^= 0x87;\n}\n\nstatic void _se_ll_init(se_ll_t *ll, u32 addr, u32 size)\n{\n\tll->num = 0;\n\tll->addr = addr;\n\tll->size = size;\n}\n\nstatic void _se_ll_set(se_ll_t *dst, se_ll_t *src)\n{\n\tSE(SE_IN_LL_ADDR_REG_OFFSET) = (u32)src;\n\tSE(SE_OUT_LL_ADDR_REG_OFFSET) = (u32)dst;\n}\n\nstatic int _se_wait()\n{\n\twhile (!(SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_OP_DONE(INT_SET)))\n\t\t;\n\tif (SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_ERROR(INT_SET) ||\n\t\tSE(SE_STATUS_0) & 3 ||\n\t\tSE(SE_ERR_STATUS_0) != 0)\n\t\treturn 0;\n\treturn 1;\n}\n\nstatic int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size)\n{\n\tse_ll_t *ll_dst = NULL, *ll_src = NULL;\n\n\tif (dst)\n\t{\n\t\tll_dst = (se_ll_t *)malloc(sizeof(se_ll_t));\n\t\t_se_ll_init(ll_dst, (u32)dst, dst_size);\n\t}\n\n\tif (src)\n\t{\n\t\tll_src = (se_ll_t *)malloc(sizeof(se_ll_t));\n\t\t_se_ll_init(ll_src, (u32)src, src_size);\n\t}\n\n\t_se_ll_set(ll_dst, ll_src);\n\n\tSE(SE_ERR_STATUS_0) = SE(SE_ERR_STATUS_0);\n\tSE(SE_INT_STATUS_REG_OFFSET) = SE(SE_INT_STATUS_REG_OFFSET);\n\tSE(SE_OPERATION_REG_OFFSET) = SE_OPERATION(op);\n\n\tint res = _se_wait();\n\n\tif (src)\n\t\tfree(ll_src);\n\tif (dst)\n\t\tfree(ll_dst);\n\n\treturn res;\n}\n\nstatic int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size)\n{\n\tif (!src || !dst)\n\t\treturn 0;\n\n\tu8 *block = (u8 *)malloc(0x10);\n\tmemset(block, 0, 0x10);\n\n\tSE(SE_BLOCK_COUNT_REG_OFFSET) = 0;\n\n\tmemcpy(block, src, src_size);\n\tint res = _se_execute(op, block, 0x10, block, 0x10);\n\tmemcpy(dst, block, dst_size);\n\t\n\tfree(block);\n\treturn res;\n}\n\nstatic void _se_aes_ctr_set(void *ctr)\n{\n\tu32 *data = (u32 *)ctr;\n\tfor (u32 i = 0; i < 4; i++)\n\t\tSE(SE_CRYPTO_CTR_REG_OFFSET + 4 * i) = data[i];\n}\n\nvoid se_rsa_acc_ctrl(u32 rs, u32 flags)\n{\n\tif (flags & 0x7F)\n\t\tSE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + 4 * rs) = (((flags >> 4) & 4) | (flags & 3)) ^ 7;\n\tif (flags & 0x80)\n\t\tSE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~(1 << rs);\n}\n\nvoid se_key_acc_ctrl(u32 ks, u32 flags)\n{\n\tif (flags & 0x7F)\n\t\tSE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks) = ~flags;\n\tif (flags & 0x80)\n\t\tSE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~(1 << ks);\n}\n\nvoid se_aes_key_set(u32 ks, void *key, u32 size)\n{\n\tu32 *data = (u32 *)key;\n\tfor (u32 i = 0; i < size / 4; i++)\n\t{\n\t\tSE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;\n\t\tSE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i];\n\t}\n}\n\nvoid se_aes_key_clear(u32 ks)\n{\n\tfor (u32 i = 0; i < TEGRA_SE_AES_MAX_KEY_SIZE / 4; i++)\n\t{\n\t\tSE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;\n\t\tSE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0;\n\t}\n}\n\nint se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)\n{\n\tSE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTAB);\n\tSE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);\n\tSE(SE_BLOCK_COUNT_REG_OFFSET) = 0;\n\tSE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst);\n\n\treturn _se_execute(OP_START, NULL, 0, input, 0x10);\n}\n\nint se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src)\n{\n\tif (enc)\n\t{\n\t\tSE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);\n\t\tSE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);\n\t}\n\telse\n\t{\n\t\tSE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);\n\t\tSE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);\n\t}\n\tSE(SE_BLOCK_COUNT_REG_OFFSET) = 0;\n\treturn _se_execute(OP_START, dst, 0x10, src, 0x10);\n}\n\nint se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr)\n{\n\tSE(SE_SPARE_0_REG_OFFSET) = 1;\n\tSE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);\n\tSE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) |\n\t\tSE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) | SE_CRYPTO_CTR_VAL(1);\n\t_se_aes_ctr_set(ctr);\n\n\tu32 src_size_aligned = src_size & 0xFFFFFFF0;\n\tu32 src_size_delta = src_size & 0xF;\n\n\tif (src_size_aligned)\n\t{\n\t\tSE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;\n\t\tif (!_se_execute(OP_START, dst, dst_size, src, src_size_aligned))\n\t\t\treturn 0;\n\t}\n\n\tif (src_size - src_size_aligned && src_size_aligned < dst_size)\n\t\treturn _se_execute_one_block(OP_START, dst + src_size_aligned,\n\t\t\tMIN(src_size_delta, dst_size - src_size_aligned),\n\t\t\tsrc + src_size_aligned, src_size_delta);\n\n\treturn 1;\n}\n\nint se_aes_xts_crypt_sec(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *src, u32 secsize)\n{\n\tint res = 0;\n\tu8 *tweak = (u8 *)malloc(0x10);\n\tu8 *pdst = (u8 *)dst;\n\tu8 *psrc = (u8 *)src;\n\n\t//Generate tweak.\n\tfor (int i = 0xF; i >= 0; i--)\n\t{\n\t\ttweak[i] = sec & 0xFF;\n\t\tsec >>= 8;\n\t}\n\tif (!se_aes_crypt_block_ecb(ks1, 1, tweak, tweak))\n\t\tgoto out;\n\n\t//We are assuming a 0x10-aligned sector size in this implementation.\n\tfor (u32 i = 0; i < secsize / 0x10; i++)\n\t{\n\t\tfor (u32 j = 0; j < 0x10; j++)\n\t\t\tpdst[j] = psrc[j] ^ tweak[j];\n\t\tif (!se_aes_crypt_block_ecb(ks2, enc, pdst, pdst))\n\t\t\tgoto out;\n\t\tfor (u32 j = 0; j < 0x10; j++)\n\t\t\tpdst[j] = pdst[j] ^ tweak[j];\n\t\t_gf256_mul_x(tweak);\n\t\tpsrc += 0x10;\n\t\tpdst += 0x10;\n\t}\n\n\tres = 1;\n\nout:;\n\tfree(tweak);\n\treturn res;\n}\n\nint se_aes_xts_crypt(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs)\n{\n\tu8 *pdst = (u8 *)dst;\n\tu8 *psrc = (u8 *)src;\n\n\tfor (u32 i = 0; i < num_secs; i++)\n\t\tif (!se_aes_xts_crypt_sec(ks1, ks2, enc, sec + i, pdst + secsize * i, psrc + secsize * i, secsize))\n\t\t\treturn 0;\n\n\treturn 1;\n}\n\n// se_calc_sha256() was derived from Atmosphère's se_calculate_sha256.\nint se_calc_sha256(void *dst, const void *src, u32 src_size)\n{\n\tint res;\n\t// Setup config for SHA256, size = BITS(src_size).\n\tSE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);\n\tSE(SE_SHA_CONFIG_REG_OFFSET) = 1;\n\tSE(SE_SHA_MSG_LENGTH_REG_OFFSET) = (u32)(src_size << 3);\n\tSE(0x208) = 0;\n\tSE(0x20C) = 0;\n\tSE(0x210) = 0;\n\tSE(SE_SHA_MSG_LEFT_REG_OFFSET) = (u32)(src_size << 3);\n\tSE(0x218) = 0;\n   \tSE(0x21C) = 0;\n\tSE(0x220) = 0;\n\n\t// Trigger the operation.\n\tres = _se_execute(OP_START, NULL, 0, src, src_size);\n\n\t// Copy output hash.\n\tu32 *dst32 = (u32 *)dst;\n\tfor (u32 i = 0; i < 8; i++)\n\t\tdst32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)));\n\n\treturn res;\n}\n\n"
  },
  {
    "path": "argon-nx-gui/src/soc/bpmp.c",
    "content": "/*\n * BPMP-Lite Cache/MMU and Frequency driver for Tegra X1\n *\n * Copyright (c) 2019 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"soc/bpmp.h\"\n#include \"soc/clock.h\"\n#include \"soc/t210.h\"\n#include \"utils/util.h\"\n\n#define BPMP_CACHE_CONFIG               0x0\n#define  CFG_ENABLE                     (1 << 0)\n#define  CFG_FORCE_WRITE_THROUGH        (1 << 3)\n#define  CFG_DISABLE_WRITE_BUFFER       (1 << 10)\n#define  CFG_DISABLE_READ_BUFFER        (1 << 11)\n#define  CFG_FULL_LINE_DIRTY            (1 << 13)\n#define  CFG_TAG_CHK_ABRT_ON_ERR        (1 << 14)\n#define BPMP_CACHE_LOCK                 0x4\n#define BPMP_CACHE_SIZE                 0xC\n#define BPMP_CACHE_LFSR                 0x10\n#define BPMP_CACHE_TAG_STATUS           0x14\n#define BPMP_CACHE_CLKEN_OVERRIDE       0x18\n#define BPMP_CACHE_MAINT_ADDR           0x20\n#define BPMP_CACHE_MAINT_DATA           0x24\n#define BPMP_CACHE_MAINT_REQ            0x28\n#define  MAINT_REQ_WAY_BITMAP(x)        ((x) << 8)\n\n#define BPMP_CACHE_INT_MASK             0x40\n#define BPMP_CACHE_INT_CLEAR            0x44\n#define  INT_CLR_MAINT_DONE             (1 << 0)\n\n#define BPMP_CACHE_INT_RAW_EVENT        0x48\n#define  INT_RAW_EVENT_MAINT_DONE      (1 << 0)\n#define BPMP_CACHE_INT_STATUS           0x4C\n\n#define BPMP_CACHE_RB_CFG               0x80\n#define BPMP_CACHE_WB_CFG               0x84\n\n#define BPMP_CACHE_MMU_FALLBACK_ENTRY   0xA0\n#define BPMP_CACHE_MMU_SHADOW_COPY_MASK 0xA4\n#define BPMP_CACHE_MMU_CFG              0xAC\n#define  MMU_CFG_SEQ_EN                 (1 << 1)\n#define  MMU_CFG_TLB_EN                 (1 << 2)\n#define  MMU_CFG_ABORT_STORE_LAST       (1 << 4)\n#define BPMP_CACHE_MMU_CMD              0xB0\n#define  MMU_CMD_NOP                    0\n#define  MMU_CMD_INIT                   1\n#define  MMU_CMD_COPY_SHADOW            2\n#define BPMP_CACHE_MMU_ABORT_STAT       0xB4\n#define BPMP_CACHE_MMU_ABORT_ADDR       0xB8\n#define BPMP_CACHE_MMU_ACTIVE_ENTRIES   0xBC\n\n#define BPMP_MMU_SHADOW_ENTRY_BASE     (BPMP_CACHE_BASE + 0x400)\n#define BPMP_MMU_MAIN_ENTRY_BASE       (BPMP_CACHE_BASE + 0x800)\n#define  MMU_ENTRY_ADDR_MASK           0xFFFFFFE0\n\n#define  MMU_EN_CACHED                (1 << 0)\n#define  MMU_EN_EXEC                  (1 << 1)\n#define  MMU_EN_READ                  (1 << 2)\n#define  MMU_EN_WRITE                 (1 << 3)\n\n#pragma GCC push_options\n#pragma GCC target (\"thumb\")\n\nbpmp_mmu_entry_t mmu_entries[] =\n{\n\t{ 0x80000000,    0xFFFFFFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true },\n\t{ 0x40003000, 0x40040000, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true }\n};\n\nvoid bpmp_mmu_maintenance(u32 op)\n{\n\tif (!(BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) & CFG_ENABLE))\n\t\treturn;\n\n\tBPMP_CACHE_CTRL(BPMP_CACHE_INT_CLEAR) = INT_CLR_MAINT_DONE;\n\n\t// This is a blocking operation.\n\tBPMP_CACHE_CTRL(BPMP_CACHE_MAINT_REQ) = MAINT_REQ_WAY_BITMAP(0xF) | op;\n\n\twhile(!(BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT) & INT_RAW_EVENT_MAINT_DONE))\n\t\t;\n\n\tBPMP_CACHE_CTRL(BPMP_CACHE_INT_CLEAR) = BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT);\n}\n\nvoid bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply)\n{\n\tif (idx > 31)\n\t\treturn;\n\n\tvolatile bpmp_mmu_entry_t *mmu_entry = (bpmp_mmu_entry_t *)(BPMP_MMU_SHADOW_ENTRY_BASE + sizeof(bpmp_mmu_entry_t) * idx);\n\n\tif (entry->enable)\n\t{\n\t\tmmu_entry->min_addr = entry->min_addr & MMU_ENTRY_ADDR_MASK;\n\t\tmmu_entry->max_addr = entry->max_addr & MMU_ENTRY_ADDR_MASK;\n\t\tmmu_entry->attr = entry->attr;\n\n\t\tBPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) |= (1 << idx);\n\n\t\tif (apply)\n\t\t\tBPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_COPY_SHADOW;\n\t}\n}\n\nvoid bpmp_mmu_enable()\n{\n\tif (BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) & CFG_ENABLE)\n\t\treturn;\n\n\t// Init BPMP MMU.\n\tBPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_INIT;\n\tBPMP_CACHE_CTRL(BPMP_CACHE_MMU_FALLBACK_ENTRY) = MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC; // RWX for non-defined regions.\n\tBPMP_CACHE_CTRL(BPMP_CACHE_MMU_CFG) = MMU_CFG_SEQ_EN | MMU_CFG_TLB_EN | MMU_CFG_ABORT_STORE_LAST;\n\n\t// Init BPMP MMU entries.\n\tBPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) = 0;\n\tfor (u32 idx = 0; idx < (sizeof(mmu_entries) / sizeof(bpmp_mmu_entry_t)); idx++)\n\t\tbpmp_mmu_set_entry(idx, &mmu_entries[idx], false);\n\n\tBPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_COPY_SHADOW;\n\n\t// Invalidate cache.\n\tbpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY);\n\n\t// Enable cache.\n\tBPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = CFG_ENABLE | CFG_FORCE_WRITE_THROUGH | CFG_TAG_CHK_ABRT_ON_ERR;\n\n\t// HW bug. Invalidate cache again.\n\tbpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY);\n}\n\nvoid bpmp_mmu_disable()\n{\n\tif (!(BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) & CFG_ENABLE))\n\t\treturn;\n\n\t// Clean and invalidate cache.\n\tbpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY);\n\n\t// Enable cache.\n\tBPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = 0;\n\n\t// HW bug. Invalidate cache again.\n\tbpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY);\n}\n\nconst u8 pllc4_divn[] = {\n\t0,   // BPMP_CLK_NORMAL:      408MHz  0% - 136MHz APB.\n\t85,  // BPMP_CLK_LOW_BOOST:   544MHz 33% - 136MHz APB.\n\t90,  // BPMP_CLK_MID_BOOST:   576MHz 41% - 144MHz APB.\n\t94   // BPMP_CLK_SUPER_BOOST: 602MHz 48% - 150MHz APB.\n\t//95   // BPMP_CLK_SUPER_BOOST: 608MHz 49% - 152MHz APB.\n};\n\nbpmp_freq_t bpmp_clock_set = BPMP_CLK_NORMAL;\n\nvoid bpmp_clk_rate_set(bpmp_freq_t fid)\n{\n\tif (fid > (BPMP_CLK_MAX - 1))\n\t\tfid = BPMP_CLK_MAX - 1;\n\n\tif (bpmp_clock_set == fid)\n\t\treturn;\n\n\tif (fid)\n\t{\n\t\tif (bpmp_clock_set)\n\t\t{\n\t\t\t// Restore to PLLP source during PLLC4 configuration.\n\t\t\tCLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) =\n\t\t\t\t(CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & 0xFFFF8888) | 0x3333; // PLLP_OUT.\n\t\t\t// Wait a bit for clock source change.\n\t\t\tmsleep(10);\n\t\t}\n\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLC4_MISC) = (1 << 30);\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) = 4 | (pllc4_divn[fid] << 8) | (1 << 30); // DIVM: 4, DIVP: 1.\n\n\t\twhile (!(CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) & (1 << 27)))\n\t\t\t;\n\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLC4_OUT) = (1 << 8) | (1 << 1); // 1.5 div.\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLC4_OUT) |= 1; // Get divider out of reset.\n\n\t\t// Wait a bit for PLLC4 to stabilize.\n\t\tmsleep(10);\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 3; // PCLK = HCLK / 4.\n\t\tCLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) =\n\t\t\t(CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & 0xFFFF8888) | 0x3323; // PLLC4_OUT3.\n\n\t\tbpmp_clock_set = fid;\n\t}\n\telse\n\t{\n\t\tCLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) =\n\t\t\t(CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & 0xFFFF8888) | 0x3333; // PLLP_OUT.\n\n\t\t// Wait a bit for clock source change.\n\t\tmsleep(10);\n\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // PCLK = HCLK / 3.\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~(1<<30);\n\t\tbpmp_clock_set = BPMP_CLK_NORMAL;\n\t}\n}\n\n#pragma GCC pop_options\n"
  },
  {
    "path": "argon-nx-gui/src/soc/clock.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"soc/clock.h\"\n#include \"soc/t210.h\"\n#include \"utils/util.h\"\n#include \"storage/sdmmc.h\"\n\n#pragma GCC push_options\n#pragma GCC target (\"thumb\")\n\n/* clock_t: reset, enable, source, index, clk_src, clk_div */\n\nstatic const clock_t _clock_uart[] = {\n/* UART A */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, 6,    0, 0 },\n/* UART B */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, 7,    0, 0 },\n/* UART C */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, 0x17, 0, 0 },\n/* UART D */ { 0 },\n/* UART E */ { 0 }\n};\n\nstatic const clock_t _clock_i2c[] = {\n/* I2C1 */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, 0xC,  0, 19 }, //20.4MHz -> 100KHz\n/* I2C2 */ { 0 },\n/* I2C3 */ { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, 3,    0, 4 },  //81.6MHz -> 400KHz\n/* I2C4 */ { 0 },\n/* I2C5 */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, 0xF,  0, 4 },  //81.6MHz -> 400KHz\n/* I2C6 */ { 0 }\n};\n\nstatic clock_t _clock_se = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE,     0x1F, 0, 0\n};\n\nstatic clock_t _clock_tzram = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE,                        0x1E, 0, 0\n};\n\nstatic clock_t _clock_host1x = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, 0x1C, 4, 3\n};\nstatic clock_t _clock_tsec = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC,   0x13, 0, 2\n};\nstatic clock_t _clock_sor_safe = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE,                        0x1E, 0, 0\n};\nstatic clock_t _clock_sor0 = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NO_SOURCE,                        0x16, 0, 0\n};\nstatic clock_t _clock_sor1 = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1,   0x17, 0, 2\n};\nstatic clock_t _clock_kfuse = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE,                        8,    0, 0\n};\n\nstatic clock_t _clock_cl_dvfs =\t{\n\tCLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE,                        0x1B, 0, 0\n};\nstatic clock_t _clock_coresight = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE,     9, 0, 4\n};\n\nstatic clock_t _clock_pwm = {\n\tCLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM,    0x11, 6, 4\n};\n\nvoid clock_enable(const clock_t *clk)\n{\n\t// Put clock into reset.\n\tCLOCK(clk->reset) = (CLOCK(clk->reset) & ~(1 << clk->index)) | (1 << clk->index);\n\t// Disable.\n\tCLOCK(clk->enable) &= ~(1 << clk->index);\n\t// Configure clock source if required.\n\tif (clk->source)\n\t\tCLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29);\n\t// Enable.\n\tCLOCK(clk->enable) = (CLOCK(clk->enable) & ~(1 << clk->index)) | (1 << clk->index);\n\t// Take clock off reset.\n\tCLOCK(clk->reset) &= ~(1 << clk->index);\n}\n\nvoid clock_disable(const clock_t *clk)\n{\n\t// Put clock into reset.\n\tCLOCK(clk->reset) = (CLOCK(clk->reset) & ~(1 << clk->index)) | (1 << clk->index);\n\t// Disable.\n\tCLOCK(clk->enable) &= ~(1 << clk->index);\n}\n\nvoid clock_enable_fuse(bool enable)\n{\n\tCLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) = (CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) & 0xEFFFFFFF) | ((enable & 1) << 28);\n}\n\nvoid clock_enable_uart(u32 idx)\n{\n\tclock_enable(&_clock_uart[idx]);\n}\n\nvoid clock_enable_i2c(u32 idx)\n{\n\tclock_enable(&_clock_i2c[idx]);\n}\n\nvoid clock_disable_i2c(u32 idx)\n{\n\tclock_disable(&_clock_i2c[idx]);\n}\n\nvoid clock_enable_se()\n{\n\tclock_enable(&_clock_se);\n}\n\nvoid clock_enable_tzram()\n{\n\tclock_enable(&_clock_tzram);\n}\n\nvoid clock_enable_host1x()\n{\n\tclock_enable(&_clock_host1x);\n}\n\nvoid clock_disable_host1x()\n{\n\tclock_disable(&_clock_host1x);\n}\n\nvoid clock_enable_tsec()\n{\n\tclock_enable(&_clock_tsec);\n}\n\nvoid clock_disable_tsec()\n{\n\tclock_disable(&_clock_tsec);\n}\n\nvoid clock_enable_sor_safe()\n{\n\tclock_enable(&_clock_sor_safe);\n}\n\nvoid clock_disable_sor_safe()\n{\n\tclock_disable(&_clock_sor_safe);\n}\n\nvoid clock_enable_sor0()\n{\n\tclock_enable(&_clock_sor0);\n}\n\nvoid clock_disable_sor0()\n{\n\tclock_disable(&_clock_sor0);\n}\n\nvoid clock_enable_sor1()\n{\n\tclock_enable(&_clock_sor1);\n}\n\nvoid clock_disable_sor1()\n{\n\tclock_disable(&_clock_sor1);\n}\n\nvoid clock_enable_kfuse()\n{\n\t//clock_enable(&_clock_kfuse);\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) = (CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) & 0xFFFFFEFF) | 0x100;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) &= 0xFFFFFEFF;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) & 0xFFFFFEFF) | 0x100;\n\tusleep(10);\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) &= 0xFFFFFEFF;\n\tusleep(20);\n}\n\nvoid clock_disable_kfuse()\n{\n\tclock_disable(&_clock_kfuse);\n}\n\nvoid clock_enable_cl_dvfs()\n{\n\tclock_enable(&_clock_cl_dvfs);\n}\n\nvoid clock_disable_cl_dvfs()\n{\n\tclock_disable(&_clock_cl_dvfs);\n}\n\nvoid clock_enable_coresight()\n{\n\tclock_enable(&_clock_coresight);\n}\n\nvoid clock_disable_coresight()\n{\n\tclock_disable(&_clock_coresight);\n}\n\nvoid clock_enable_pwm()\n{\n\tclock_enable(&_clock_pwm);\n}\n\nvoid clock_disable_pwm()\n{\n\tclock_disable(&_clock_pwm);\n}\n\n#define L_SWR_SDMMC1_RST (1 << 14)\n#define L_SWR_SDMMC2_RST (1 << 9)\n#define L_SWR_SDMMC4_RST (1 << 15)\n#define U_SWR_SDMMC3_RST (1 << 5)\n\n#define L_CLK_ENB_SDMMC1 (1 << 14)\n#define L_CLK_ENB_SDMMC2 (1 << 9)\n#define L_CLK_ENB_SDMMC4 (1 << 15)\n#define U_CLK_ENB_SDMMC3 (1 << 5)\n\n#define L_SET_SDMMC1_RST (1 << 14)\n#define L_SET_SDMMC2_RST (1 << 9)\n#define L_SET_SDMMC4_RST (1 << 15)\n#define U_SET_SDMMC3_RST (1 << 5)\n\n#define L_CLR_SDMMC1_RST (1 << 14)\n#define L_CLR_SDMMC2_RST (1 << 9)\n#define L_CLR_SDMMC4_RST (1 << 15)\n#define U_CLR_SDMMC3_RST (1 << 5)\n\n#define L_SET_CLK_ENB_SDMMC1 (1 << 14)\n#define L_SET_CLK_ENB_SDMMC2 (1 << 9)\n#define L_SET_CLK_ENB_SDMMC4 (1 << 15)\n#define U_SET_CLK_ENB_SDMMC3 (1 << 5)\n\n#define L_CLR_CLK_ENB_SDMMC1 (1 << 14)\n#define L_CLR_CLK_ENB_SDMMC2 (1 << 9)\n#define L_CLR_CLK_ENB_SDMMC4 (1 << 15)\n#define U_CLR_CLK_ENB_SDMMC3 (1 << 5)\n\nstatic int _clock_sdmmc_is_reset(u32 id)\n{\n\tswitch (id)\n\t{\n\tcase SDMMC_1:\n\t\treturn CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & L_SWR_SDMMC1_RST;\n\tcase SDMMC_2:\n\t\treturn CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & L_SWR_SDMMC2_RST;\n\tcase SDMMC_3:\n\t\treturn CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_U) & U_SWR_SDMMC3_RST;\n\tcase SDMMC_4:\n\t\treturn CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & L_SWR_SDMMC4_RST;\n\t}\n\treturn 0;\n}\n\nstatic void _clock_sdmmc_set_reset(u32 id)\n{\n\tswitch (id)\n\t{\n\tcase SDMMC_1:\n\t\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = L_SET_SDMMC1_RST;\n\t\tbreak;\n\tcase SDMMC_2:\n\t\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = L_SET_SDMMC2_RST;\n\t\tbreak;\n\tcase SDMMC_3:\n\t\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_U_SET) = U_SET_SDMMC3_RST;\n\t\tbreak;\n\tcase SDMMC_4:\n\t\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = L_SET_SDMMC4_RST;\n\t\tbreak;\n\t}\n}\n\nstatic void _clock_sdmmc_clear_reset(u32 id)\n{\n\tswitch (id)\n\t{\n\tcase SDMMC_1:\n\t\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = L_CLR_SDMMC1_RST;\n\t\tbreak;\n\tcase SDMMC_2:\n\t\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = L_CLR_SDMMC2_RST;\n\t\tbreak;\n\tcase SDMMC_3:\n\t\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_U_CLR) = U_CLR_SDMMC3_RST;\n\t\tbreak;\n\tcase SDMMC_4:\n\t\tCLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = L_CLR_SDMMC4_RST;\n\t\tbreak;\n\t}\n}\n\nstatic int _clock_sdmmc_is_enabled(u32 id)\n{\n\tswitch (id)\n\t{\n\tcase SDMMC_1:\n\t\treturn CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & L_CLK_ENB_SDMMC1;\n\tcase SDMMC_2:\n\t\treturn CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & L_CLK_ENB_SDMMC2;\n\tcase SDMMC_3:\n\t\treturn CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) & U_CLK_ENB_SDMMC3;\n\tcase SDMMC_4:\n\t\treturn CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & L_CLK_ENB_SDMMC4;\n\t}\n\treturn 0;\n}\n\nstatic void _clock_sdmmc_set_enable(u32 id)\n{\n\tswitch (id)\n\t{\n\tcase SDMMC_1:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC1;\n\t\tbreak;\n\tcase SDMMC_2:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC2;\n\t\tbreak;\n\tcase SDMMC_3:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_SET) = U_SET_CLK_ENB_SDMMC3;\n\t\tbreak;\n\tcase SDMMC_4:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC4;\n\t\tbreak;\n\t}\n}\n\nstatic void _clock_sdmmc_clear_enable(u32 id)\n{\n\tswitch (id)\n\t{\n\tcase SDMMC_1:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC1;\n\t\tbreak;\n\tcase SDMMC_2:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC2;\n\t\tbreak;\n\tcase SDMMC_3:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_CLR) = U_CLR_CLK_ENB_SDMMC3;\n\t\tbreak;\n\tcase SDMMC_4:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC4;\n\t\tbreak;\n\t}\n}\n\nstatic u32 _clock_sdmmc_table[8] = { 0 };\n\n#define PLLP_OUT0      0x0\n\nstatic int _clock_sdmmc_config_clock_source_inner(u32 *pout, u32 id, u32 val)\n{\n\tu32 divisor = 0;\n\tu32 source = PLLP_OUT0;\n\n\tswitch (val)\n\t{\n\tcase 25000:\n\t\t*pout = 24728;\n\t\tdivisor = 31;\n\t\tbreak;\n\tcase 26000:\n\t\t*pout = 25500;\n\t\tdivisor = 30;\n\t\tbreak;\n\tcase 40800:\n\t\t*pout = 40800;\n\t\tdivisor = 18;\n\t\tbreak;\n\tcase 50000:\n\t\t*pout = 48000;\n\t\tdivisor = 15;\n\t\tbreak;\n\tcase 52000:\n\t\t*pout = 51000;\n\t\tdivisor = 14;\n\t\tbreak;\n\tcase 100000:\n\t\t*pout = 90667;\n\t\tdivisor = 7;\n\t\tbreak;\n\tcase 200000:\n\t\t*pout = 163200;\n\t\tdivisor = 3;\n\t\tbreak;\n\tcase 208000:\n\t\t*pout = 204000;\n\t\tdivisor = 2;\n\t\tbreak;\n\tdefault:\n\t\t*pout = 24728;\n\t\tdivisor = 31;\n\t}\n\n\t_clock_sdmmc_table[2 * id] = val;\n\t_clock_sdmmc_table[2 * id + 1] = *pout;\n\n\tswitch (id)\n\t{\n\tcase SDMMC_1:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = (source << 29) | divisor;\n\t\tbreak;\n\tcase SDMMC_2:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = (source << 29) | divisor;\n\t\tbreak;\n\tcase SDMMC_3:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = (source << 29) | divisor;\n\t\tbreak;\n\tcase SDMMC_4:\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = (source << 29) | divisor;\n\t\tbreak;\n\t}\n\n\treturn 1;\n}\n\nvoid clock_sdmmc_config_clock_source(u32 *pout, u32 id, u32 val)\n{\n\tif (_clock_sdmmc_table[2 * id] == val)\n\t{\n\t\t*pout = _clock_sdmmc_table[2 * id + 1];\n\t}\n\telse\n\t{\n\t\tint is_enabled = _clock_sdmmc_is_enabled(id);\n\t\tif (is_enabled)\n\t\t\t_clock_sdmmc_clear_enable(id);\n\t\t_clock_sdmmc_config_clock_source_inner(pout, id, val);\n\t\tif (is_enabled)\n\t\t\t_clock_sdmmc_set_enable(id);\n\t\t_clock_sdmmc_is_reset(id);\n\t}\n}\n\nvoid clock_sdmmc_get_params(u32 *pout, u16 *pdivisor, u32 type)\n{\n\tswitch (type)\n\t{\n\tcase 0:\n\t\t*pout = 26000;\n\t\t*pdivisor = 66;\n\t\tbreak;\n\tcase 1:\n\t\t*pout = 26000;\n\t\t*pdivisor = 1;\n\t\tbreak;\n\tcase 2:\n\t\t*pout = 52000;\n\t\t*pdivisor = 1;\n\t\tbreak;\n\tcase 3:\n\tcase 4:\n\tcase 11:\n\t\t*pout = 200000;\n\t\t*pdivisor = 1;\n\t\tbreak;\n\tcase 5:\n\t\t*pout = 25000;\n\t\t*pdivisor = 64;\n\t\tbreak;\n\tcase 6:\n\tcase 8:\n\t\t*pout = 25000;\n\t\t*pdivisor = 1;\n\t\tbreak;\n\tcase 7:\n\t\t*pout = 50000;\n\t\t*pdivisor = 1;\n\t\tbreak;\n\tcase 10:\n\t\t*pout = 100000;\n\t\t*pdivisor = 1;\n\t\tbreak;\n\tcase 13:\n\t\t*pout = 40800;\n\t\t*pdivisor = 1;\n\t\tbreak;\n\tcase 14:\n\t\t*pout = 200000;\n\t\t*pdivisor = 2;\n\t\tbreak;\n\t}\n}\n\nint clock_sdmmc_is_not_reset_and_enabled(u32 id)\n{\n\treturn !_clock_sdmmc_is_reset(id) && _clock_sdmmc_is_enabled(id);\n}\n\nvoid clock_sdmmc_enable(u32 id, u32 val)\n{\n\tu32 div = 0;\n\n\tif (_clock_sdmmc_is_enabled(id))\n\t\t_clock_sdmmc_clear_enable(id);\n\t_clock_sdmmc_set_reset(id);\n\t_clock_sdmmc_config_clock_source_inner(&div, id, val);\n\t_clock_sdmmc_set_enable(id);\n\t_clock_sdmmc_is_reset(id);\n\tusleep((100000 + div - 1) / div);\n\t_clock_sdmmc_clear_reset(id);\n\t_clock_sdmmc_is_reset(id);\n}\n\nvoid clock_sdmmc_disable(u32 id)\n{\n\t_clock_sdmmc_set_reset(id);\n\t_clock_sdmmc_clear_enable(id);\n\t_clock_sdmmc_is_reset(id);\n}\n\n#pragma GCC pop_options\n"
  },
  {
    "path": "argon-nx-gui/src/soc/cluster.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"soc/cluster.h\"\n#include \"soc/i2c.h\"\n#include \"soc/clock.h\"\n#include \"utils/util.h\"\n#include \"soc/pmc.h\"\n#include \"soc/t210.h\"\n#include \"power/max77620.h\"\n#include \"power/max7762x.h\"\n\nvoid _cluster_enable_power()\n{\n\tu8 tmp = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO);\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO, tmp & 0xDF);\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, MAX77620_CNFG_GPIO_DRV_PUSHPULL | MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH);\n\n\t// Enable cores power.\n\t// 1-3.x: MAX77621_NFSR_ENABLE.\n\ti2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL1_REG,\n\t\tMAX77621_AD_ENABLE | MAX77621_NFSR_ENABLE | MAX77621_SNS_ENABLE);\n\t// 1.0.0-3.x: MAX77621_T_JUNCTION_120 | MAX77621_CKKADV_TRIP_DISABLE | MAX77621_INDUCTOR_NOMINAL.\n\ti2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL2_REG,\n\t\tMAX77621_T_JUNCTION_120 | MAX77621_WDTMR_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US| MAX77621_INDUCTOR_NOMINAL);\n\ti2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_REG, MAX77621_VOUT_ENABLE | 0x37);\n\ti2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_DVC_REG, MAX77621_VOUT_ENABLE | 0x37);\n}\n\nint _cluster_pmc_enable_partition(u32 part, u32 toggle, bool enable)\n{\n\t// Check if the partition has already been turned on.\n\tif (enable && PMC(APBDEV_PMC_PWRGATE_STATUS) & part)\n\t\treturn 1;\n\n\tu32 i = 5001;\n\twhile (PMC(APBDEV_PMC_PWRGATE_TOGGLE) & 0x100)\n\t{\n\t\tusleep(1);\n\t\ti--;\n\t\tif (i < 1)\n\t\t\treturn 0;\n\t}\n\n\tPMC(APBDEV_PMC_PWRGATE_TOGGLE) = toggle | (enable ? 0x100 : 0);\n\n\ti = 5001;\n\twhile (i > 0)\n\t{\n\t\tif (PMC(APBDEV_PMC_PWRGATE_STATUS) & part)\n\t\t\tbreak;\n\t\tusleep(1);\n\t\ti--;\n\t}\n\n\treturn 1;\n}\n\nvoid cluster_boot_cpu0(u32 entry)\n{\n\t// Set ACTIVE_CLUSER to FAST.\n\tFLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= 0xFFFFFFFE;\n\n\t_cluster_enable_power();\n\n\tif (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x40000000))\n\t{\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= 0xFFFFFFF7;\n\t\tusleep(2);\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x80404E02;\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x404E02;\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLX_MISC) = (CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) & 0xFFFBFFFF) | 0x40000;\n\t\tCLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x40404E02;\n\t}\n\twhile (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x8000000))\n\t\t;\n\n\t// Configure MSELECT source and enable clock.\n\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) & 0x1FFFFF00) | 6;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) & 0xFFFFFFF7) | 8;\n\n\t// Configure initial CPU clock frequency and enable clock.\n\tCLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888;\n\tCLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000;\n\tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = 1;\n\n\tclock_enable_coresight();\n\n\t// CAR2PMC_CPU_ACK_WIDTH should be set to 0.\n\tCLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) &= 0xFFFFF000;\n\n\t// Enable CPU rail.\n\t_cluster_pmc_enable_partition(1, 0, true);\n\t// Enable cluster 0 non-CPU.\n\t_cluster_pmc_enable_partition(0x8000, 15, true);\n\t// Enable CE0.\n\t_cluster_pmc_enable_partition(0x4000, 14, true);\n\n\t// Request and wait for RAM repair.\n\tFLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = 1;\n\twhile (!(FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) & 2))\n\t\t;\n\n\tEXCP_VEC(EVP_CPU_RESET_VECTOR) = 0;\n\n\t// Set reset vector.\n\tSB(SB_AA64_RESET_LOW) = entry | 1;\n\tSB(SB_AA64_RESET_HIGH) = 0;\n\t// Non-secure reset vector write disable.\n\tSB(SB_CSR) = 2;\n\t(void)SB(SB_CSR);\n\n\t// Clear MSELECT reset.\n\tCLOCK(CLK_RST_CONTROLLER_RST_DEVICES_V) &= 0xFFFFFFF7;\n\t// Clear NONCPU reset.\n\tCLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000;\n\t// Clear CPU0 reset.\n\t// < 5.x: 0x411F000F, Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.\n\tCLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x41010001;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/soc/fuse.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 shuffle2\n * Copyright (c) 2018 balika011\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"soc/fuse.h\"\n#include \"soc/t210.h\"\n\n#define ARRAYSIZE(x) (sizeof(x) / sizeof(*x))\n\nstatic const u32 evp_thunk_template[] = {\n\t0xe92d0007, //   STMFD   SP!, {R0-R2}\n\t0xe1a0200e, //   MOV     R2, LR\n\t0xe2422002, //   SUB     R2, R2, #2\n\t0xe5922000, //   LDR     R2, [R2]\n\t0xe20220ff, //   AND     R2, R2, #0xFF\n\t0xe1a02082, //   MOV     R2, R2,LSL#1\n\t0xe59f001c, //   LDR     R0, =evp_thunk_template\n\t0xe59f101c, //   LDR     R1, =thunk_end\n\t0xe0411000, //   SUB     R1, R1, R0\n\t0xe59f0018, //   LDR     R0, =iram_evp_thunks\n\t0xe0800001, //   ADD     R0, R0, R1\n\t0xe0822000, //   ADD     R2, R2, R0\n\t0xe3822001, //   ORR     R2, R2, #1\n\t0xe8bd0003, //   LDMFD   SP!, {R0,R1}\n\t0xe12fff12, //   BX      R2\n\t0x001007b0, // off_1007EC DCD evp_thunk_template\n\t0x001007f8, // off_1007F0 DCD thunk_end\n\t0x40004c30, // off_1007F4 DCD iram_evp_thunks\n\t// thunk_end is here\n};\nstatic const u32 evp_thunk_template_len = sizeof(evp_thunk_template);\n\n// treated as 12bit values\nstatic const u32 hash_vals[] = {1, 2, 4, 8, 0, 3, 5, 6, 7, 9, 10, 11};\n\nvoid fuse_disable_program()\n{\n\tFUSE(FUSE_DISABLEREGPROGRAM) = 1;\n}\n\nu32 fuse_read_odm(u32 idx)\n{\n\treturn FUSE(FUSE_RESERVED_ODMX(idx));\n}\n\nvoid fuse_wait_idle()\n{\n    u32 ctrl;\n    do\n    {\n        ctrl = FUSE(FUSE_CTRL);\n    } while (((ctrl >> 16) & 0x1f) != 4);\n}\n\nu32 parity32_even(u32 *words, u32 count)\n{\n\tu32 acc = words[0];\n\tfor (u32 i = 1; i < count; i++)\n\t{\n\t\tacc ^= words[i];\n\t}\n\tu32 lo = ((acc & 0xffff) ^ (acc >> 16)) & 0xff;\n\tu32 hi = ((acc & 0xffff) ^ (acc >> 16)) >> 8;\n\tu32 x = hi ^ lo;\n\tlo = ((x & 0xf) ^ (x >> 4)) & 3;\n\thi = ((x & 0xf) ^ (x >> 4)) >> 2;\n\tx = hi ^ lo;\n \n\treturn (x & 1) ^ (x >> 1);\n}\n\nint patch_hash_one(u32 *word)\n{\n\tu32 bits20_31 = *word & 0xfff00000;\n\tu32 parity_bit = parity32_even(&bits20_31, 1);\n\tu32 hash = 0;\n\tfor (u32 i = 0; i < 12; i++)\n\t{\n\t\tif (*word & (1 << (20 + i)))\n\t\t{\n\t\t\thash ^= hash_vals[i];\n\t\t}\n\t}\n\tif (hash == 0)\n\t{\n\t\tif (parity_bit == 0)\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\t\t*word ^= 1 << 24;\n\t\treturn 1;\n\t}\n\tif (parity_bit == 0)\n\t{\n\t\treturn 3;\n\t}\n\tfor (u32 i = 0; i < ARRAYSIZE(hash_vals); i++)\n\t{\n\t\tif (hash_vals[i] == hash)\n\t\t{\n\t\t\t*word ^= 1 << (20 + i);\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 2;\n}\n\nint patch_hash_multi(u32 *words, u32 count)\n{\n\tu32 parity_bit = parity32_even(words, count);\n\tu32 bits0_14 = words[0] & 0x7fff;\n\tu32 bit15 = words[0] & 0x8000;\n\tu32 bits16_19 = words[0] & 0xf0000;\n\n\tu32 hash = 0;\n\twords[0] = bits16_19;\n\tfor (u32 i = 0; i < count; i++)\n\t{\n\t\tu32 w = words[i];\n\t\tif (w)\n\t\t{\n\t\t\tfor (u32 bitpos = 0; bitpos < 32; bitpos++)\n\t\t\t{\n\t\t\t\tif ((w >> bitpos) & 1)\n\t\t\t\t{\n\t\t\t\t\thash ^= 0x4000 + i * 32 + bitpos;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\thash ^= bits0_14;\n\t// stupid but this is what original code does.\n\t// equivalent to original words[0] &= 0xfff00000\n\twords[0] = bits16_19 ^ bit15 ^ bits0_14;\n\n\tif (hash == 0)\n\t{\n\t\tif (parity_bit == 0)\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\t\twords[0] ^= 0x8000;\n\t\treturn 1;\n\t}\n\tif (parity_bit == 0)\n\t{\n\t\treturn 3;\n\t}\n\tu32 bitcount = hash - 0x4000;\n\tif (bitcount < 16 || bitcount >= count * 32)\n\t{\n\t\tu32 num_set = 0;\n\t\tfor (u32 bitpos = 0; bitpos < 15; bitpos++)\n\t\t{\n\t\t\tif ((hash >> bitpos) & 1)\n\t\t\t{\n\t\t\t\tnum_set++;\n\t\t\t}\n\t\t}\n\t\tif (num_set != 1)\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\t\twords[0] ^= hash;\n\t\treturn 1;\n\t}\n\twords[bitcount / 32] ^= 1 << (hash & 0x1f);\n\treturn 1;\n}\n\nint fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value))\n{\n\tu32 words[80];\n\tu32 word_count;\n\tu32 word_addr;\n\tu32 word0 = 0;\n\tu32 total_read = 0;\n\n\tword_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);\n\tword_count &= 0x7f;\n\tword_addr = 191;\n\n\twhile (word_count)\n\t{\n\t\ttotal_read += word_count;\n\t\tif (total_read >= ARRAYSIZE(words))\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t\t\n\t\tfor (u32 i = 0; i < word_count; i++)\n\t\t{\n\t\t\tFUSE(FUSE_ADDR) = word_addr--;\n\t\t\tFUSE(FUSE_CTRL) = (FUSE(FUSE_ADDR) & ~FUSE_CMD_MASK) | FUSE_READ;\n\t\t\tfuse_wait_idle();\n\t\t\twords[i] = FUSE(FUSE_RDATA);\n\t\t}\n\t\t\n\t\tword0 = words[0];\n\t\tif (patch_hash_multi(words, word_count) >= 2)\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tu32 ipatch_count = (words[0] >> 16) & 0xf;\n\t\tif (ipatch_count)\n\t\t{\n\t\t\tfor (u32 i = 0; i < ipatch_count; i++)\n\t\t\t{\n\t\t\t\tu32 word = words[i + 1];\n\t\t\t\tu32 addr = (word >> 16) * 2;\n\t\t\t\tu32 data = word & 0xffff;\n\t\t\n\t\t\t\tipatch(addr, data);\n\t\t\t}\n\t\t}\n\t\twords[0] = word0;\n\t\tif ((word0 >> 25) == 0)\n\t\t\tbreak;\n\t\tif (patch_hash_one(&word0) >= 2)\n\t\t{\n\t\t\treturn 3;\n\t\t}\n\t\tword_count = word0 >> 25;\n\t}\n\t\n\treturn 0;\n}\n\nint fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)\n{\n\tu32 words[80];\n\tu32 word_count;\n\tu32 word_addr;\n\tu32 word0 = 0;\n\tu32 total_read = 0;\n\tint evp_thunk_written = 0;\n\tvoid *evp_thunk_dst_addr = 0;\n\n\tmemset(iram_evp_thunks, 0, *iram_evp_thunks_len);\n\n\tword_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);\n\tword_count &= 0x7f;\n\tword_addr = 191;\n\n\twhile (word_count)\n\t{\n\t\ttotal_read += word_count;\n\t\tif (total_read >= ARRAYSIZE(words))\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t\t\n\t\tfor (u32 i = 0; i < word_count; i++)\n\t\t{\n\t\t\tFUSE(FUSE_ADDR) = word_addr--;\n\t\t\tFUSE(FUSE_CTRL) = (FUSE(FUSE_ADDR) & ~FUSE_CMD_MASK) | FUSE_READ;\n\t\t\tfuse_wait_idle();\n\t\t\twords[i] = FUSE(FUSE_RDATA);\n\t\t}\n\t\t\n\t\tword0 = words[0];\n\t\tif (patch_hash_multi(words, word_count) >= 2)\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tu32 ipatch_count = (words[0] >> 16) & 0xf;\n\t\tu32 insn_count = word_count - ipatch_count - 1;\n\t\tif (insn_count)\n\t\t{\n\t\t\tif (!evp_thunk_written)\n\t\t\t{\n\t\t\t\tevp_thunk_dst_addr = (void *)iram_evp_thunks;\n\n\t\t\t\tmemcpy(evp_thunk_dst_addr, (void *)evp_thunk_template, evp_thunk_template_len);\n\t\t\t\tevp_thunk_dst_addr += evp_thunk_template_len;\n\t\t\t\tevp_thunk_written = 1;\n\t\t\t\t*iram_evp_thunks_len = evp_thunk_template_len;\n\n\t\t\t\t//write32(TEGRA_EXCEPTION_VECTORS_BASE + 0x208, iram_evp_thunks);\n\t\t\t}\n\n\t\t\tu32 thunk_patch_len = insn_count * sizeof(u32);\n\t\t\tmemcpy(evp_thunk_dst_addr, &words[ipatch_count + 1], thunk_patch_len);\n\t\t\tevp_thunk_dst_addr += thunk_patch_len;\n\t\t\t*iram_evp_thunks_len += thunk_patch_len;\n\t\t}\n\t\twords[0] = word0;\n\t\tif ((word0 >> 25) == 0)\n\t\t\tbreak;\n\t\tif (patch_hash_one(&word0) >= 2)\n\t\t{\n\t\t\treturn 3;\n\t\t}\n\t\tword_count = word0 >> 25;\n\t}\n\t\n\treturn 0;\n}\n\nvoid read_raw_ipatch_fuses(u32 *words)\n{\n\tfor (u32 i = 0; i < 0x100; i++)\n\t{\n\t\tFUSE(FUSE_ADDR) = i;\n\t\tFUSE(FUSE_CTRL) = (FUSE(FUSE_ADDR) & ~FUSE_CMD_MASK) | FUSE_READ;\n\t\tfuse_wait_idle();\n\t\twords[i] = FUSE(FUSE_RDATA);\n\t}\n}"
  },
  {
    "path": "argon-nx-gui/src/soc/gpio.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"soc/gpio.h\"\n#include \"soc/t210.h\"\n\nstatic const u16 _gpio_cnf[31] = {\n\t0x000, 0x004, 0x008, 0x00C,\n\t0x100, 0x104, 0x108, 0x10C,\n\t0x200, 0x204, 0x208, 0x20C,\n\t0x300, 0x304, 0x308, 0x30C,\n\t0x400, 0x404, 0x408, 0x40C,\n\t0x500, 0x504, 0x508, 0x50C,\n\t0x600, 0x604, 0x608, 0x60C,\n\t0x700, 0x704, 0x708\n};\n\nstatic const u16 _gpio_oe[31] = {\n\t0x010, 0x014, 0x018, 0x01C,\n\t0x110, 0x114, 0x118, 0x11C,\n\t0x210, 0x214, 0x218, 0x21C,\n\t0x310, 0x314, 0x318, 0x31C,\n\t0x410, 0x414, 0x418, 0x41C,\n\t0x510, 0x514, 0x518, 0x51C,\n\t0x610, 0x614, 0x618, 0x61C,\n\t0x710, 0x714, 0x718\n};\n\nstatic const u16 _gpio_out[31] = {\n\t0x020, 0x024, 0x028, 0x02C,\n\t0x120, 0x124, 0x128, 0x12C,\n\t0x220, 0x224, 0x228, 0x22C,\n\t0x320, 0x324, 0x328, 0x32C,\n\t0x420, 0x424, 0x428, 0x42C,\n\t0x520, 0x524, 0x528, 0x52C,\n\t0x620, 0x624, 0x628, 0x62C,\n\t0x720, 0x724, 0x728\n};\n\nstatic const u16 _gpio_in[31] = {\n\t0x030, 0x034, 0x038, 0x03C,\n\t0x130, 0x134, 0x138, 0x13C,\n\t0x230, 0x234, 0x238, 0x23C,\n\t0x330, 0x334, 0x338, 0x33C,\n\t0x430, 0x434, 0x438, 0x43C,\n\t0x530, 0x534, 0x538, 0x53C,\n\t0x630, 0x634, 0x638, 0x63C,\n\t0x730, 0x734, 0x738\n};\n\nvoid gpio_config(u32 port, u32 pins, int mode)\n{\n\tif (mode)\n\t\tGPIO(_gpio_cnf[port]) |= pins;\n\telse\n\t\tGPIO(_gpio_cnf[port]) &= ~pins;\n\t(void)GPIO(_gpio_cnf[port]);\n}\n\nvoid gpio_output_enable(u32 port, u32 pins, int enable)\n{\n\tif (enable)\n\t\tGPIO(_gpio_oe[port]) |= pins;\n\telse\n\t\tGPIO(_gpio_oe[port]) &= ~pins;\n\t(void)GPIO(_gpio_oe[port]);\n}\n\nvoid gpio_write(u32 port, u32 pins, int high)\n{\n\tif (high)\n\t\tGPIO(_gpio_out[port]) |= pins;\n\telse\n\t\tGPIO(_gpio_out[port]) &= ~pins;\n\t(void)GPIO(_gpio_out[port]);\n}\n\nint gpio_read(u32 port, u32 pins)\n{\n\treturn (GPIO(_gpio_in[port]) & pins) ? 1 : 0;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/soc/hw_init.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"soc/hw_init.h\"\n\n#include \"gfx/di.h\"\n\n#include \"mem/mc.h\"\n#include \"mem/sdram.h\"\n\n#include \"minerva/minerva.h\"\n\n#include \"power/max77620.h\"\n#include \"power/max7762x.h\"\n\n#include \"sec/se.h\"\n#include \"sec/se_t210.h\"\n\n#include \"soc/clock.h\"\n#include \"soc/fuse.h\"\n#include \"soc/gpio.h\"\n#include \"soc/i2c.h\"\n#include \"soc/pinmux.h\"\n#include \"soc/pmc.h\"\n#include \"soc/t210.h\"\n#include \"soc/uart.h\"\n#include \"soc/bpmp.h\"\n\n#include \"storage/sdmmc.h\"\n\n#include \"utils/util.h\"\n#include \"utils/fs_utils.h\"\n\n\nvoid reconfig_hw_workaround(argon_ctxt_t *argon_ctxt, bool extra_reconfig, u32 magic)\n{\n    bpmp_mmu_disable();\n    bpmp_clk_rate_set(BPMP_CLK_NORMAL);\n\n    minerva_change_freq(argon_ctxt->mtc_conf, FREQ_204);\n\n    // Re-enable clocks to Audio Processing Engine as a workaround to hanging.\n    CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= (1 << 10); // Enable AHUB clock.\n    CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= (1 << 6);  // Enable APE clock.\n\n    if (extra_reconfig)\n    {\n        msleep(10);\n        PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_SDMMC1_IO_EN;\n\n        clock_disable_cl_dvfs();\n\n        // Disable Joy-con GPIOs.\n        gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);\n        gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);\n        gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_SPIO);\n        gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_SPIO);\n\n        // Fix GPU after warmboot for Linux.\n        i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, 2);\n        i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO6, 2);\n\n        // Touch\n        gpio_config(GPIO_PORT_J, GPIO_PIN_7, GPIO_MODE_SPIO);\n    }\n\n    // Power off display.\n    display_end();\n\n    // Enable clock to USBD and init SDMMC1 to avoid hangs with bad hw inits.\n    if (magic == 0xBAADF00D)\n    {\n        CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) |= (1 << 22);\n        sdmmc_init(&g_sd_sdmmc, SDMMC_1, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, 5, 0);\n        clock_disable_cl_dvfs();\n\n        msleep(200);\n    }\n}\n"
  },
  {
    "path": "argon-nx-gui/src/soc/i2c.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"soc/i2c.h\"\n#include \"utils/util.h\"\n\nstatic u32 i2c_addrs[] = {\n\t0x7000C000, 0x7000C400, 0x7000C500,\n\t0x7000C700, 0x7000D000, 0x7000D100\n};\n\nstatic void _i2c_wait(vu32 *base)\n{\n\tbase[I2C_CONFIG_LOAD] = 0x25;\n\tfor (u32 i = 0; i < 20; i++)\n\t{\n\t\tusleep(1);\n\t\tif (!(base[I2C_CONFIG_LOAD] & 1))\n\t\t\tbreak;\n\t}\n}\n\nstatic int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)\n{\n\tif (size > 4)\n\t\treturn 0;\n\n\tu32 tmp = 0;\n\tmemcpy(&tmp, buf, size);\n\n\tvu32 *base = (vu32 *)i2c_addrs[idx];\n\tbase[I2C_CMD_ADDR0] = x << 1; //Set x (send mode).\n\tbase[I2C_CMD_DATA1] = tmp;    //Set value.\n\tbase[I2C_CNFG] = (2 * size - 2) | 0x2800; //Set size and send mode.\n\t_i2c_wait(base);  //Kick transaction.\n\n\tbase[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200;\n\twhile (base[I2C_STATUS] & 0x100)\n\t\t;\n\n\tif (base[I2C_STATUS] << 28)\n\t\treturn 0;\n\n\treturn 1;\n}\n\nstatic int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)\n{\n\tif (size > 8)\n\t\treturn 0;\n\n\tvu32 *base = (vu32 *)i2c_addrs[idx];\n\tbase[I2C_CMD_ADDR0] = (x << 1) | 1; // Set x (recv mode).\n\tbase[I2C_CNFG] = (size - 1) << 1 | 0x2840; // Set size and recv mode.\n\t_i2c_wait(base);        // Kick transaction.\n\n\tbase[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200;\n\twhile (base[I2C_STATUS] & 0x100)\n\t\t;\n\n\tif (base[I2C_STATUS] << 28)\n\t\treturn 0;\n\n\tu32 tmp = base[I2C_CMD_DATA1]; // Get LS value.\n\tif (size > 4)\n\t{\n\t\tmemcpy(buf, &tmp, 4);\n\t\ttmp = base[I2C_CMD_DATA2]; // Get MS value.\n\t\tmemcpy(buf + 4, &tmp, size - 4);\n\t}\n\telse\n\t\tmemcpy(buf, &tmp, size);\n\n\treturn 1;\n}\n\nvoid i2c_init(u32 idx)\n{\n\tvu32 *base = (vu32 *)i2c_addrs[idx];\n\n\tbase[I2C_CLK_DIVISOR_REGISTER] = 0x50001;\n\tbase[I2C_BUS_CLEAR_CONFIG] = 0x90003;\n\t_i2c_wait(base);\n\n\tfor (u32 i = 0; i < 10; i++)\n\t{\n\t\tusleep(20000);\n\t\tif (base[INTERRUPT_STATUS_REGISTER] & 0x800)\n\t\t\tbreak;\n\t}\n\n\t(vu32)base[I2C_BUS_CLEAR_STATUS];\n\tbase[INTERRUPT_STATUS_REGISTER] = base[INTERRUPT_STATUS_REGISTER];\n}\n\nint i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size)\n{\n\tu8 tmp[4];\n\n\tif (size > 3)\n\t\treturn 0;\n\n\ttmp[0] = y;\n\tmemcpy(tmp + 1, buf, size);\n\n\treturn _i2c_send_pkt(idx, x, tmp, size + 1);\n}\n\nint i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y)\n{\n\tint res = _i2c_send_pkt(idx, x, (u8 *)&y, 1);\n\tif (res)\n\t\tres = _i2c_recv_pkt(idx, buf, size, x);\n\treturn res;\n}\n\nint i2c_send_byte(u32 idx, u32 x, u32 y, u8 b)\n{\n\treturn i2c_send_buf_small(idx, x, y, &b, 1);\n}\n\nu8 i2c_recv_byte(u32 idx, u32 x, u32 y)\n{\n\tu8 tmp = 0;\n\ti2c_recv_buf_small(&tmp, 1, idx, x, y);\n\treturn tmp;\n}\n\n"
  },
  {
    "path": "argon-nx-gui/src/soc/pinmux.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"soc/pinmux.h\"\n#include \"soc/t210.h\"\n\nvoid pinmux_config_uart(u32 idx)\n{\n\tPINMUX_AUX(PINMUX_AUX_UARTX_TX(idx)) = 0;\n\tPINMUX_AUX(PINMUX_AUX_UARTX_RX(idx)) = PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;\n\tPINMUX_AUX(PINMUX_AUX_UARTX_RTS(idx)) = 0;\n\tPINMUX_AUX(PINMUX_AUX_UARTX_CTS(idx)) = PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN;\n}\n\nvoid pinmux_config_i2c(u32 idx)\n{\n\tPINMUX_AUX(PINMUX_AUX_X_I2C_SCL(idx)) = PINMUX_INPUT_ENABLE;\n\tPINMUX_AUX(PINMUX_AUX_X_I2C_SDA(idx)) = PINMUX_INPUT_ENABLE;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/soc/smmu.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (c) 2018 balika011\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"soc/smmu.h\"\n#include \"soc/cluster.h\"\n#include \"soc/t210.h\"\n#include \"mem/mc_t210.h\"\n#include \"utils/util.h\"\n#include \"utils/aarch64_util.h\"\n\nbool smmu_used = false;\nu8 *_pageheap = (u8 *)SMMU_HEAP_ADDR;\n\n//Enabling SMMU requires a TZ secure write: MC(MC_SMMU_CONFIG) = 1;\nu8 smmu_payload[] __attribute__((aligned(16))) = {\n\t0x41, 0x01, 0x00, 0x58, // 0x00: LDR  X1, =0x70019010\n\t0x20, 0x00, 0x80, 0xD2, // 0x04: MOV  X0, #0x1\n\t0x20, 0x00, 0x00, 0xB9, // 0x08: STR  W0, [X1]\n\t0x1F, 0x71, 0x08, 0xD5, // 0x0C: IC   IALLUIS\n\t0x9F, 0x3B, 0x03, 0xD5, // 0x10: DSB  ISH\n\t0xFE, 0xFF, 0xFF, 0x17, // 0x14: B    loop\n\t0x00, 0x00, 0x80, 0xD2, // 0x18: MOV  X0, #0x0\n\t0x20, 0x00, 0x00, 0xB9, // 0x1C: STR  W0, [X1]\n\t0x80, 0x00, 0x00, 0x58, // 0x20: LDR  X0, =0x4002B000\n\t0x00, 0x00, 0x1F, 0xD6, // 0x28: BR   X0\n\t0x10, 0x90, 0x01, 0x70, // 0x28: MC_SMMU_CONFIG\n\t0x00, 0x00, 0x00, 0x00, // 0x2C:\n\t0x00, 0x00, 0x00, 0x00, // 0x30: secmon address\n\t0x00, 0x00, 0x00, 0x00  // 0x34:\n};\n\nvoid *page_alloc(u32 num)\n{\n\tu8 *res = _pageheap;\n\t_pageheap += 0x1000 * num;\n\tmemset(res, 0, 0x1000 * num);\n\treturn res;\n}\n\nu32 *smmu_alloc_pdir()\n{\n\tu32 *pdir = (u32 *)page_alloc(1);\n\tfor (int pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)\n\t\tpdir[pdn] = _PDE_VACANT(pdn);\n\treturn pdir;\n}\n\nvoid smmu_flush_regs()\n{\n\t(void)MC(MC_SMMU_PTB_DATA);\n}\n\nvoid smmu_flush_all()\n{\n\tMC(MC_SMMU_PTC_FLUSH) = 0;\n\tsmmu_flush_regs();\n\tMC(MC_SMMU_TLB_FLUSH) = 0;\n\tsmmu_flush_regs();\n}\n\nvoid smmu_init(u32 secmon_base)\n{\n\tMC(MC_SMMU_PTB_ASID) = 0;\n\tMC(MC_SMMU_PTB_DATA) = 0;\n\tMC(MC_SMMU_TLB_CONFIG) = 0x30000030;\n\tMC(MC_SMMU_PTC_CONFIG) = 0x28000F3F;\n\tMC(MC_SMMU_PTC_FLUSH) = 0;\n\tMC(MC_SMMU_TLB_FLUSH) = 0;\n\n\t// Set the secmon address\n\t*(u32 *)(smmu_payload + 0x30) = secmon_base;\n}\n\nvoid smmu_enable()\n{\n\tif (smmu_used)\n\t\treturn;\n\n\tcluster_boot_cpu0((u32)smmu_payload);\n\tsmmu_used = true;\n\tmsleep(150);\n\n\tsmmu_flush_all();\n}\n\nbool smmu_is_used()\n{\n\treturn smmu_used;\n}\n\nvoid smmu_exit()\n{\n\t*(uint32_t *)(smmu_payload + 0x14) = _NOP();\n}\n\nu32 *smmu_init_domain4(u32 dev_base, u32 asid)\n{\n\tu32 *pdir = smmu_alloc_pdir();\n\n\tMC(MC_SMMU_PTB_ASID) = asid;\n\tMC(MC_SMMU_PTB_DATA) = SMMU_MK_PDIR((u32)pdir, _PDIR_ATTR);\n\tsmmu_flush_regs();\n\n\tMC(dev_base) = 0x80000000 | (asid << 24) | (asid << 16) | (asid << 8) | (asid);\n\tsmmu_flush_regs();\n\n\treturn pdir;\n}\n\nu32 *smmu_get_pte(u32 *pdir, u32 iova)\n{\n\tu32 ptn = SMMU_ADDR_TO_PFN(iova);\n\tu32 pdn = SMMU_ADDR_TO_PDN(iova);\n\tu32 *ptbl;\n\n\tif (pdir[pdn] != _PDE_VACANT(pdn))\n\t\tptbl = (u32 *)((pdir[pdn] & SMMU_PFN_MASK) << SMMU_PDIR_SHIFT);\n\telse\n\t{\n\t\tptbl = (u32 *)page_alloc(1);\n\t\tu32 addr = SMMU_PDN_TO_ADDR(pdn);\n\t\tfor (int pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SMMU_PAGE_SIZE)\n\t\t\tptbl[pn] = _PTE_VACANT(addr);\n\t\tpdir[pdn] = SMMU_MK_PDE((u32)ptbl, _PDE_ATTR | _PDE_NEXT);\n\t\tsmmu_flush_all();\n\t}\n\n\treturn &ptbl[ptn % SMMU_PTBL_COUNT];\n}\n\nvoid smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr)\n{\n\tfor (int i = 0; i < cnt; i++)\n\t{\n\t\tu32 *pte = smmu_get_pte(pdir, addr);\n\t\t*pte = SMMU_ADDR_TO_PFN(page) | attr;\n\t\taddr += 0x1000;\n\t\tpage += 0x1000;\n\t}\n\tsmmu_flush_all();\n}\n\nu32 *smmu_init_for_tsec()\n{\n\treturn smmu_init_domain4(MC_SMMU_TSEC_ASID, 1);\n}\n\nvoid smmu_deinit_for_tsec()\n{\n\tMC(MC_SMMU_PTB_ASID) = 1;\n\tMC(MC_SMMU_PTB_DATA) = 0;\n\tMC(MC_SMMU_TSEC_ASID) = 0;\n\tsmmu_flush_regs();\n}\n\n"
  },
  {
    "path": "argon-nx-gui/src/soc/uart.c",
    "content": "/*\n* Copyright (c) 2018 naehrwert\n*\n* This program is free software; you can redistribute it and/or modify it\n* under the terms and conditions of the GNU General Public License,\n* version 2, as published by the Free Software Foundation.\n*\n* This program is distributed in the hope it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include \"soc/uart.h\"\n#include \"soc/t210.h\"\n#include \"utils/util.h\"\n\n/* UART A, B, C, D and E. */\nstatic const u32 uart_baseoff[5] = { 0, 0x40, 0x200, 0x300, 0x400 };\n\nvoid uart_init(u32 idx, u32 baud)\n{\n\tuart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);\n\n\t// Make sure no data is being sent.\n\tuart_wait_idle(idx, UART_TX_IDLE);\n\n\t// Misc settings.\n\tu32 rate = (8 * baud + 408000000) / (16 * baud);\n\tuart->UART_IER_DLAB = 0; // Disable interrupts.\n\tuart->UART_MCR = 0; // Disable hardware flow control.\n\tuart->UART_LCR = UART_LCR_DLAB | UART_LCR_WORD_LENGTH_8; // Enable DLAB & set 8n1 mode.\n\tuart->UART_THR_DLAB = (u8)rate; // Divisor latch LSB.\n\tuart->UART_IER_DLAB = (u8)(rate >> 8); // Divisor latch MSB.\n\tuart->UART_LCR = UART_LCR_WORD_LENGTH_8; // Diable DLAB.\n\n\t// Setup and flush fifo.\n\tuart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO | UART_IIR_FCR_RX_CLR | UART_IIR_FCR_TX_CLR;\n\tusleep(3 * ((baud + 999999) / baud));\n\tuart_wait_idle(idx, UART_TX_IDLE | UART_RX_IDLE);\n}\n\nvoid uart_wait_idle(u32 idx, u32 which)\n{\n\tuart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);\n\tif (UART_TX_IDLE & which)\n\t{\n\t\twhile (!(uart->UART_LSR & UART_LSR_TMTY))\n\t\t\t;\n\t}\n\tif (UART_RX_IDLE & which)\n\t{\n\t\twhile (uart->UART_LSR & UART_LSR_RDR)\n\t\t\t;\n\t}\n}\n\nvoid uart_send(u32 idx, u8 *buf, u32 len)\n{\n\tuart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);\n\n\tfor (u32 i = 0; i != len; i++)\n\t{\n\t\twhile (!(uart->UART_LSR & UART_LSR_THRE))\n\t\t\t;\n\t\tuart->UART_THR_DLAB = buf[i];\n\t};\n}\n\nvoid uart_recv(u32 idx, u8 *buf, u32 len)\n{\n\tuart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);\n\n\tfor (u32 i = 0; i != len; i++)\n\t{\n\t\twhile (!(uart->UART_LSR & UART_LSR_RDR))\n\t\t\t;\n\t\tbuf[i] = uart->UART_THR_DLAB;\n\t};\n}\n"
  },
  {
    "path": "argon-nx-gui/src/start.s",
    "content": "/*\n* Copyright (c) 2018 naehrwert\n*\n* This program is free software; you can redistribute it and/or modify it\n* under the terms and conditions of the GNU General Public License,\n* version 2, as published by the Free Software Foundation.\n*\n* This program is distributed in the hope it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n.section .text._start\n.arm\n\n.extern _reloc_ipl\n.type _reloc_ipl, %function\n\n.extern memset\n.type memset, %function\n\n.extern ipl_main\n.type ipl_main, %function\n\n.globl _start\n.type _start, %function\n_start:\n\tADR R0, _start\n\tLDR R1, =__ipl_start\n\tCMP R0, R1\n\tBEQ _real_start\n\n\t/* If we are not in the right location already, copy a relocator to upper IRAM. */\n\tADR R2, _reloc_ipl\n\tLDR R3, =0x4003FF00\n\tMOV R4, #(_real_start - _reloc_ipl)\n_copy_loop:\n\tLDMIA R2!, {R5}\n\tSTMIA R3!, {R5}\n\tSUBS R4, #4\n\tBNE _copy_loop\n\n\t/* Use the relocator to copy ourselves into the right place. */\n\tLDR R2, =__ipl_end\n\tSUB R2, R2, R1\n\tLDR R3, =_real_start\n\tLDR R4, =0x4003FF00\n\tBX R4\n\n_reloc_ipl:\n\tLDMIA R0!, {R4-R7}\n\tSTMIA R1!, {R4-R7}\n\tSUBS R2, #0x10\n\tBNE _reloc_ipl\n\t/* Jump to the relocated entry. */\n\tBX R3\n\n_real_start:\n\t/* Initially, we place our stack in IRAM but will move it to SDRAM later. */\n\tLDR SP, =0x4003FF00\n\tLDR R0, =__bss_start\n\tEOR R1, R1, R1\n\tLDR R2, =__bss_end\n\tSUB R2, R2, R0\n\tBL memset\n\tBL ipl_main\n\tB .\n\n.globl pivot_stack\n.type pivot_stack, %function\npivot_stack:\n\tMOV SP, R0\n\tBX LR\n"
  },
  {
    "path": "argon-nx-gui/src/storage/sdmmc.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n#include \"storage/sdmmc.h\"\n#include \"storage/mmc.h\"\n#include \"storage/sd.h\"\n#include \"gfx/gfx.h\"\n#include \"mem/heap.h\"\n#include \"utils/util.h\"\n\n#define DPRINTF(...)\n\n#pragma GCC push_options\n#pragma GCC target (\"thumb\")\n\nstatic inline u32 unstuff_bits(u32 *resp, u32 start, u32 size)\n{\n\tconst u32 mask = (size < 32 ? 1 << size : 0) - 1;\n\tconst u32 off = 3 - ((start) / 32);\n\tconst u32 shft = (start) & 31;\n\tu32 res = resp[off] >> shft;\n\tif (size + shft > 32)\n\t\tres |= resp[off - 1] << ((32 - shft) % 32);\n\treturn res & mask;\n}\n\n/*\n* Common functions for SD and MMC.\n*/\n\nstatic int _sdmmc_storage_check_result(u32 res)\n{\n\t//Error mask:\n\t//R1_OUT_OF_RANGE, R1_ADDRESS_ERROR, R1_BLOCK_LEN_ERROR,\n\t//R1_ERASE_SEQ_ERROR, R1_ERASE_PARAM, R1_WP_VIOLATION,\n\t//R1_LOCK_UNLOCK_FAILED, R1_COM_CRC_ERROR, R1_ILLEGAL_COMMAND,\n\t//R1_CARD_ECC_FAILED, R1_CC_ERROR, R1_ERROR, R1_CID_CSD_OVERWRITE,\n\t//R1_WP_ERASE_SKIP, R1_ERASE_RESET, R1_SWITCH_ERROR\n\tif (!(res & 0xFDF9A080))\n\t\treturn 1;\n\t//TODO: R1_SWITCH_ERROR we can skip for certain card types.\n\treturn 0;\n}\n\nstatic int _sdmmc_storage_execute_cmd_type1_ex(sdmmc_storage_t *storage, u32 *resp, u32 cmd, u32 arg, u32 check_busy, u32 expected_state, u32 mask)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, cmd, arg, SDMMC_RSP_TYPE_1, check_busy);\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0))\n\t\treturn 0;\n\n\tsdmmc_get_rsp(storage->sdmmc, resp, 4, SDMMC_RSP_TYPE_1);\n\tif (mask)\n\t\t*resp &= ~mask;\n\n\tif (_sdmmc_storage_check_result(*resp))\n\t\tif (expected_state == 0x10 || R1_CURRENT_STATE(*resp) == expected_state)\n\t\t\treturn 1;\n\treturn 0;\n}\n\nstatic int _sdmmc_storage_execute_cmd_type1(sdmmc_storage_t *storage, u32 cmd, u32 arg, u32 check_busy, u32 expected_state)\n{\n\tu32 tmp;\n\treturn _sdmmc_storage_execute_cmd_type1_ex(storage, &tmp, cmd, arg, check_busy, expected_state, 0);\n}\n\nstatic int _sdmmc_storage_go_idle_state(sdmmc_storage_t *storage)\n{\n\tsdmmc_cmd_t cmd;\n\tsdmmc_init_cmd(&cmd, MMC_GO_IDLE_STATE, 0, SDMMC_RSP_TYPE_0, 0);\n\treturn sdmmc_execute_cmd(storage->sdmmc, &cmd, 0, 0);\n}\n\nstatic int _sdmmc_storage_get_cid(sdmmc_storage_t *storage, void *buf)\n{\n\tsdmmc_cmd_t cmd;\n\tsdmmc_init_cmd(&cmd, MMC_ALL_SEND_CID, 0, SDMMC_RSP_TYPE_2, 0);\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmd, 0, 0))\n\t\treturn 0;\n\tsdmmc_get_rsp(storage->sdmmc, buf, 0x10, SDMMC_RSP_TYPE_2);\n\treturn 1;\n}\n\nstatic int _sdmmc_storage_select_card(sdmmc_storage_t *storage)\n{\n\treturn _sdmmc_storage_execute_cmd_type1(storage, MMC_SELECT_CARD, storage->rca << 16, 1, 0x10);\n}\n\nstatic int _sdmmc_storage_get_csd(sdmmc_storage_t *storage, void *buf)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, MMC_SEND_CSD, storage->rca << 16, SDMMC_RSP_TYPE_2, 0);\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0))\n\t\treturn 0;\n\tsdmmc_get_rsp(storage->sdmmc, buf, 0x10, SDMMC_RSP_TYPE_2);\n\treturn 1;\n}\n\nstatic int _sdmmc_storage_set_blocklen(sdmmc_storage_t *storage, u32 blocklen)\n{\n\treturn _sdmmc_storage_execute_cmd_type1(storage, MMC_SET_BLOCKLEN, blocklen, 0, R1_STATE_TRAN);\n}\n\nstatic int _sdmmc_storage_get_status(sdmmc_storage_t *storage, u32 *resp, u32 mask)\n{\n\treturn _sdmmc_storage_execute_cmd_type1_ex(storage, resp, MMC_SEND_STATUS, storage->rca << 16, 0, R1_STATE_TRAN, mask);\n}\n\nstatic int _sdmmc_storage_check_status(sdmmc_storage_t *storage)\n{\n\tu32 tmp;\n\treturn _sdmmc_storage_get_status(storage, &tmp, 0);\n}\n\nstatic int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out, u32 sector, u32 num_sectors, void *buf, u32 is_write)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, is_write ? MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK, sector, SDMMC_RSP_TYPE_1, 0);\n\n\tsdmmc_req_t reqbuf;\n\treqbuf.buf = buf;\n\treqbuf.num_sectors = num_sectors;\n\treqbuf.blksize = 512;\n\treqbuf.is_write = is_write;\n\treqbuf.is_multi_block = 1;\n\treqbuf.is_auto_cmd12 = 1;\n\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, blkcnt_out))\n\t{\n\t\tu32 tmp = 0;\n\t\tsdmmc_stop_transmission(storage->sdmmc, &tmp);\n\t\t_sdmmc_storage_get_status(storage, &tmp, 0);\n\t\treturn 0;\n\t}\n\treturn 1;\n}\n\nint sdmmc_storage_end(sdmmc_storage_t *storage)\n{\n\tif (!_sdmmc_storage_go_idle_state(storage))\n\t\treturn 0;\n\tsdmmc_end(storage->sdmmc);\n\treturn 1;\n}\n\nstatic int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf, u32 is_write)\n{\n\tu8 *bbuf = (u8 *)buf;\n\n\twhile (num_sectors)\n\t{\n\t\tu32 blkcnt = 0;\n\t\t//Retry 9 times on error.\n\t\tu32 retries = 10;\n\t\tdo\n\t\t{\n\t\t\tif (_sdmmc_storage_readwrite_ex(storage, &blkcnt, sector, MIN(num_sectors, 0xFFFF), bbuf, is_write))\n\t\t\t\tgoto out;\n\t\t\telse\n\t\t\t\tretries--;\n\n\t\t\tmsleep(100);\n\t\t} while (retries);\n\t\treturn 0;\n\nout:;\n\t\tDPRINTF(\"readwrite: %08X\\n\", blkcnt);\n\t\tsector += blkcnt;\n\t\tnum_sectors -= blkcnt;\n\t\tbbuf += 512 * blkcnt;\n\t}\n\treturn 1;\n}\n\nint sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf)\n{\n\treturn _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 0);\n}\n\nint sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf)\n{\n\treturn _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 1);\n}\n\n/*\n* MMC specific functions.\n*/\n\nstatic int _mmc_storage_get_op_cond_inner(sdmmc_storage_t *storage, u32 *pout, u32 power)\n{\n\tsdmmc_cmd_t cmd;\n\n\tu32 arg = 0;\n\tswitch (power)\n\t{\n\tcase SDMMC_POWER_1_8:\n\t\targ = 0x40000080; //Sector access, voltage.\n\t\tbreak;\n\tcase SDMMC_POWER_3_3:\n\t\targ = 0x403F8000; //Sector access, voltage.\n\t\tbreak;\n\tdefault:\n\t\treturn 0;\n\t}\n\n\tsdmmc_init_cmd(&cmd, MMC_SEND_OP_COND, arg, SDMMC_RSP_TYPE_3, 0);\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmd, 0, 0))\n\t\treturn 0;\n\n\treturn sdmmc_get_rsp(storage->sdmmc, pout, 4, SDMMC_RSP_TYPE_3);\n}\n\nstatic int _mmc_storage_get_op_cond(sdmmc_storage_t *storage, u32 power)\n{\n\tu32 timeout = get_tmr_ms() + 1500;\n\n\twhile (1)\n\t{\n\t\tu32 cond = 0;\n\t\tif (!_mmc_storage_get_op_cond_inner(storage, &cond, power))\n\t\t\tbreak;\n\t\tif (cond & MMC_CARD_BUSY)\n\t\t{\n\t\t\tif (cond & 0x40000000)\n\t\t\t\tstorage->has_sector_access = 1;\n\t\t\treturn 1;\n\t\t}\n\t\tif (get_tmr_ms() > timeout)\n\t\t\tbreak;\n\t\tusleep(1000);\n\t}\n\n\treturn 0;\n}\n\nstatic int _mmc_storage_set_relative_addr(sdmmc_storage_t *storage)\n{\n\treturn _sdmmc_storage_execute_cmd_type1(storage, MMC_SET_RELATIVE_ADDR, storage->rca << 16, 0, 0x10);\n}\n\nstatic void _mmc_storage_parse_cid(sdmmc_storage_t *storage)\n{\n\tu32 *raw_cid = (u32 *)&(storage->raw_cid);\n\n\tswitch (storage->csd.mmca_vsn)\n\t{\n\tcase 0: /* MMC v1.0 - v1.2 */\n\tcase 1: /* MMC v1.4 */\n\t\tstorage->cid.prod_name[6] = unstuff_bits(raw_cid, 48, 8);\n\t\tstorage->cid.manfid = unstuff_bits(raw_cid, 104, 24);\n\t\tstorage->cid.hwrev  = unstuff_bits(raw_cid, 44, 4);\n\t\tstorage->cid.fwrev  = unstuff_bits(raw_cid, 40, 4);\n\t\tstorage->cid.serial = unstuff_bits(raw_cid, 16, 24);\n\t\tbreak;\n\tcase 2: /* MMC v2.0 - v2.2 */\n\tcase 3: /* MMC v3.1 - v3.3 */\n\tcase 4: /* MMC v4 */\n\t\tstorage->cid.manfid   = unstuff_bits(raw_cid, 120, 8);\n\t\tstorage->cid.card_bga = unstuff_bits(raw_cid, 112, 2);\n\t\tstorage->cid.oemid    = unstuff_bits(raw_cid, 104, 8);\n\t\tstorage->cid.prv      = unstuff_bits(raw_cid, 48, 8);\n\t\tstorage->cid.serial   = unstuff_bits(raw_cid, 16, 32);\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\tstorage->cid.prod_name[0] = unstuff_bits(raw_cid, 96, 8);\n\tstorage->cid.prod_name[1] = unstuff_bits(raw_cid, 88, 8);\n\tstorage->cid.prod_name[2] = unstuff_bits(raw_cid, 80, 8);\n\tstorage->cid.prod_name[3] = unstuff_bits(raw_cid, 72, 8);\n\tstorage->cid.prod_name[4] = unstuff_bits(raw_cid, 64, 8);\n\tstorage->cid.prod_name[5] = unstuff_bits(raw_cid, 56, 8);\n\n\tstorage->cid.month = unstuff_bits(raw_cid, 12, 4);\n\tstorage->cid.year  = unstuff_bits(raw_cid, 8, 4) + 1997;\n\tif (storage->ext_csd.rev >= 5)\n\t{\n\t\tif (storage->cid.year < 2010)\n\t\t\tstorage->cid.year += 16;\n\t}\n}\n\nstatic void _mmc_storage_parse_csd(sdmmc_storage_t *storage)\n{\n\tu32 *raw_csd = (u32 *)&(storage->raw_csd);\n\n\tstorage->csd.mmca_vsn = unstuff_bits(raw_csd, 122, 4);\n\tstorage->csd.structure = unstuff_bits(raw_csd, 126, 2);\n\tstorage->csd.cmdclass = unstuff_bits(raw_csd, 84, 12);\n\tstorage->csd.read_blkbits = unstuff_bits(raw_csd, 80, 4);\n\tstorage->csd.capacity = (1 + unstuff_bits(raw_csd, 62, 12)) << (unstuff_bits(raw_csd, 47, 3) + 2);\n}\n\nstatic void _mmc_storage_parse_ext_csd(sdmmc_storage_t *storage, u8 *buf)\n{\n\tstorage->ext_csd.rev = buf[EXT_CSD_REV];\n\tstorage->ext_csd.ext_struct = buf[EXT_CSD_STRUCTURE];\n\tstorage->ext_csd.card_type = buf[EXT_CSD_CARD_TYPE];\n\tstorage->ext_csd.dev_version = *(u16 *)&buf[EXT_CSD_DEVICE_VERSION];\n\tstorage->ext_csd.boot_mult = buf[EXT_CSD_BOOT_MULT];\n\tstorage->ext_csd.rpmb_mult = buf[EXT_CSD_RPMB_MULT];\n\tstorage->ext_csd.sectors = *(u32 *)&buf[EXT_CSD_SEC_CNT];\n\tstorage->ext_csd.bkops = buf[EXT_CSD_BKOPS_SUPPORT];\n\tstorage->ext_csd.bkops_en = buf[EXT_CSD_BKOPS_EN];\n\tstorage->ext_csd.bkops_status = buf[EXT_CSD_BKOPS_STATUS];\n\n\tstorage->sec_cnt  = *(u32 *)&buf[EXT_CSD_SEC_CNT];\n}\n\nstatic int _mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, MMC_SEND_EXT_CSD, 0, SDMMC_RSP_TYPE_1, 0);\n\n\tsdmmc_req_t reqbuf;\n\treqbuf.buf = buf;\n\treqbuf.blksize = 512;\n\treqbuf.num_sectors = 1;\n\treqbuf.is_write = 0;\n\treqbuf.is_multi_block = 0;\n\treqbuf.is_auto_cmd12 = 0;\n\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, 0))\n\t\treturn 0;\n\n\tu32 tmp = 0;\n\tsdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);\n\t_mmc_storage_parse_ext_csd(storage, buf);\n\n\treturn _sdmmc_storage_check_result(tmp);\n}\n\nstatic int _mmc_storage_switch(sdmmc_storage_t *storage, u32 arg)\n{\n\treturn _sdmmc_storage_execute_cmd_type1(storage, MMC_SWITCH, arg, 1, 0x10);\n}\n\nstatic int _mmc_storage_switch_buswidth(sdmmc_storage_t *storage, u32 bus_width)\n{\n\tif (bus_width == SDMMC_BUS_WIDTH_1)\n\t\treturn 1;\n\n\tu32 arg = 0;\n\tswitch (bus_width)\n\t{\n\tcase SDMMC_BUS_WIDTH_4:\n\t\targ = SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4);\n\t\tbreak;\n\tcase SDMMC_BUS_WIDTH_8:\n\t\targ = SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8);\n\t\tbreak;\n\t}\n\n\tif (_mmc_storage_switch(storage, arg))\n\t\tif (_sdmmc_storage_check_status(storage))\n\t\t{\n\t\t\tsdmmc_set_bus_width(storage->sdmmc, bus_width);\n\t\t\treturn 1;\n\t\t}\n\n\treturn 0;\n}\n\nstatic int _mmc_storage_enable_HS(sdmmc_storage_t *storage, int check)\n{\n\tif (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS)))\n\t\treturn 0;\n\tif (check && !_sdmmc_storage_check_status(storage))\n\t\treturn 0;\n\tif (!sdmmc_setup_clock(storage->sdmmc, 2))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] switched to HS\\n\");\n\tstorage->csd.busspeed = 52;\n\tif (check || _sdmmc_storage_check_status(storage))\n\t\treturn 1;\n\treturn 0;\n}\n\nstatic int _mmc_storage_enable_HS200(sdmmc_storage_t *storage)\n{\n\tif (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS200)))\n\t\treturn 0;\n\tif (!sdmmc_setup_clock(storage->sdmmc, 3))\n\t\treturn 0;\n\tif (!sdmmc_config_tuning(storage->sdmmc, 3, MMC_SEND_TUNING_BLOCK_HS200))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] switched to HS200\\n\");\n\tstorage->csd.busspeed = 200;\n\treturn _sdmmc_storage_check_status(storage);\n}\n\nstatic int _mmc_storage_enable_HS400(sdmmc_storage_t *storage)\n{\n\tif (!_mmc_storage_enable_HS200(storage))\n\t\treturn 0;\n\tsdmmc_get_venclkctl(storage->sdmmc);\n\tif (!_mmc_storage_enable_HS(storage, 0))\n\t\treturn 0;\n\tif (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_DDR_BUS_WIDTH_8)))\n\t\treturn 0;\n\tif (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400)))\n\t\treturn 0;\n\tif (!sdmmc_setup_clock(storage->sdmmc, 4))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] switched to HS400\\n\");\n\tstorage->csd.busspeed = 400;\n\treturn _sdmmc_storage_check_status(storage);\n}\n\nstatic int _mmc_storage_enable_highspeed(sdmmc_storage_t *storage, u32 card_type, u32 type)\n{\n\t//TODO: this should be a config item.\n\t// --v\n\tif (!1 || sdmmc_get_voltage(storage->sdmmc) != SDMMC_POWER_1_8)\n\t\tgoto out;\n\n\tif (sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_8 &&\n\t\tcard_type & EXT_CSD_CARD_TYPE_HS400_1_8V &&\n\t\ttype == 4)\n\t\treturn _mmc_storage_enable_HS400(storage);\n\n\tif (sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_8 ||\n\t\t(sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_4\n\t\t&& card_type & EXT_CSD_CARD_TYPE_HS200_1_8V\n\t\t&& (type == 4 || type == 3)))\n\t\treturn _mmc_storage_enable_HS200(storage);\n\nout:;\n\tif (card_type & EXT_CSD_CARD_TYPE_HS_52)\n\t\treturn _mmc_storage_enable_HS(storage, 1);\n\treturn 1;\n}\n\nstatic int _mmc_storage_enable_bkops(sdmmc_storage_t *storage)\n{\n\tif (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_SET_BITS, EXT_CSD_BKOPS_EN, EXT_CSD_BKOPS_LEVEL_2)))\n\t\treturn 0;\n\treturn _sdmmc_storage_check_status(storage);\n}\n\nint sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type)\n{\n\tmemset(storage, 0, sizeof(sdmmc_storage_t));\n\tstorage->sdmmc = sdmmc;\n\tstorage->rca = 2; //TODO: this could be a config item.\n\n\tif (!sdmmc_init(sdmmc, id, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_1, 0, 0))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] after init\\n\");\n\n\tusleep(1000 + (74000 + sdmmc->divisor - 1) / sdmmc->divisor);\n\n\tif (!_sdmmc_storage_go_idle_state(storage))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] went to idle state\\n\");\n\n\tif (!_mmc_storage_get_op_cond(storage, SDMMC_POWER_1_8))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] got op cond\\n\");\n\n\tif (!_sdmmc_storage_get_cid(storage, storage->raw_cid))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] got cid\\n\");\n\n\tif (!_mmc_storage_set_relative_addr(storage))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] set relative addr\\n\");\n\n\tif (!_sdmmc_storage_get_csd(storage, storage->raw_csd))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] got csd\\n\");\n\t_mmc_storage_parse_csd(storage);\n\n\tif (!sdmmc_setup_clock(storage->sdmmc, 1))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] after setup clock\\n\");\n\n\tif (!_sdmmc_storage_select_card(storage))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] card selected\\n\");\n\n\tif (!_sdmmc_storage_set_blocklen(storage, 512))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] set blocklen to 512\\n\");\n\n\tu32 *csd = (u32 *)storage->raw_csd;\n\t//Check system specification version, only version 4.0 and later support below features.\n\tif (unstuff_bits(csd, 122, 4) < CSD_SPEC_VER_4)\n\t{\n\t\tstorage->sec_cnt = (1 + unstuff_bits(csd, 62, 12)) << (unstuff_bits(csd, 47, 3) + 2);\n\t\treturn 1;\n\t}\n\n\tif (!_mmc_storage_switch_buswidth(storage, bus_width))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] switched buswidth\\n\");\n\n\tu8 *ext_csd = (u8 *)malloc(512);\n\tif (!_mmc_storage_get_ext_csd(storage, ext_csd))\n\t{\n\t\tfree(ext_csd);\n\t\treturn 0;\n\t}\n\tfree(ext_csd);\n\tDPRINTF(\"[MMC] got ext_csd\\n\");\n\t_mmc_storage_parse_cid(storage); //This needs to be after csd and ext_csd\n\t//gfx_hexdump(0, ext_csd, 512);\n\n\t/* When auto BKOPS is enabled the mmc device should be powered all the time until we disable this and check status.\n\t   Disable it for now until BKOPS disable added to power down sequence at sdmmc_storage_end().\n\t   Additionally this works only when we put the device in idle mode which we don't after enabling it. */\n\tif (storage->ext_csd.bkops & 0x1 && !(storage->ext_csd.bkops_en & EXT_CSD_BKOPS_LEVEL_2) && 0)\n\t{\n\t\t_mmc_storage_enable_bkops(storage);\n\t\tDPRINTF(\"[MMC] BKOPS enabled\\n\");\n\t}\n\telse\n\t{\n\t\tDPRINTF(\"[MMC] BKOPS disabled\\n\");\n\t}\n\n\tif (!_mmc_storage_enable_highspeed(storage, storage->ext_csd.card_type, type))\n\t\treturn 0;\n\tDPRINTF(\"[MMC] succesfully switched to highspeed mode\\n\");\n\n\tsdmmc_sd_clock_ctrl(storage->sdmmc, 1);\n\n\treturn 1;\n}\n\nint sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition)\n{\n\tif (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_PART_CONFIG, partition)))\n\t\treturn 0;\n\tif (!_sdmmc_storage_check_status(storage))\n\t\treturn 0;\n\tstorage->partition = partition;\n\treturn 1;\n}\n\n/*\n* SD specific functions.\n*/\n\nstatic int _sd_storage_execute_app_cmd(sdmmc_storage_t *storage, u32 expected_state, u32 mask, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out)\n{\n\tu32 tmp;\n\tif (!_sdmmc_storage_execute_cmd_type1_ex(storage, &tmp, MMC_APP_CMD, storage->rca << 16, 0, expected_state, mask))\n\t\treturn 0;\n\treturn sdmmc_execute_cmd(storage->sdmmc, cmd, req, blkcnt_out);\n}\n\nstatic int _sd_storage_execute_app_cmd_type1(sdmmc_storage_t *storage, u32 *resp, u32 cmd, u32 arg, u32 check_busy, u32 expected_state)\n{\n\tif (!_sdmmc_storage_execute_cmd_type1(storage, MMC_APP_CMD, storage->rca << 16, 0, R1_STATE_TRAN))\n\t\treturn 0;\n\treturn _sdmmc_storage_execute_cmd_type1_ex(storage, resp, cmd, arg, check_busy, expected_state, 0);\n}\n\nstatic int _sd_storage_send_if_cond(sdmmc_storage_t *storage)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, 0x1AA, SDMMC_RSP_TYPE_5, 0);\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0))\n\t\treturn 1; // The SD Card is version 1.X\n\n\tu32 resp = 0;\n\tif (!sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_5))\n\t\treturn 2;\n\n\treturn (resp & 0xFF) == 0xAA ? 0 : 2;\n}\n\nstatic int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, int is_version_1, int supports_low_voltage)\n{\n\tsdmmc_cmd_t cmdbuf;\n\t// Support for Current > 150mA\n\tu32 arg = (~is_version_1 & 1) ? SD_OCR_XPC : 0;\n\t// Support for handling block-addressed SDHC cards\n\targ\t|= (~is_version_1 & 1) ? SD_OCR_CCS : 0;\n\t// Support for 1.8V\n\targ |= (supports_low_voltage & ~is_version_1 & 1) ? SD_OCR_S18R : 0;\n\t// This is needed for most cards. Do not set bit7 even if 1.8V is supported.\n\targ |= SD_OCR_VDD_32_33;\n\tsdmmc_init_cmd(&cmdbuf, SD_APP_OP_COND, arg, SDMMC_RSP_TYPE_3, 0);\n\tif (!_sd_storage_execute_app_cmd(storage, 0x10, is_version_1 ? 0x400000 : 0, &cmdbuf, 0, 0))\n\t\treturn 0;\n\treturn sdmmc_get_rsp(storage->sdmmc, cond, 4, SDMMC_RSP_TYPE_3);\n}\n\nstatic int _sd_storage_get_op_cond(sdmmc_storage_t *storage, int is_version_1, int supports_low_voltage)\n{\n\tu32 timeout = get_tmr_ms() + 1500;\n\n\twhile (1)\n\t{\n\t\tu32 cond = 0;\n\t\tif (!_sd_storage_get_op_cond_once(storage, &cond, is_version_1, supports_low_voltage))\n\t\t\tbreak;\n\t\tif (cond & MMC_CARD_BUSY)\n\t\t{\n\t\t\tif (cond & SD_OCR_CCS)\n\t\t\t\tstorage->has_sector_access = 1;\n\n\t\t\tif (cond & SD_ROCR_S18A && supports_low_voltage)\n\t\t\t{\n\t\t\t\t//The low voltage regulator configuration is valid for SDMMC1 only.\n\t\t\t\tif (storage->sdmmc->id == SDMMC_1 &&\n\t\t\t\t\t_sdmmc_storage_execute_cmd_type1(storage, SD_SWITCH_VOLTAGE, 0, 0, R1_STATE_READY))\n\t\t\t\t{\n\t\t\t\t\tif (!sdmmc_enable_low_voltage(storage->sdmmc))\n\t\t\t\t\t\treturn 0;\n\t\t\t\t\tstorage->is_low_voltage = 1;\n\n\t\t\t\t\tDPRINTF(\"-> switched to low voltage\\n\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn 1;\n\t\t}\n\t\tif (get_tmr_ms() > timeout)\n\t\t\tbreak;\n\t\tmsleep(10); // Needs to be at least 10ms for some SD Cards\n\t}\n\n\treturn 0;\n}\n\nstatic int _sd_storage_get_rca(sdmmc_storage_t *storage)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, SD_SEND_RELATIVE_ADDR, 0, SDMMC_RSP_TYPE_4, 0);\n\n\tu32 timeout = get_tmr_ms() + 1500;\n\n\twhile (1)\n\t{\n\t\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0))\n\t\t\tbreak;\n\n\t\tu32 resp = 0;\n\t\tif (!sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_4))\n\t\t\tbreak;\n\n\t\tif (resp >> 16)\n\t\t{\n\t\t\tstorage->rca = resp >> 16;\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (get_tmr_ms() > timeout)\n\t\t\tbreak;\n\t\tusleep(1000);\n\t}\n\n\treturn 0;\n}\n\nstatic void _sd_storage_parse_scr(sdmmc_storage_t *storage)\n{\n\t// unstuff_bits can parse only 4 u32\n\tu32 resp[4];\n\n\tresp[3] = *(u32 *)&storage->raw_scr[4];\n\tresp[2] = *(u32 *)&storage->raw_scr[0];\n\n\tstorage->scr.sda_vsn = unstuff_bits(resp, 56, 4);\n\tstorage->scr.bus_widths = unstuff_bits(resp, 48, 4);\n\tif (storage->scr.sda_vsn == SCR_SPEC_VER_2)\n\t\t/* Check if Physical Layer Spec v3.0 is supported */\n\t\tstorage->scr.sda_spec3 = unstuff_bits(resp, 47, 1);\n\tif (storage->scr.sda_spec3)\n\t\tstorage->scr.cmds = unstuff_bits(resp, 32, 2);\n}\n\nint _sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, SD_APP_SEND_SCR, 0, SDMMC_RSP_TYPE_1, 0);\n\n\tsdmmc_req_t reqbuf;\n\treqbuf.buf = buf;\n\treqbuf.blksize = 8;\n\treqbuf.num_sectors = 1;\n\treqbuf.is_write = 0;\n\treqbuf.is_multi_block = 0;\n\treqbuf.is_auto_cmd12 = 0;\n\n\tif (!_sd_storage_execute_app_cmd(storage, R1_STATE_TRAN, 0, &cmdbuf, &reqbuf, 0))\n\t\treturn 0;\n\n\tu32 tmp = 0;\n\tsdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);\n\t//Prepare buffer for unstuff_bits\n\tfor (int i = 0; i < 8; i+=4)\n\t{\n\t\tstorage->raw_scr[i + 3] = buf[i];\n\t\tstorage->raw_scr[i + 2] = buf[i + 1];\n\t\tstorage->raw_scr[i + 1] = buf[i + 2];\n\t\tstorage->raw_scr[i]     = buf[i + 3];\n\t}\n\t_sd_storage_parse_scr(storage);\n\t//gfx_hexdump(0, storage->raw_scr, 8);\n\n\treturn _sdmmc_storage_check_result(tmp);\n}\n\nint _sd_storage_switch_get(sdmmc_storage_t *storage, void *buf)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, SD_SWITCH, 0xFFFFFF, SDMMC_RSP_TYPE_1, 0);\n\n\tsdmmc_req_t reqbuf;\n\treqbuf.buf = buf;\n\treqbuf.blksize = 64;\n\treqbuf.num_sectors = 1;\n\treqbuf.is_write = 0;\n\treqbuf.is_multi_block = 0;\n\treqbuf.is_auto_cmd12 = 0;\n\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, 0))\n\t\treturn 0;\n\n\tu32 tmp = 0;\n\tsdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);\n\treturn _sdmmc_storage_check_result(tmp);\n}\n\nint _sd_storage_switch(sdmmc_storage_t *storage, void *buf, int mode, int group, u32 arg)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tu32 switchcmd = mode << 31 | 0x00FFFFFF;\n\tswitchcmd &= ~(0xF << (group * 4));\n\tswitchcmd |= arg << (group * 4);\n\tsdmmc_init_cmd(&cmdbuf, SD_SWITCH, switchcmd, SDMMC_RSP_TYPE_1, 0);\n\n\tsdmmc_req_t reqbuf;\n\treqbuf.buf = buf;\n\treqbuf.blksize = 64;\n\treqbuf.num_sectors = 1;\n\treqbuf.is_write = 0;\n\treqbuf.is_multi_block = 0;\n\treqbuf.is_auto_cmd12 = 0;\n\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, 0))\n\t\treturn 0;\n\n\tu32 tmp = 0;\n\tsdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);\n\treturn _sdmmc_storage_check_result(tmp);\n}\n\nvoid _sd_storage_set_current_limit(sdmmc_storage_t *storage, u8 *buf)\n{\n\tu32 pwr = SD_SET_CURRENT_LIMIT_800;\n\t_sd_storage_switch(storage, buf, SD_SWITCH_SET, 3, pwr);\n\n\twhile (pwr > 0)\n\t{\n\t\tpwr--;\n\t\t_sd_storage_switch(storage, buf, SD_SWITCH_SET, 3, pwr);\n\t\tif (((buf[15] >> 4) & 0x0F) == pwr)\n\t\t\tbreak;\n\t}\n\n\tswitch (pwr)\n\t{\n\tcase SD_SET_CURRENT_LIMIT_800:\n\t\tDPRINTF(\"[SD] Power limit raised to 800mA\\n\");\n\t\tbreak;\n\tcase SD_SET_CURRENT_LIMIT_600:\n\t\tDPRINTF(\"[SD] Power limit raised to 600mA\\n\");\n\t\tbreak;\n\tcase SD_SET_CURRENT_LIMIT_400:\n\t\tDPRINTF(\"[SD] Power limit raised to 800mA\\n\");\n\t\tbreak;\n\tdefault:\n\tcase SD_SET_CURRENT_LIMIT_200:\n\t\tDPRINTF(\"[SD] Power limit defaulted to 200mA\\n\");\n\t\tbreak;\n\t}\n}\n\nint _sd_storage_enable_highspeed(sdmmc_storage_t *storage, u32 hs_type, u8 *buf)\n{\n\tif (!_sd_storage_switch(storage, buf, SD_SWITCH_CHECK, 0, hs_type))\n\t\treturn 0;\n\n\tu32 type_out = buf[16] & 0xF;\n\tif (type_out != hs_type)\n\t\treturn 0;\n\n\tif ((((u16)buf[0] << 8) | buf[1]) < 0x320)\n\t{\n\t\tif (!_sd_storage_switch(storage, buf, SD_SWITCH_SET, 0, hs_type))\n\t\t\treturn 0;\n\n\t\tif (type_out != (buf[16] & 0xF))\n\t\t\treturn 0;\n\t}\n\n\treturn 1;\n}\n\nint _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8 *buf)\n{\n\t// Try to raise the current limit to let the card perform better.\n\t_sd_storage_set_current_limit(storage, buf);\n\n\tif (sdmmc_get_bus_width(storage->sdmmc) != SDMMC_BUS_WIDTH_4)\n\t\treturn 0;\n\n\tif (!_sd_storage_switch_get(storage, buf))\n\t\treturn 0;\n\t//gfx_hexdump(0, (u8 *)buf, 64);\n\n\tu32 hs_type = 0;\n\tswitch (type)\n\t{\n\tcase 11:\n\t\t// Fall through if not supported.\n\t\tif (buf[13] & SD_MODE_UHS_SDR104)\n\t\t{\n\t\t\ttype = 11;\n\t\t\ths_type = UHS_SDR104_BUS_SPEED;\n\t\t\tDPRINTF(\"[SD] Bus speed set to SDR104\\n\");\n\t\t\tstorage->csd.busspeed = 104;\n\t\t\tbreak;\n\t\t}\n\tcase 10:\n\t\tif (buf[13] & SD_MODE_UHS_SDR50)\n\t\t{\n\t\t\ttype = 10;\n\t\t\ths_type = UHS_SDR50_BUS_SPEED;\n\t\t\tDPRINTF(\"[SD] Bus speed set to SDR50\\n\");\n\t\t\tstorage->csd.busspeed = 50;\n\t\t\tbreak;\n\t\t}\n\tcase 8:\n\t\tif (!(buf[13] & SD_MODE_UHS_SDR12))\n\t\t\treturn 0;\n\t\ttype = 8;\n\t\ths_type = UHS_SDR12_BUS_SPEED;\n\t\tDPRINTF(\"[SD] Bus speed set to SDR12\\n\");\n\t\tstorage->csd.busspeed = 12;\n\t\tbreak;\n\tdefault:\n\t\treturn 0;\n\t\tbreak;\n\t}\n\n\tif (!_sd_storage_enable_highspeed(storage, hs_type, buf))\n\t\treturn 0;\n\tif (!sdmmc_setup_clock(storage->sdmmc, type))\n\t\treturn 0;\n\tif (!sdmmc_config_tuning(storage->sdmmc, type, MMC_SEND_TUNING_BLOCK))\n\t\treturn 0;\n\treturn _sdmmc_storage_check_status(storage);\n}\n\nint _sd_storage_enable_highspeed_high_volt(sdmmc_storage_t *storage, u8 *buf)\n{\n\tif (!_sd_storage_switch_get(storage, buf))\n\t\treturn 0;\n\t//gfx_hexdump(0, (u8 *)buf, 64);\n\tif (!(buf[13] & SD_MODE_HIGH_SPEED))\n\t\treturn 1;\n\n\tif (!_sd_storage_enable_highspeed(storage, 1, buf))\n\t\treturn 0;\n\tif (!_sdmmc_storage_check_status(storage))\n\t\treturn 0;\n\treturn sdmmc_setup_clock(storage->sdmmc, 7);\n}\n\nstatic void _sd_storage_parse_ssr(sdmmc_storage_t *storage)\n{\n\t// unstuff_bits supports only 4 u32 so break into 2 x 16byte groups\n\tu32 raw_ssr1[4];\n\tu32 raw_ssr2[4];\n\n\traw_ssr1[3] = *(u32 *)&storage->raw_ssr[12];\n\traw_ssr1[2] = *(u32 *)&storage->raw_ssr[8];\n\traw_ssr1[1] = *(u32 *)&storage->raw_ssr[4];\n\traw_ssr1[0] = *(u32 *)&storage->raw_ssr[0];\n\n\traw_ssr2[3] = *(u32 *)&storage->raw_ssr[28];\n\traw_ssr2[2] = *(u32 *)&storage->raw_ssr[24];\n\traw_ssr2[1] = *(u32 *)&storage->raw_ssr[20];\n\traw_ssr2[0] = *(u32 *)&storage->raw_ssr[16];\n\n\tstorage->ssr.bus_width = (unstuff_bits(raw_ssr1, 510 - 384, 2) & SD_BUS_WIDTH_4) ? 4 : 1;\n\tswitch(unstuff_bits(raw_ssr1, 440 - 384, 8))\n\t{\n\tcase 0:\n\t\tstorage->ssr.speed_class = 0;\n\t\tbreak;\n\tcase 1:\n\t\tstorage->ssr.speed_class = 2;\n\t\tbreak;\n\tcase 2:\n\t\tstorage->ssr.speed_class = 4;\n\t\tbreak;\n\tcase 3:\n\t\tstorage->ssr.speed_class = 6;\n\t\tbreak;\n\tcase 4:\n\t\tstorage->ssr.speed_class = 10;\n\t\tbreak;\n\tdefault:\n\t\tstorage->ssr.speed_class = unstuff_bits(raw_ssr1, 440 - 384, 8);\n\t\tbreak;\n\t}\n\tstorage->ssr.uhs_grade = unstuff_bits(raw_ssr1, 396 - 384, 4);\n\tstorage->ssr.video_class = unstuff_bits(raw_ssr1, 384 - 384, 8);\n\n\tstorage->ssr.app_class = unstuff_bits(raw_ssr2, 336 - 256, 4);\n}\n\nstatic int _sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, SD_APP_SD_STATUS, 0, SDMMC_RSP_TYPE_1, 0);\n\n\tsdmmc_req_t reqbuf;\n\treqbuf.buf = buf;\n\treqbuf.blksize = 64;\n\treqbuf.num_sectors = 1;\n\treqbuf.is_write = 0;\n\treqbuf.is_multi_block = 0;\n\treqbuf.is_auto_cmd12 = 0;\n\n\tif (!(storage->csd.cmdclass & CCC_APP_SPEC))\n\t{\n\t\tDPRINTF(\"[SD] ssr: Card lacks mandatory SD Status function\\n\");\n\t\treturn 0;\n\t}\n\n\tif (!_sd_storage_execute_app_cmd(storage, R1_STATE_TRAN, 0, &cmdbuf, &reqbuf, 0))\n\t\treturn 0;\n\n\tu32 tmp = 0;\n\tsdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);\n    //Prepare buffer for unstuff_bits\n\tfor (int i = 0; i < 64; i+=4)\n\t{\n\t\tstorage->raw_ssr[i + 3] = buf[i];\n\t\tstorage->raw_ssr[i + 2] = buf[i + 1];\n\t\tstorage->raw_ssr[i + 1] = buf[i + 2];\n\t\tstorage->raw_ssr[i]     = buf[i + 3];\n\t}\n\t_sd_storage_parse_ssr(storage);\n\t//gfx_hexdump(0, storage->raw_ssr, 64);\n\n\treturn _sdmmc_storage_check_result(tmp);\n}\n\nstatic void _sd_storage_parse_cid(sdmmc_storage_t *storage)\n{\n\tu32 *raw_cid = (u32 *)&(storage->raw_cid);\n\n\tstorage->cid.manfid = unstuff_bits(raw_cid, 120, 8);\n\tstorage->cid.oemid  = unstuff_bits(raw_cid, 104, 16);\n\tstorage->cid.prod_name[0] = unstuff_bits(raw_cid, 96, 8);\n\tstorage->cid.prod_name[1] = unstuff_bits(raw_cid, 88, 8);\n\tstorage->cid.prod_name[2] = unstuff_bits(raw_cid, 80, 8);\n\tstorage->cid.prod_name[3] = unstuff_bits(raw_cid, 72, 8);\n\tstorage->cid.prod_name[4] = unstuff_bits(raw_cid, 64, 8);\n\tstorage->cid.hwrev  = unstuff_bits(raw_cid, 60, 4);\n\tstorage->cid.fwrev  = unstuff_bits(raw_cid, 56, 4);\n\tstorage->cid.serial = unstuff_bits(raw_cid, 24, 32);\n\tstorage->cid.month  = unstuff_bits(raw_cid, 8, 4);\n\tstorage->cid.year   = unstuff_bits(raw_cid, 12, 8) + 2000;\n}\n\nstatic void _sd_storage_parse_csd(sdmmc_storage_t *storage)\n{\n\tu32 *raw_csd = (u32 *)&(storage->raw_csd);\n\n\tstorage->csd.structure = unstuff_bits(raw_csd, 126, 2);\n\tstorage->csd.cmdclass  = unstuff_bits(raw_csd, 84, 12);\n\tstorage->csd.read_blkbits  = unstuff_bits(raw_csd, 80, 4);\n\tstorage->csd.write_protect = unstuff_bits(raw_csd, 12, 2);\n\tswitch(storage->csd.structure)\n\t{\n\tcase 0:\n\t\tstorage->csd.capacity = (1 + unstuff_bits(raw_csd, 62, 12)) << (unstuff_bits(raw_csd, 47, 3) + 2);\n\t\tbreak;\n\tcase 1:\n\t\tstorage->csd.c_size = (1 + unstuff_bits(raw_csd, 48, 22));\n\t\tstorage->csd.capacity = storage->csd.c_size << 10;\n\t\tstorage->csd.read_blkbits = 9;\n\t\tbreak;\n\t}\n}\n\nint sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type)\n{\n\tint is_version_1 = 0;\n\t\n\t// Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.\n\tmsleep(100);\n\n\tmemset(storage, 0, sizeof(sdmmc_storage_t));\n\tstorage->sdmmc = sdmmc;\n\n\tif (!sdmmc_init(sdmmc, id, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, 5, 0))\n\t\treturn 0;\n\tDPRINTF(\"[SD] after init\\n\");\n\n\tusleep(1000 + (74000 + sdmmc->divisor - 1) / sdmmc->divisor);\n\n\tif (!_sdmmc_storage_go_idle_state(storage))\n\t\treturn 0;\n\tDPRINTF(\"[SD] went to idle state\\n\");\n\n\tis_version_1 = _sd_storage_send_if_cond(storage);\n\tif (is_version_1 == 2)\n\t\treturn 0;\n\tDPRINTF(\"[SD] after send if cond\\n\");\n\n\tif (!_sd_storage_get_op_cond(storage, is_version_1, bus_width == SDMMC_BUS_WIDTH_4 && type == 11))\n\t\treturn 0;\n\tDPRINTF(\"[SD] got op cond\\n\");\n\n\tif (!_sdmmc_storage_get_cid(storage, storage->raw_cid))\n\t\treturn 0;\n\tDPRINTF(\"[SD] got cid\\n\");\n\t_sd_storage_parse_cid(storage);\n\n\tif (!_sd_storage_get_rca(storage))\n\t\treturn 0;\n\tDPRINTF(\"[SD] got rca (= %04X)\\n\", storage->rca);\n\n\tif (!_sdmmc_storage_get_csd(storage, storage->raw_csd))\n\t\treturn 0;\n\tDPRINTF(\"[SD] got csd\\n\");\n\n\t//Parse CSD.\n\t_sd_storage_parse_csd(storage);\n\tswitch (storage->csd.structure)\n\t{\n\tcase 0:\n\t\tstorage->sec_cnt = storage->csd.capacity;\n\t\tbreak;\n\tcase 1:\n\t\tstorage->sec_cnt = storage->csd.c_size << 10;\n\t\tbreak;\n\tdefault:\n\t\tDPRINTF(\"[SD] Unknown CSD structure %d\\n\", storage->csd.structure);\n\t\tbreak;\n\t}\n\n\tif (!storage->is_low_voltage)\n\t{\n\t\tif (!sdmmc_setup_clock(storage->sdmmc, 6))\n\t\t\treturn 0;\n\t\tDPRINTF(\"[SD] after setup clock\\n\");\n\t}\n\n\tif (!_sdmmc_storage_select_card(storage))\n\t\treturn 0;\n\tDPRINTF(\"[SD] card selected\\n\");\n\n\tif (!_sdmmc_storage_set_blocklen(storage, 512))\n\t\treturn 0;\n\tDPRINTF(\"[SD] set blocklen to 512\\n\");\n\n\tu32 tmp = 0;\n\tif (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_CLR_CARD_DETECT, 0, 0, R1_STATE_TRAN))\n\t\treturn 0;\n\tDPRINTF(\"[SD] cleared card detect\\n\");\n\n\tu8 *buf = (u8 *)malloc(512);\n\tif (!_sd_storage_get_scr(storage, buf))\n\t{\n\t\tfree(buf);\n\t\treturn 0;\n\t}\n\t\t\n\t//gfx_hexdump(0, storage->raw_scr, 8);\n\tDPRINTF(\"[SD] got scr\\n\");\n\n\t// Check if card supports a wider bus and if it's not SD Version 1.X\n\tif (bus_width == SDMMC_BUS_WIDTH_4 && (storage->scr.bus_widths & 4) && (storage->scr.sda_vsn & 0xF))\n\t{\n\t\tif (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_BUS_WIDTH, SD_BUS_WIDTH_4, 0, R1_STATE_TRAN))\n\t\t{\n\t\t\tfree(buf);\n\t\t\treturn 0;\n\t\t}\n\t\tsdmmc_set_bus_width(storage->sdmmc, SDMMC_BUS_WIDTH_4);\n\t\tDPRINTF(\"[SD] switched to wide bus width\\n\");\n\t}\n\telse\n\t{\n\t\tDPRINTF(\"[SD] SD does not support wide bus width\\n\");\n\t}\n\n\tif (storage->is_low_voltage)\n\t{\n\t\tif (!_sd_storage_enable_highspeed_low_volt(storage, type, buf))\n\t\t{\n\t\t\tfree(buf);\n\t\t\treturn 0;\n\t\t}\n\t\tDPRINTF(\"[SD] enabled highspeed (low voltage)\\n\");\n\t}\n\telse if (type != 6 && (storage->scr.sda_vsn & 0xF) != 0)\n\t{\n\t\tif (!_sd_storage_enable_highspeed_high_volt(storage, buf))\n\t\t{\n\t\t\tfree(buf);\n\t\t\treturn 0;\n\t\t}\n\t\tDPRINTF(\"[SD] enabled highspeed (high voltage)\\n\");\n\t\tstorage->csd.busspeed = 25;\n\t}\n\n\tsdmmc_sd_clock_ctrl(sdmmc, 1);\n\n\t// Parse additional card info from sd status.\n\tif (_sd_storage_get_ssr(storage, buf))\n\t{\n\t\tDPRINTF(\"[SD] got sd status\\n\");\n\t}\n\n\tfree(buf);\n\treturn 1;\n}\n\n/*\n* Gamecard specific functions.\n*/\n\nint _gc_storage_custom_cmd(sdmmc_storage_t *storage, void *buf)\n{\n\tu32 resp;\n\tsdmmc_cmd_t cmdbuf;\n\tsdmmc_init_cmd(&cmdbuf, 60, 0, SDMMC_RSP_TYPE_1, 1);\n\n\tsdmmc_req_t reqbuf;\n\treqbuf.buf = buf;\n\treqbuf.blksize = 64;\n\treqbuf.num_sectors = 1;\n\treqbuf.is_write = 1;\n\treqbuf.is_multi_block = 0;\n\treqbuf.is_auto_cmd12 = 0;\n\n\tif (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, 0))\n\t{\n\t\tsdmmc_stop_transmission(storage->sdmmc, &resp);\n\t\treturn 0;\n\t}\n\n\tif (!sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_1))\n\t\treturn 0;\n\tif (!_sdmmc_storage_check_result(resp))\n\t\treturn 0;\n\treturn _sdmmc_storage_check_status(storage);\n}\n\nint sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc)\n{\n\tmemset(storage, 0, sizeof(sdmmc_storage_t));\n\tstorage->sdmmc = sdmmc;\n\n\tif (!sdmmc_init(sdmmc, SDMMC_2, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_8, 14, 0))\n\t\treturn 0;\n\tDPRINTF(\"[gc] after init\\n\");\n\n\tusleep(1000 + (10000 + sdmmc->divisor - 1) / sdmmc->divisor);\n\n\tif (!sdmmc_config_tuning(storage->sdmmc, 14, MMC_SEND_TUNING_BLOCK_HS200))\n\t\treturn 0;\n\tDPRINTF(\"[gc] after tuning\\n\");\n\n\tsdmmc_sd_clock_ctrl(sdmmc, 1);\n\n\treturn 1;\n}\n\n#pragma GCC pop_options\n"
  },
  {
    "path": "argon-nx-gui/src/storage/sdmmc_driver.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"storage/mmc.h\"\n#include \"storage/sdmmc.h\"\n#include \"gfx/gfx.h\"\n#include \"power/max7762x.h\"\n#include \"soc/bpmp.h\"\n#include \"soc/clock.h\"\n#include \"soc/gpio.h\"\n#include \"soc/pinmux.h\"\n#include \"soc/pmc.h\"\n#include \"soc/t210.h\"\n#include \"utils/util.h\"\n\n//#define DPRINTF(...) gfx_printf(__VA_ARGS__)\n#define DPRINTF(...)\n\n\n/*! SCMMC controller base addresses. */\nstatic const u32 _sdmmc_bases[4] = {\n\t0x700B0000,\n\t0x700B0200,\n\t0x700B0400,\n\t0x700B0600,\n};\n\nint sdmmc_get_voltage(sdmmc_t *sdmmc)\n{\n\tu32 p = sdmmc->regs->pwrcon;\n\tif (!(p & TEGRA_MMC_PWRCTL_SD_BUS_POWER))\n\t\treturn SDMMC_POWER_OFF;\n\tif (p & TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8)\n\t\treturn SDMMC_POWER_1_8;\n\tif (p & TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3)\n\t\treturn SDMMC_POWER_3_3;\n\treturn -1;\n}\n\nstatic int _sdmmc_set_voltage(sdmmc_t *sdmmc, u32 power)\n{\n\tu8 pwr = 0;\n\n\tswitch (power)\n\t{\n\tcase SDMMC_POWER_OFF:\n\t\tsdmmc->regs->pwrcon &= ~TEGRA_MMC_PWRCTL_SD_BUS_POWER;\n\t\tbreak;\n\tcase SDMMC_POWER_1_8:\n\t\tsdmmc->regs->pwrcon = TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8;\n\t\tpwr = TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8;\n\t\tbreak;\n\tcase SDMMC_POWER_3_3:\n\t\tsdmmc->regs->pwrcon = TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3;\n\t\tpwr = TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3;\n\t\tbreak;\n\tdefault:\n\t\treturn 0;\n\t}\n\n\tif (power != SDMMC_POWER_OFF)\n\t{\n\t\tpwr |= TEGRA_MMC_PWRCTL_SD_BUS_POWER;\n\t\tsdmmc->regs->pwrcon = pwr;\n\t}\t\n\n\treturn 1;\n}\n\nu32 sdmmc_get_bus_width(sdmmc_t *sdmmc)\n{\n\tu32 h = sdmmc->regs->hostctl;\n\tif (h & TEGRA_MMC_HOSTCTL_8BIT)\n\t\treturn SDMMC_BUS_WIDTH_8;\n\tif (h & TEGRA_MMC_HOSTCTL_4BIT)\n\t\treturn SDMMC_BUS_WIDTH_4;\n\treturn SDMMC_BUS_WIDTH_1;\n}\n\nvoid sdmmc_set_bus_width(sdmmc_t *sdmmc, u32 bus_width)\n{\n\tif (bus_width == SDMMC_BUS_WIDTH_1)\n\t\tsdmmc->regs->hostctl &= ~(TEGRA_MMC_HOSTCTL_4BIT | TEGRA_MMC_HOSTCTL_8BIT);\n\telse if (bus_width == SDMMC_BUS_WIDTH_4)\n\t{\n\t\tsdmmc->regs->hostctl |= TEGRA_MMC_HOSTCTL_4BIT;\n\t\tsdmmc->regs->hostctl &= ~TEGRA_MMC_HOSTCTL_8BIT;\n\t}\n\telse if (bus_width == SDMMC_BUS_WIDTH_8)\n\t\tsdmmc->regs->hostctl |= TEGRA_MMC_HOSTCTL_8BIT;\n}\n\nvoid sdmmc_get_venclkctl(sdmmc_t *sdmmc)\n{\n\tsdmmc->venclkctl_tap = sdmmc->regs->venclkctl >> 16;\n\tsdmmc->venclkctl_set = 1;\n}\n\nstatic int _sdmmc_config_ven_ceata_clk(sdmmc_t *sdmmc, u32 id)\n{\n\tu32 tap_val = 0;\n\n\tif (id == 4)\n\t\tsdmmc->regs->venceatactl = (sdmmc->regs->venceatactl & 0xFFFFC0FF) | 0x2800;\n\tsdmmc->regs->ventunctl0 &= 0xFFFDFFFF;\n\tif (id == 4)\n\t{\n\t\tif (!sdmmc->venclkctl_set)\n\t\t\treturn 0;\n\t\ttap_val = sdmmc->venclkctl_tap;\n\t}\n\telse\n\t{\n\t\tstatic const u32 tap_values[] = { 4, 0, 3, 0 };\n\t\ttap_val = tap_values[sdmmc->id];\n\t}\n\tsdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (tap_val << 16);\n\n\treturn 1;\n}\n\nstatic int _sdmmc_get_clkcon(sdmmc_t *sdmmc)\n{\n\treturn sdmmc->regs->clkcon;\n}\n\nstatic void _sdmmc_pad_config_fallback(sdmmc_t *sdmmc, u32 power)\n{\n\t_sdmmc_get_clkcon(sdmmc);\n\tswitch (sdmmc->id)\n\t{\n\tcase SDMMC_1:\n\t\tif (power == SDMMC_POWER_OFF)\n\t\t\tbreak;\n\t\tif (power == SDMMC_POWER_1_8)\n\t\t\tAPB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = 0x304; // Up: 3, Dn: 4.\n\t\telse if (power == SDMMC_POWER_3_3)\n\t\t\tAPB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = 0x808; // Up: 8, Dn: 8.\n\t\tbreak;\n\tcase SDMMC_4:\n\t\tAPB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) & 0x3FFC) | 0x1040;\n\t\tbreak;\n\t}\n\t//TODO: load standard values for other controllers, can depend on power.\n}\n\nstatic int _sdmmc_wait_type4(sdmmc_t *sdmmc)\n{\n\tint res = 1, should_disable_sd_clock = 0;\n\n\tif (!(sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE))\n\t{\n\t\tshould_disable_sd_clock = 1;\n\t\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t}\n\n\tsdmmc->regs->vendllcal |= 0x80000000;\n\t_sdmmc_get_clkcon(sdmmc);\n\n\tu32 timeout = get_tmr_ms() + 5;\n\twhile (sdmmc->regs->vendllcal & 0x80000000)\n\t{\n\t\tif (get_tmr_ms() > timeout)\n\t\t{\n\t\t\tres = 0;\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\ttimeout = get_tmr_ms() + 10;\n\twhile (sdmmc->regs->dllcfgstatus & 0x80000000)\n\t{\n\t\tif (get_tmr_ms() > timeout)\n\t\t{\n\t\t\tres = 0;\n\t\t\tgoto out;\n\t\t}\n\t}\n\nout:;\n\tif (should_disable_sd_clock)\n\t\tsdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\treturn res;\n}\n\nint sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)\n{\n\t// Disable the SD clock if it was enabled, and reenable it later.\n\tbool should_enable_sd_clock = false;\n\tif (sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE)\n\t{\n\t\tshould_enable_sd_clock = true;\n\t\tsdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t}\n\n\t_sdmmc_config_ven_ceata_clk(sdmmc, type);\n\n\tswitch (type)\n\t{\n\tcase 0:\n\tcase 1:\n\tcase 5:\n\tcase 6:\n\t\tsdmmc->regs->hostctl  &= 0xFB; // Should this be 0xFFFB (~4) ?\n\t\tsdmmc->regs->hostctl2 &= SDHCI_CTRL_VDD_330;\n\t\tbreak;\n\tcase 2:\n\tcase 7:\n\t\tsdmmc->regs->hostctl  |= 4;\n\t\tsdmmc->regs->hostctl2 &= SDHCI_CTRL_VDD_330;\n\t\tbreak;\n\tcase 3:\n\tcase 11:\n\tcase 13:\n\tcase 14:\n\t\tsdmmc->regs->hostctl2  = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR104_BUS_SPEED;\n\t\tsdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;\n\t\tbreak;\n\tcase 4:\n\t\t // Non standard\n\t\tsdmmc->regs->hostctl2  = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | HS400_BUS_SPEED;\n\t\tsdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;\n\t\tbreak;\n\tcase 8:\n\t\tsdmmc->regs->hostctl2  = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR12_BUS_SPEED;\n\t\tsdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;\n\t\tbreak;\n\tcase 10:\n\t\t// T210 Errata for SDR50, the host must be set to SDR104.\n\t\tsdmmc->regs->hostctl2  = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR104_BUS_SPEED;\n\t\tsdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;\n\t\tbreak;\n\t}\n\n\t_sdmmc_get_clkcon(sdmmc);\n\n\tu32 tmp;\n\tu16 divisor;\n\tclock_sdmmc_get_params(&tmp, &divisor, type);\n\tclock_sdmmc_config_clock_source(&tmp, sdmmc->id, tmp);\n\tsdmmc->divisor = (tmp + divisor - 1) / divisor;\n\n\t//if divisor != 1 && divisor << 31 -> error\n\n\tu16 div = divisor >> 1;\n\tdivisor = 0;\n\tif (div > 0xFF)\n\t\tdivisor = div >> 8;\n\tsdmmc->regs->clkcon = (sdmmc->regs->clkcon & 0x3F) | (div << 8) | (divisor << 6);\n\n\t// Enable the SD clock again.\n\tif (should_enable_sd_clock)\n\t\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\n\tif (type == 4)\n\t\treturn _sdmmc_wait_type4(sdmmc);\n\treturn 1;\n}\n\nstatic void _sdmmc_sd_clock_enable(sdmmc_t *sdmmc)\n{\n\tif (!sdmmc->no_sd)\n\t{\n\t\tif (!(sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE))\n\t\t\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t}\n\tsdmmc->sd_clock_enabled = 1;\n}\n\nstatic void _sdmmc_sd_clock_disable(sdmmc_t *sdmmc)\n{\n\tsdmmc->sd_clock_enabled = 0;\n\tsdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n}\n\nvoid sdmmc_sd_clock_ctrl(sdmmc_t *sdmmc, int no_sd)\n{\n\tsdmmc->no_sd = no_sd;\n\tif (no_sd)\n\t{\n\t\tif (!(sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE))\n\t\t\treturn;\n\t\tsdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t\treturn;\n\t}\n\tif (sdmmc->sd_clock_enabled)\n\t\tif (!(sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE))\n\t\t\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n}\n\nstatic int _sdmmc_cache_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)\n{\n\tswitch (type)\n\t{\n\tcase SDMMC_RSP_TYPE_1:\n\tcase SDMMC_RSP_TYPE_3:\n\tcase SDMMC_RSP_TYPE_4:\n\tcase SDMMC_RSP_TYPE_5:\n\t\tif (size < 4)\n\t\t\treturn 0;\n\t\trsp[0] = sdmmc->regs->rspreg0;\n\t\tbreak;\n\tcase SDMMC_RSP_TYPE_2:\n\t\tif (size < 0x10)\n\t\t\treturn 0;\n\t\t// CRC is stripped, so shifting is needed.\n\t\tu32 tempreg;\n\t\tfor (int i = 0; i < 4; i++)\n\t\t{\n\t\t\tswitch(i)\n\t\t\t{\n\t\t\tcase 0:\n\t\t\t\ttempreg = sdmmc->regs->rspreg3;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\ttempreg = sdmmc->regs->rspreg2;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\ttempreg = sdmmc->regs->rspreg1;\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\ttempreg = sdmmc->regs->rspreg0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\trsp[i] = tempreg << 8;\n\n\t\t\tif (i != 0)\n\t\t\t\trsp[i - 1] |= (tempreg >> 24) & 0xFF;\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\treturn 0;\n\t\tbreak;\n\t}\n\n\treturn 1;\n}\n\nint sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)\n{\n\tif (!rsp || sdmmc->expected_rsp_type != type)\n\t\treturn 0;\n\n\tswitch (type)\n\t{\n\tcase SDMMC_RSP_TYPE_1:\n\tcase SDMMC_RSP_TYPE_3:\n\tcase SDMMC_RSP_TYPE_4:\n\tcase SDMMC_RSP_TYPE_5:\n\t\tif (size < 4)\n\t\t\treturn 0;\n\t\trsp[0] = sdmmc->rsp[0];\n\t\tbreak;\n\tcase SDMMC_RSP_TYPE_2:\n\t\tif (size < 0x10)\n\t\t\treturn 0;\n\t\trsp[0] = sdmmc->rsp[0];\n\t\trsp[1] = sdmmc->rsp[1];\n\t\trsp[2] = sdmmc->rsp[2];\n\t\trsp[3] = sdmmc->rsp[3];\n\t\tbreak;\n\tdefault:\n\t\treturn 0;\n\t\tbreak;\n\t}\n\n\treturn 1;\n}\n\nstatic void _sdmmc_reset(sdmmc_t *sdmmc)\n{\n\tsdmmc->regs->swrst |= \n\t\tTEGRA_MMC_SWRST_SW_RESET_FOR_CMD_LINE | TEGRA_MMC_SWRST_SW_RESET_FOR_DAT_LINE;\n\t_sdmmc_get_clkcon(sdmmc);\n\tu32 timeout = get_tmr_ms() + 2000;\n\twhile (sdmmc->regs->swrst << 29 >> 30 && get_tmr_ms() < timeout)\n\t\t;\n}\n\nstatic int _sdmmc_wait_prnsts_type0(sdmmc_t *sdmmc, u32 wait_dat)\n{\n\t_sdmmc_get_clkcon(sdmmc);\n\n\tu32 timeout = get_tmr_ms() + 2000;\n\twhile(sdmmc->regs->prnsts & 1) // CMD inhibit.\n\t\tif (get_tmr_ms() > timeout)\n\t\t{\n\t\t\t_sdmmc_reset(sdmmc);\n\t\t\treturn 0;\n\t\t}\n\n\tif (wait_dat)\n\t{\n\t\ttimeout = get_tmr_ms() + 2000;\n\t\twhile (sdmmc->regs->prnsts & 2) // DAT inhibit.\n\t\t\tif (get_tmr_ms() > timeout)\n\t\t\t{\n\t\t\t\t_sdmmc_reset(sdmmc);\n\t\t\t\treturn 0;\n\t\t\t}\n\t}\n\n\treturn 1;\n}\n\nstatic int _sdmmc_wait_prnsts_type1(sdmmc_t *sdmmc)\n{\n\t_sdmmc_get_clkcon(sdmmc);\n\n\tu32 timeout = get_tmr_ms() + 2000;\n\twhile (!(sdmmc->regs->prnsts & 0x100000)) // DAT0 line level.\n\t\tif (get_tmr_ms() > timeout)\n\t\t{\n\t\t\t_sdmmc_reset(sdmmc);\n\t\t\treturn 0;\n\t\t}\n\n\treturn 1;\n}\n\nstatic int _sdmmc_setup_read_small_block(sdmmc_t *sdmmc)\n{\n\tswitch (sdmmc_get_bus_width(sdmmc))\n\t{\n\tcase SDMMC_BUS_WIDTH_1:\n\t\treturn 0;\n\t\tbreak;\n\tcase SDMMC_BUS_WIDTH_4:\n\t\tsdmmc->regs->blksize = 0x40;\n\t\tbreak;\n\tcase SDMMC_BUS_WIDTH_8:\n\t\tsdmmc->regs->blksize = 0x80;\n\t\tbreak;\n\t}\n\tsdmmc->regs->blkcnt = 1;\n\tsdmmc->regs->trnmod = TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ;\n\treturn 1;\n}\n\nstatic int _sdmmc_parse_cmdbuf(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, bool is_data_present)\n{\n\tu16 cmdflags = 0;\n\t\n\tswitch (cmd->rsp_type)\n\t{\n\tcase SDMMC_RSP_TYPE_0:\n\t\tbreak;\n\tcase SDMMC_RSP_TYPE_1:\n\tcase SDMMC_RSP_TYPE_4:\n\tcase SDMMC_RSP_TYPE_5:\n\t\tif (cmd->check_busy)\n\t\t\tcmdflags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48_BUSY |\n\t\t\t\tTEGRA_MMC_TRNMOD_CMD_INDEX_CHECK |\n\t\t\t\tTEGRA_MMC_TRNMOD_CMD_CRC_CHECK;\n\t\telse\n\t\t\tcmdflags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48 |\n\t\t\t\tTEGRA_MMC_TRNMOD_CMD_INDEX_CHECK |\n\t\t\t\tTEGRA_MMC_TRNMOD_CMD_CRC_CHECK;\n\t\tbreak;\n\tcase SDMMC_RSP_TYPE_2:\n\t\tcmdflags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_136 |\n\t\t\tTEGRA_MMC_TRNMOD_CMD_CRC_CHECK;\n\t\tbreak;\n\tcase SDMMC_RSP_TYPE_3:\n\t\tcmdflags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48;\n\t\tbreak;\n\tdefault:\n\t\treturn 0;\n\t\tbreak;\n\t}\n\n\tif (is_data_present)\n\t\tcmdflags |= TEGRA_MMC_TRNMOD_DATA_PRESENT_SELECT_DATA_TRANSFER;\n\tsdmmc->regs->argument = cmd->arg;\n\tsdmmc->regs->cmdreg = (cmd->cmd << 8) | cmdflags;\n\n\treturn 1;\n}\n\nstatic void _sdmmc_parse_cmd_48(sdmmc_t *sdmmc, u32 cmd)\n{\n\tsdmmc_cmd_t cmdbuf;\n\tcmdbuf.cmd = cmd;\n\tcmdbuf.arg = 0;\n\tcmdbuf.rsp_type = SDMMC_RSP_TYPE_1;\n\tcmdbuf.check_busy = 0;\n\t_sdmmc_parse_cmdbuf(sdmmc, &cmdbuf, true);\n}\n\nstatic int _sdmmc_config_tuning_once(sdmmc_t *sdmmc, u32 cmd)\n{\n\tif (sdmmc->no_sd)\n\t\treturn 0;\n\tif (!_sdmmc_wait_prnsts_type0(sdmmc, 1))\n\t\treturn 0;\n\n\t_sdmmc_setup_read_small_block(sdmmc);\n\tsdmmc->regs->norintstsen |= TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY;\n\tsdmmc->regs->norintsts = sdmmc->regs->norintsts;\n\tsdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t_sdmmc_parse_cmd_48(sdmmc, cmd);\n\t_sdmmc_get_clkcon(sdmmc);\n\tusleep(1);\n\t_sdmmc_reset(sdmmc);\n\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t_sdmmc_get_clkcon(sdmmc);\n\n\tu32 timeout = get_tmr_us() + 5000;\n\twhile (get_tmr_us() < timeout)\n\t{\n\t\tif (sdmmc->regs->norintsts & 0x20)\n\t\t{\n\t\t\tsdmmc->regs->norintsts = 0x20;\n\t\t\tsdmmc->regs->norintstsen &= 0xFFDF;\n\t\t\t_sdmmc_get_clkcon(sdmmc);\n\t\t\tusleep((1000 * 8 + sdmmc->divisor - 1) / sdmmc->divisor);\n\t\t\treturn 1;\n\t\t}\n\t}\n\t_sdmmc_reset(sdmmc);\n\tsdmmc->regs->norintstsen &= 0xFFDF;\n\t_sdmmc_get_clkcon(sdmmc);\n\tusleep((1000 * 8 + sdmmc->divisor - 1) / sdmmc->divisor);\n\treturn 0;\n}\n\nint sdmmc_config_tuning(sdmmc_t *sdmmc, u32 type, u32 cmd)\n{\n\tu32 max = 0, flag = 0;\n\n\tsdmmc->regs->field_1C4 = 0;\n\tswitch (type)\n\t{\n\tcase 3:\n\tcase 4:\n\tcase 11:\n\t\tmax = 0x80;\n\t\tflag = 0x4000;\n\t\tbreak;\n\tcase 10:\n\tcase 13:\n\tcase 14:\n\t\tmax = 0x100;\n\t\tflag = 0x8000;\n\t\tbreak;\n\tdefault:\n\t\treturn 0;\n\t}\n\n\tsdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | flag;\n\tsdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | 0x40;\n\tsdmmc->regs->ventunctl0 |= 0x20000;\n\tsdmmc->regs->hostctl2  |= SDHCI_CTRL_EXEC_TUNING;\n\n\tfor (u32 i = 0; i < max; i++)\n\t{\n\t\t_sdmmc_config_tuning_once(sdmmc, cmd);\n\t\tif (!(sdmmc->regs->hostctl2 & SDHCI_CTRL_EXEC_TUNING))\n\t\t\tbreak;\n\t}\n\n\tif (sdmmc->regs->hostctl2 & SDHCI_CTRL_TUNED_CLK)\n\t\treturn 1;\n\treturn 0;\n}\n\nstatic int _sdmmc_enable_internal_clock(sdmmc_t *sdmmc)\n{\n\t//Enable internal clock and wait till it is stable.\n\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_INTERNAL_CLOCK_ENABLE;\n\t_sdmmc_get_clkcon(sdmmc);\n\tu32 timeout = get_tmr_ms() + 2000;\n\twhile (!(sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_INTERNAL_CLOCK_STABLE))\n\t{\n\t\tif (get_tmr_ms() > timeout)\n\t\t\treturn 0;\n\t}\n\n\tsdmmc->regs->hostctl2 &= ~SDHCI_CTRL_PRESET_VAL_EN;\n\tsdmmc->regs->clkcon   &= ~TEGRA_MMC_CLKCON_CLKGEN_SELECT;\n\tsdmmc->regs->hostctl2 |= SDHCI_HOST_VERSION_4_EN;\n\n\tif (!(sdmmc->regs->capareg & 0x10000000))\n\t\treturn 0;\n\n\tsdmmc->regs->hostctl2 |= SDHCI_ADDRESSING_64BIT_EN;\n\tsdmmc->regs->hostctl &= 0xE7;\n\tsdmmc->regs->timeoutcon = (sdmmc->regs->timeoutcon & 0xF0) | 0xE;\n\n\treturn 1;\n}\n\nstatic int _sdmmc_autocal_config_offset(sdmmc_t *sdmmc, u32 power)\n{\n\tu32 off_pd = 0;\n\tu32 off_pu = 0;\n\n\tswitch (sdmmc->id)\n\t{\n\tcase SDMMC_2:\n\tcase SDMMC_4:\n\t\tif (power != SDMMC_POWER_1_8)\n\t\t\treturn 0;\n\t\toff_pd = 5;\n\t\toff_pu = 5;\n\t\tbreak;\n\tcase SDMMC_1:\n\tcase SDMMC_3:\n\t\tif (power == SDMMC_POWER_1_8)\n\t\t{\n\t\t\toff_pd = 123;\n\t\t\toff_pu = 123;\n\t\t}\n\t\telse if (power == SDMMC_POWER_3_3)\n\t\t{\n\t\t\toff_pd = 125;\n\t\t\toff_pu = 0;\n\t\t}\n\t\telse\n\t\t\treturn 0;\n\t\tbreak;\n\t}\n\n\tsdmmc->regs->autocalcfg = (((sdmmc->regs->autocalcfg & 0xFFFF80FF) | (off_pd << 8)) >> 7 << 7) | off_pu;\n\treturn 1;\n}\n\nstatic void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)\n{\n\tbool should_enable_sd_clock = false;\n\tif (sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE)\n\t{\n\t\tshould_enable_sd_clock = true;\n\t\tsdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t}\n\n\tif (!(sdmmc->regs->sdmemcmppadctl & 0x80000000))\n\t{\n\t\tsdmmc->regs->sdmemcmppadctl |= 0x80000000;\n\t\t_sdmmc_get_clkcon(sdmmc);\n\t\tusleep(1);\n\t}\n\n\tsdmmc->regs->autocalcfg |= 0xA0000000;\n\t_sdmmc_get_clkcon(sdmmc);\n\tusleep(1);\n\n\tu32 timeout = get_tmr_ms() + 10;\n\twhile (sdmmc->regs->autocalcfg & 0x80000000)\n\t{\n\t\tif (get_tmr_ms() > timeout)\n\t\t{\n\t\t\t// In case autocalibration fails, we load suggested standard values.\n\t\t\t_sdmmc_pad_config_fallback(sdmmc, power);\n\t\t\tsdmmc->regs->autocalcfg &= 0xDFFFFFFF;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tsdmmc->regs->sdmemcmppadctl &= 0x7FFFFFFF;\n\n\tif(should_enable_sd_clock)\n\t\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n}\n\nstatic void _sdmmc_enable_interrupts(sdmmc_t *sdmmc)\n{\n\tsdmmc->regs->norintstsen |= 0xB;\n\tsdmmc->regs->errintstsen |= 0x17F;\n\tsdmmc->regs->norintsts = sdmmc->regs->norintsts;\n\tsdmmc->regs->errintsts = sdmmc->regs->errintsts;\n}\n\nstatic void _sdmmc_mask_interrupts(sdmmc_t *sdmmc)\n{\n\tsdmmc->regs->errintstsen &= 0xFE80;\n\tsdmmc->regs->norintstsen &= 0xFFF4;\n}\n\nstatic int _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)\n{\n\tu16 norintsts = sdmmc->regs->norintsts;\n\tu16 errintsts = sdmmc->regs->errintsts;\n\n\tDPRINTF(\"norintsts %08X; errintsts %08X\\n\", norintsts, errintsts);\n\n\tif (pout)\n\t\t*pout = norintsts;\n\n\t// Check for error interrupt.\n\tif (norintsts & TEGRA_MMC_NORINTSTS_ERR_INTERRUPT)\n\t{\n\t\tsdmmc->regs->errintsts = errintsts;\n\t\treturn SDMMC_MASKINT_ERROR;\n\t}\n\telse if (norintsts & mask)\n\t{\n\t\tsdmmc->regs->norintsts = norintsts & mask;\n\t\treturn SDMMC_MASKINT_MASKED;\n\t}\n\t\n\treturn SDMMC_MASKINT_NOERROR;\n}\n\nstatic int _sdmmc_wait_request(sdmmc_t *sdmmc)\n{\n\t_sdmmc_get_clkcon(sdmmc);\n\n\tu32 timeout = get_tmr_ms() + 2000;\n\twhile (1)\n\t{\n\t\tint res = _sdmmc_check_mask_interrupt(sdmmc, 0, TEGRA_MMC_NORINTSTS_CMD_COMPLETE);\n\t\tif (res == SDMMC_MASKINT_MASKED)\n\t\t\tbreak;\n\t\tif (res != SDMMC_MASKINT_NOERROR || get_tmr_ms() > timeout)\n\t\t{\n\t\t\t_sdmmc_reset(sdmmc);\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\treturn 1;\n}\n\nstatic int _sdmmc_stop_transmission_inner(sdmmc_t *sdmmc, u32 *rsp)\n{\n\tsdmmc_cmd_t cmd;\n\n\tif (!_sdmmc_wait_prnsts_type0(sdmmc, 0))\n\t\treturn 0;\n\n\t_sdmmc_enable_interrupts(sdmmc);\n\tcmd.cmd = MMC_STOP_TRANSMISSION;\n\tcmd.arg = 0;\n\tcmd.rsp_type = SDMMC_RSP_TYPE_1;\n\tcmd.check_busy = 1;\n\t_sdmmc_parse_cmdbuf(sdmmc, &cmd, false);\n\tint res = _sdmmc_wait_request(sdmmc);\n\t_sdmmc_mask_interrupts(sdmmc);\n\n\tif (!res)\n\t\treturn 0;\n\t\n\t_sdmmc_cache_rsp(sdmmc, rsp, 4, SDMMC_RSP_TYPE_1);\n\treturn _sdmmc_wait_prnsts_type1(sdmmc);\n}\n\nint sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp)\n{\n\tif (!sdmmc->sd_clock_enabled)\n\t\treturn 0;\n\n\tbool should_disable_sd_clock = false;\n\tif (!(sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE))\n\t{\n\t\tshould_disable_sd_clock = true;\n\t\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t\t_sdmmc_get_clkcon(sdmmc);\n\t\tusleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor);\n\t}\n\n\tint res = _sdmmc_stop_transmission_inner(sdmmc, rsp);\n\tusleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor);\n\tif (should_disable_sd_clock)\n\t\tsdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\n\treturn res;\n}\n\nstatic int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)\n{\n\tif (!req->blksize || !req->num_sectors)\n\t\treturn 0;\n\n\tu32 blkcnt = req->num_sectors;\n\tif (blkcnt >= 0xFFFF)\n\t\tblkcnt = 0xFFFF;\n\tu32 admaaddr = (u32)req->buf;\n\n\t// Check alignment.\n\tif (admaaddr << 29)\n\t\treturn 0;\n\n\tsdmmc->regs->admaaddr = admaaddr;\n\tsdmmc->regs->admaaddr_hi = 0;\n\n\tsdmmc->dma_addr_next = (admaaddr + 0x80000) & 0xFFF80000;\n\n\tsdmmc->regs->blksize = req->blksize | 0x7000;\n\tsdmmc->regs->blkcnt = blkcnt;\n\n\tif (blkcnt_out)\n\t\t*blkcnt_out = blkcnt;\n\n\tu32 trnmode = TEGRA_MMC_TRNMOD_DMA_ENABLE;\n\tif (req->is_multi_block)\n\t\ttrnmode = TEGRA_MMC_TRNMOD_MULTI_BLOCK_SELECT |\n\t\t\tTEGRA_MMC_TRNMOD_BLOCK_COUNT_ENABLE |\n\t\t\tTEGRA_MMC_TRNMOD_DMA_ENABLE;\n\tif (!req->is_write)\n\t\ttrnmode |= TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ;\n\tif (req->is_auto_cmd12)\n\t\ttrnmode = (trnmode & 0xFFF3) | TEGRA_MMC_TRNMOD_AUTO_CMD12;\n\tbpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY);\n\tsdmmc->regs->trnmod = trnmode;\n\n\treturn 1;\n}\n\nstatic int _sdmmc_update_dma(sdmmc_t *sdmmc)\n{\n\tu16 blkcnt = 0;\n\tdo\n\t{\n\t\tblkcnt = sdmmc->regs->blkcnt;\n\t\tu32 timeout = get_tmr_ms() + 1500;\n\t\tdo\n\t\t{\n\t\t\tint res = 0;\n\t\t\twhile (1)\n\t\t\t{\n\t\t\t\tu16 intr = 0;\n\t\t\t\tres = _sdmmc_check_mask_interrupt(sdmmc, &intr, \n\t\t\t\t\tTEGRA_MMC_NORINTSTS_XFER_COMPLETE | TEGRA_MMC_NORINTSTS_DMA_INTERRUPT);\n\t\t\t\tif (res < 0)\n\t\t\t\t\tbreak;\n\t\t\t\tif (intr & TEGRA_MMC_NORINTSTS_XFER_COMPLETE)\n\t\t\t\t{\n\t\t\t\t\tbpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY);\n\t\t\t\t\treturn 1; // Transfer complete.\n\t\t\t\t}\n\t\t\t\tif (intr & TEGRA_MMC_NORINTSTS_DMA_INTERRUPT)\n\t\t\t\t{\n\t\t\t\t\t// Update DMA.\n\t\t\t\t\tsdmmc->regs->admaaddr = sdmmc->dma_addr_next;\n\t\t\t\t\tsdmmc->regs->admaaddr_hi = 0;\n\t\t\t\t\tsdmmc->dma_addr_next += 0x80000;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (res != SDMMC_MASKINT_NOERROR)\n\t\t\t{\n\t\t\t\t_sdmmc_reset(sdmmc);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t} while (get_tmr_ms() < timeout);\n\t} while (sdmmc->regs->blkcnt != blkcnt);\n\n\t_sdmmc_reset(sdmmc);\n\treturn 0;\n}\n\nstatic int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out)\n{\n\tint has_req_or_check_busy = req || cmd->check_busy;\n\tif (!_sdmmc_wait_prnsts_type0(sdmmc, has_req_or_check_busy))\n\t\treturn 0;\n\n\tu32 blkcnt = 0;\n\tbool is_data_present = false;\n\tif (req)\n\t{\n\t\t_sdmmc_config_dma(sdmmc, &blkcnt, req);\n\t\t_sdmmc_enable_interrupts(sdmmc);\n\t\tis_data_present = true;\n\t}\n\telse\n\t{\n\t\t_sdmmc_enable_interrupts(sdmmc);\n\t\tis_data_present = false;\n\t}\n\n\t_sdmmc_parse_cmdbuf(sdmmc, cmd, is_data_present);\n\n\tint res = _sdmmc_wait_request(sdmmc);\n\tDPRINTF(\"rsp(%d): %08X, %08X, %08X, %08X\\n\", res, \n\t\tsdmmc->regs->rspreg0, sdmmc->regs->rspreg1, sdmmc->regs->rspreg2, sdmmc->regs->rspreg3);\n\tif (res)\n\t{\n\t\tif (cmd->rsp_type)\n\t\t{\n\t\t\tsdmmc->expected_rsp_type = cmd->rsp_type;\n\t\t\t_sdmmc_cache_rsp(sdmmc, sdmmc->rsp, 0x10, cmd->rsp_type);\n\t\t}\n\t\tif (req)\n\t\t\t_sdmmc_update_dma(sdmmc);\n\t}\n\n\t_sdmmc_mask_interrupts(sdmmc);\n\n\tif (res)\n\t{\n\t\tif (req)\n\t\t{\n\t\t\tif (blkcnt_out)\n\t\t\t\t*blkcnt_out = blkcnt;\n\t\t\tif (req->is_auto_cmd12)\n\t\t\t\tsdmmc->rsp3 = sdmmc->regs->rspreg3;\n\t\t}\n\n\t\tif (cmd->check_busy || req)\n\t\t\treturn _sdmmc_wait_prnsts_type1(sdmmc);\n\t}\n\n\treturn res;\n}\n\nstatic int _sdmmc_config_sdmmc1()\n{\n\t// Configure SD card detect.\n\tPINMUX_AUX(PINMUX_AUX_GPIO_PZ1) = PINMUX_INPUT_ENABLE | PINMUX_PULL_UP | 1; //GPIO control, pull up.\n\tAPB_MISC(APB_MISC_GP_VGPIO_GPIO_MUX_SEL) = 0;\n\tgpio_config(GPIO_PORT_Z, GPIO_PIN_1, GPIO_MODE_GPIO);\n\tgpio_output_enable(GPIO_PORT_Z, GPIO_PIN_1, GPIO_OUTPUT_DISABLE);\n\tusleep(100);\n\tif(!!gpio_read(GPIO_PORT_Z, GPIO_PIN_1))\n\t\treturn 0;\n\n\t/*\n\t* Pinmux config:\n\t*  DRV_TYPE = DRIVE_2X\n\t*  E_SCHMT = ENABLE (for 1.8V),  DISABLE (for 3.3V)\n\t*  E_INPUT = ENABLE\n\t*  TRISTATE = PASSTHROUGH\n\t*  APB_MISC_GP_SDMMCx_CLK_LPBK_CONTROL = SDMMCx_CLK_PAD_E_LPBK for CLK\n\t*/\n\n\t// Configure SDMMC1 pinmux.\n\tAPB_MISC(APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL) = 1;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_CLK)  = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_CMD)  = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_DAT3) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_DAT2) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;\n\n\t// Make sure the SDMMC1 controller is powered.\n\tPMC(APBDEV_PMC_NO_IOPOWER) &= ~(1 << 12);\n\t// Assume 3.3V SD card voltage.\n\tPMC(APBDEV_PMC_PWR_DET_VAL) |= (1 << 12);\n\n\t// Set enable SD card power.\n\tPINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN | 1; //GPIO control, pull down.\n\tgpio_config(GPIO_PORT_E, GPIO_PIN_4, GPIO_MODE_GPIO);\n\tgpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_HIGH);\n\tgpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_ENABLE);\n\n\tusleep(1000);\n\n\t// Enable SD card power.\n\tmax77620_regulator_set_voltage(REGULATOR_LDO2, 3300000);\n\tmax77620_regulator_enable(REGULATOR_LDO2, 1);\n\n\tusleep(1000);\n\n\t// For good measure.\n\tAPB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = 0x10000000;\n\n\tusleep(1000);\n\n\treturn 1;\n}\n\nint sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int no_sd)\n{\n\tif (id > SDMMC_4)\n\t\treturn 0;\n\n\tif (id == SDMMC_1)\n\t\tif (!_sdmmc_config_sdmmc1())\n\t\t\treturn 0;\n\n\tmemset(sdmmc, 0, sizeof(sdmmc_t));\n\n\tsdmmc->regs = (t210_sdmmc_t *)_sdmmc_bases[id];\n\tsdmmc->id = id;\n\tsdmmc->clock_stopped = 1;\n\n\tif (clock_sdmmc_is_not_reset_and_enabled(id))\n\t{\n\t\t_sdmmc_sd_clock_disable(sdmmc);\n\t\t_sdmmc_get_clkcon(sdmmc);\n\t}\n\n\tu32 clock;\n\tu16 divisor;\n\tclock_sdmmc_get_params(&clock, &divisor, type);\n\tclock_sdmmc_enable(id, clock);\n\n\tsdmmc->clock_stopped = 0;\n\n\t//TODO: make this skip-able.\n\tsdmmc->regs->iospare |= 0x80000;\n\tsdmmc->regs->veniotrimctl &= 0xFFFFFFFB;\n\tstatic const u32 trim_values[] = { 2, 8, 3, 8 };\n\tsdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xE0FFFFFF) | (trim_values[sdmmc->id] << 24);\n\tsdmmc->regs->sdmemcmppadctl = (sdmmc->regs->sdmemcmppadctl & 0xF) | 7;\n\tif (!_sdmmc_autocal_config_offset(sdmmc, power))\n\t\treturn 0;\n\t_sdmmc_autocal_execute(sdmmc, power);\n\tif (_sdmmc_enable_internal_clock(sdmmc))\n\t{\n\t\tsdmmc_set_bus_width(sdmmc, bus_width);\n\t\t_sdmmc_set_voltage(sdmmc, power);\n\t\tif (sdmmc_setup_clock(sdmmc, type))\n\t\t{\n\t\t\tsdmmc_sd_clock_ctrl(sdmmc, no_sd);\n\t\t\t_sdmmc_sd_clock_enable(sdmmc);\n\t\t\t_sdmmc_get_clkcon(sdmmc);\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t}\n\treturn 0;\n}\n\nvoid sdmmc_end(sdmmc_t *sdmmc)\n{\n\tif (!sdmmc->clock_stopped)\n\t{\n\t\t_sdmmc_sd_clock_disable(sdmmc);\n\t\t// Disable SDMMC power. \n\t\t_sdmmc_set_voltage(sdmmc, SDMMC_POWER_OFF);\n\n\t\t// Disable SD card power.\n\t\tif (sdmmc->id == SDMMC_1)\n\t\t{\n\t\t\tgpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);\n\t\t\tmax77620_regulator_enable(REGULATOR_LDO2, 0);\n\t\t\tmsleep(1); // To power cycle, min 1ms without power is needed.\n\t\t}\n\n\t\t_sdmmc_get_clkcon(sdmmc);\n\t\tclock_sdmmc_disable(sdmmc->id);\n\t\tsdmmc->clock_stopped = 1;\n\t}\n}\n\nvoid sdmmc_init_cmd(sdmmc_cmd_t *cmdbuf, u16 cmd, u32 arg, u32 rsp_type, u32 check_busy)\n{\n\tcmdbuf->cmd = cmd;\n\tcmdbuf->arg = arg;\n\tcmdbuf->rsp_type = rsp_type;\n\tcmdbuf->check_busy = check_busy;\n}\n\nint sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out)\n{\n\tif (!sdmmc->sd_clock_enabled)\n\t\treturn 0;\n\n\t// Recalibrate periodically for SDMMC1.\n\tif (sdmmc->id == SDMMC_1 && sdmmc->no_sd)\n\t\t_sdmmc_autocal_execute(sdmmc, sdmmc_get_voltage(sdmmc));\n\n\tint should_disable_sd_clock = 0;\n\tif (!(sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE))\n\t{\n\t\tshould_disable_sd_clock = 1;\n\t\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t\t_sdmmc_get_clkcon(sdmmc);\n\t\tusleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor);\n\t}\n\n\tint res = _sdmmc_execute_cmd_inner(sdmmc, cmd, req, blkcnt_out);\n\tusleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor);\n\tif (should_disable_sd_clock)\n\t\tsdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\n\treturn res;\n}\n\nint sdmmc_enable_low_voltage(sdmmc_t *sdmmc)\n{\n\tif(sdmmc->id != SDMMC_1)\n\t\treturn 0;\n\n\tif (!sdmmc_setup_clock(sdmmc, 8))\n\t\treturn 0;\n\n\t_sdmmc_get_clkcon(sdmmc);\n\n\t// Enable schmitt trigger for better duty cycle and low jitter clock.\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_CLK)  |= PINMUX_SCHMT;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_CMD)  |= PINMUX_SCHMT;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_DAT3) |= PINMUX_SCHMT;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_DAT2) |= PINMUX_SCHMT;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) |= PINMUX_SCHMT;\n\tPINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) |= PINMUX_SCHMT;\n\n\tmax77620_regulator_set_voltage(REGULATOR_LDO2, 1800000);\n\tPMC(APBDEV_PMC_PWR_DET_VAL) &= ~(1 << 12);\n\n\t_sdmmc_autocal_config_offset(sdmmc, SDMMC_POWER_1_8);\n\t_sdmmc_autocal_execute(sdmmc, SDMMC_POWER_1_8);\n\t_sdmmc_set_voltage(sdmmc, SDMMC_POWER_1_8);\n\t_sdmmc_get_clkcon(sdmmc);\n\tmsleep(5);\n\t\n\tif (sdmmc->regs->hostctl2 & SDHCI_CTRL_VDD_180)\n\t{\n\t\tsdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;\n\t\t_sdmmc_get_clkcon(sdmmc);\n\t\tmsleep(1);\n\t\tif ((sdmmc->regs->prnsts & 0xF00000) == 0xF00000)\n\t\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/utils/btn.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"utils/btn.h\"\n#include \"soc/i2c.h\"\n#include \"soc/gpio.h\"\n#include \"soc/t210.h\"\n#include \"utils/util.h\"\n#include \"power/max77620.h\"\n\nu32 btn_read()\n{\n\tu32 res = 0;\n\tif (!gpio_read(GPIO_PORT_X, GPIO_PIN_7))\n\t\tres |= BTN_VOL_DOWN;\n\tif (!gpio_read(GPIO_PORT_X, GPIO_PIN_6))\n\t\tres |= BTN_VOL_UP;\n\tif (i2c_recv_byte(4, MAX77620_I2C_ADDR, 0x15) & 0x4)\n\t\tres |= BTN_POWER;\n\treturn res;\n}\n\nu32 btn_wait()\n{\n\tu32 res = 0, btn = btn_read();\n\tbool pwr = false;\n\n\t//Power button down, raise a filter.\n\tif (btn & BTN_POWER)\n\t{\n\t\tpwr = true;\n\t\tbtn &= ~BTN_POWER;\n\t}\n\n\tdo\n\t{\n\t\tres = btn_read();\n\t\t//Power button up, remove filter.\n\t\tif (!(res & BTN_POWER) && pwr)\n\t\t\tpwr = false;\n\t\telse if (pwr) //Power button still down.\n\t\t\tres &= ~BTN_POWER;\n\t} while (btn == res);\n\n\treturn res;\n}\n\nu32 btn_wait_timeout(u32 time_ms, u32 mask)\n{\n\tu32 timeout = get_tmr_ms() + time_ms;\n\tu32 res = btn_read() & mask;\n\n\tdo\n\t{\n\t\tif (!(res & mask))\n\t\t\tres = btn_read() & mask;\n\t} while (get_tmr_ms() < timeout);\n\n\treturn res;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/utils/dirlist.c",
    "content": "/*\n * Copyright (c) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"libs/fatfs/ff.h\"\n#include \"mem/heap.h\"\n#include \"utils/types.h\"\n\nchar *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles)\n{\n\tu8 max_entries = 61;\n\n\tint res = 0;\n\tu32 i = 0, j = 0, k = 0;\n\tDIR dir;\n\tstatic FILINFO fno;\n\t\n\tchar *dir_entries = (char *)calloc(max_entries, 256);\n\tchar *copy_entries = (char *)calloc(max_entries, 256);\n\tchar *temp = (char *)calloc(1, 256);\n\n\tif (!pattern && !f_opendir(&dir, directory))\n\t{\n\t\tfor (;;)\n\t\t{\n\t\t\tres = f_readdir(&dir, &fno);\n\t\t\tif (res || !fno.fname[0])\n\t\t\t\tbreak;\n\t\t\tif (!(fno.fattrib & AM_DIR) && (fno.fname[0] != '.') && (includeHiddenFiles || !(fno.fattrib & AM_HID)))\n\t\t\t{\n\t\t\t\tmemcpy(dir_entries + (k * 256), fno.fname, strlen(fno.fname) + 1);\n\t\t\t\tk++;\n\t\t\t\tif (k > (max_entries - 1))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tf_closedir(&dir);\n\t}\n\telse if (pattern && !f_findfirst(&dir, &fno, directory, pattern) && fno.fname[0])\n\t{\n\t\tdo\n\t\t{\n\t\t\tif (!(fno.fattrib & AM_DIR) && (fno.fname[0] != '.') && (includeHiddenFiles || !(fno.fattrib & AM_HID)))\n\t\t\t{\n\t\t\t\tmemcpy(dir_entries + (k * 256), fno.fname, strlen(fno.fname) + 1);\n\t\t\t\tk++;\n\t\t\t\tif (k > (max_entries - 1))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tres = f_findnext(&dir, &fno);\n\t\t} while (fno.fname[0] && !res);\n\t\tf_closedir(&dir);\n\t}\n\n\tif (!k)\n\t{\n\t\tfree(temp);\n\t\tfree(dir_entries);\n\t\tfree(copy_entries);\n\n\t\treturn NULL;\n\t}\n\n\t// make copy_entries lowercase version of dir_entries\n\tfor(i = 0; i < k; i++) \n\t{\n\t\tj = i * 256;\n\t\twhile(dir_entries[j]) \n\t\t{\n\t\t\tcopy_entries[j] = dir_entries[j];\n\n\t\t\tif(dir_entries[j] >= 'A' && dir_entries[j] <= 'Z')\n\t\t\t\tcopy_entries[j] += 32;\n\t\t\t\n\t\t\tj++;\n\t\t}\n\t\t\n\t\tcopy_entries[j] = '\\0';\n\t}\n\n\t// compare copy_entries but sort dir_entries\n\tfor (i = 0; i < k - 1 ; i++)\n\t{\n\t\tfor (j = i + 1; j < k; j++)\n\t\t{\n\t\t\tif (strcmp(&copy_entries[i * 256], &copy_entries[j * 256]) > 0) \n\t\t\t{\n\t\t\t\tmemcpy(temp, &dir_entries[i * 256], strlen(&dir_entries[i * 256]) + 1);\n\t\t\t\tmemcpy(&dir_entries[i * 256], &dir_entries[j * 256], strlen(&dir_entries[j * 256]) + 1);\n\t\t\t\tmemcpy(&dir_entries[j * 256], temp, strlen(temp) + 1);\n\t\t\t}\n\t\t}\n\t}\n\n\tfree(temp);\n\tfree(copy_entries);\n\n\treturn dir_entries;\n}\n"
  },
  {
    "path": "argon-nx-gui/src/utils/fs_utils.c",
    "content": "/*\n * Copyright (c) 2018 naehrwert\n * Copyright (C) 2018 CTCaer\n * Copyright (C) 2018 Guillem96\n * \n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"utils/fs_utils.h\"\n\n#include \"mem/heap.h\"\n#include \"gfx/gfx.h\"\n#include <string.h>\n#include <stdarg.h>\n\nbool sd_mount()\n{\n\tif (g_sd_mounted)\n\t\treturn true;\n\n\tif (!sdmmc_storage_init_sd(&g_sd_storage, &g_sd_sdmmc, SDMMC_1, SDMMC_BUS_WIDTH_4, 11))\n\t{\n\t\tgfx_printf(\"Failed to init SD card.\\nMake sure that it is inserted.\\nOr that SD reader is properly seated!\");\n\t}\n\telse\n\t{\n\t\tint res = 0;\n\t\tres = f_mount(&g_sd_fs, \"\", 1);\n\t\tif (res == FR_OK)\n\t\t{\n\t\t\tg_sd_mounted = 1;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tgfx_printf(\"Failed to mount SD card (FatFS Error %d).\\nMake sure that a FAT partition exists..\", res);\n\t\t}\n\t}\n\n\treturn false;\n}\n\nvoid sd_unmount()\n{\n\tif (g_sd_mounted)\n\t{\n\t\tf_mount(NULL, \"\", 1);\n\t\tsdmmc_storage_end(&g_sd_storage);\n\t\tg_sd_mounted = false;\n\t}\n}\n\nvoid *sd_file_read(char *path)\n{\n\tFIL fp;\n\tif (f_open(&fp, path, FA_READ) != FR_OK)\n\t\treturn NULL;\n\n\tu32 size = f_size(&fp);\n\tvoid *buf = malloc(size);\n\n\tu8 *ptr = buf;\n\twhile (size > 0)\n\t{\n\t\tu32 rsize = MIN(size, 512 * 512);\n\t\tif (f_read(&fp, ptr, rsize, NULL) != FR_OK)\n\t\t{\n\t\t\tfree(buf);\n\t\t\treturn NULL;\n\t\t}\n\n\t\tptr += rsize;\n\t\tsize -= rsize;\n\t}\n\n\tf_close(&fp);\n\n\treturn buf;\n}\n\nint sd_save_to_file(void *buf, u32 size, const char *filename)\n{\n\tFIL fp;\n\tu32 res = 0;\n\tres = f_open(&fp, filename, FA_CREATE_ALWAYS | FA_WRITE);\n\tif (res)\n\t{\n        gfx_printf(\"%kError (%d) creating file\\n%s.\\n%k\\n\", 0xFFFFDD00, res, filename, 0xFFCCCCCC);\n\t\treturn 1;\n\t}\n\n\tf_sync(&fp);\n\tf_write(&fp, buf, size, NULL);\n\tf_close(&fp);\n\n\treturn 0;\n}\n\nbool sd_file_exists(const char* filename)\n{\n    FIL fp;\n\tu32 res = 0;\n\tres = f_open(&fp, filename, FA_READ);\n\tif (res == FR_OK)\n\t{\n        f_close(&fp);\n        return true;\n\t}\n\n    return false;\n}\n\nvoid flipVertically(unsigned char* pixels_buffer, const unsigned int width, const unsigned int height, const int bytes_per_pixel)\n{\n    const unsigned int rows = height / 2; // Iterate only half the buffer to get a full flip\n    const unsigned int row_stride = width * bytes_per_pixel;\n    unsigned char* temp_row = (unsigned char*)malloc(row_stride);\n\n    int source_offset, target_offset;\n\n    for (int rowIndex = 0; rowIndex < rows; rowIndex++)\n    {\n        source_offset = rowIndex * row_stride;\n        target_offset = (height - rowIndex - 1) * row_stride;\n\n        memcpy(temp_row, pixels_buffer + source_offset, row_stride);\n        memcpy(pixels_buffer + source_offset, pixels_buffer + target_offset, row_stride);\n        memcpy(pixels_buffer + target_offset, temp_row, row_stride);\n    }\n\n    free(temp_row);\n    temp_row = NULL;\n}\n\nchar **sout_buf;\n\nstatic void _s_putc(char c)\n{\n\t**sout_buf = c;\n\t*sout_buf += 1;\n}\n\nstatic void _s_puts(const char *s)\n{\n\tfor (; *s; s++)\n\t\t_s_putc(*s);\n}\n\nstatic void _s_putn(u32 v, int base, char fill, int fcnt)\n{\n\tchar buf[65];\n\tstatic const char digits[] = \"0123456789ABCDEFghijklmnopqrstuvwxyz\";\n\tchar *p;\n\tint c = fcnt;\n\n\tif (base > 36)\n\t\treturn;\n\n\tp = buf + 64;\n\t*p = 0;\n\tdo\n\t{\n\t\tc--;\n\t\t*--p = digits[v % base];\n\t\tv /= base;\n\t} while (v);\n\n\tif (fill != 0)\n\t{\n\t\twhile (c > 0)\n\t\t{\n\t\t\t*--p = fill;\n\t\t\tc--;\n\t\t}\n\t}\n\n\t_s_puts(p);\n}\n\nstatic void _s_putp(u32 *v, int base, char fill, int fcnt)\n{\n\t_s_putn(*v, base, fill, fcnt);\n}\n\nvoid s_printf(char *out_buf, const char *fmt, ...)\n{\n\tva_list ap;\n\tint fill, fcnt;\n\n\tsout_buf = &out_buf;\n\n\tva_start(ap, fmt);\n\twhile(*fmt)\n\t{\n\t\tif(*fmt == '%')\n\t\t{\n\t\t\tfmt++;\n\t\t\tfill = 0;\n\t\t\tfcnt = 0;\n\t\t\tif ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ')\n\t\t\t{\n\t\t\t\tfcnt = *fmt;\n\t\t\t\tfmt++;\n\t\t\t\tif (*fmt >= '0' && *fmt <= '9')\n\t\t\t\t{\n\t\t\t\t\tfill = fcnt;\n\t\t\t\t\tfcnt = *fmt - '0';\n\t\t\t\t\tfmt++;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfill = ' ';\n\t\t\t\t\tfcnt -= '0';\n\t\t\t\t}\n\t\t\t}\n\t\t\tswitch(*fmt)\n\t\t\t{\n\t\t\tcase 'c':\n\t\t\t\t_s_putc(va_arg(ap, u32));\n\t\t\t\tbreak;\n\t\t\tcase 's':\n\t\t\t\t_s_puts(va_arg(ap, char *));\n\t\t\t\tbreak;\n\t\t\tcase 'd':\n\t\t\t\t_s_putn(va_arg(ap, u32), 10, fill, fcnt);\n\t\t\t\tbreak;\n\t\t\tcase 'p':\n\t\t\tcase 'P':\n\t\t\t\t_s_putp(va_arg(ap, u32*), 16, fill, fcnt);\n\t\t\t\tbreak;\n\t\t\tcase 'x':\n\t\t\tcase 'X':\n\t\t\t\t_s_putn(va_arg(ap, u32), 16, fill, fcnt);\n\t\t\t\tbreak;\n\t\t\tcase 'k':\n\t\t\t\t//gfx_con.fgcol = va_arg(ap, u32);\n\t\t\t\tbreak;\n\t\t\tcase 'K':\n\t\t\t\t//gfx_con.bgcol = va_arg(ap, u32);\n\t\t\t\t//gfx_con.fillbg = 1;\n\t\t\t\tbreak;\n\t\t\tcase '%':\n\t\t\t\t_s_putc('%');\n\t\t\t\tbreak;\n\t\t\tcase '\\0':\n\t\t\t\tgoto out;\n\t\t\tdefault:\n\t\t\t\t_s_putc('%');\n\t\t\t\t_s_putc(*fmt);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\t_s_putc(*fmt);\n\t\tfmt++;\n\t}\n\nout:\n\t**sout_buf = '\\0';\n\tva_end(ap);\n}"
  },
  {
    "path": "argon-nx-gui/src/utils/touch.c",
    "content": "/*\n * Touch driver for Nintendo Switch's STMicroelectronics FingerTip touch controller\n *\n * Copyright (c) 2018 langerhans\n * Copyright (c) 2018 CTCaer\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n\n#include \"soc/clock.h\"\n#include \"soc/i2c.h\"\n#include \"soc/pinmux.h\"\n#include \"power/max7762x.h\"\n#include \"power/max77620.h\"\n#include \"soc/gpio.h\"\n#include \"soc/t210.h\"\n#include \"utils/util.h\"\n#include \"utils/touch.h\"\n\n\n#include \"gfx/gfx.h\"\nextern gfx_ctxt_t gfx_ctxt;\nextern gfx_con_t gfx_con;\n#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)\n\nstatic int touch_command(u8 cmd)\n{\n\tint err = i2c_send_byte(I2C_3, STMFTS_I2C_ADDR, cmd, 0);\n\tif (!err)\n\t\treturn 1;\n\t\t\n\t// TODO: Check for completion in event loop\n\tmsleep(1);\n\treturn 0;\n}\n\nstatic void _touch_process_contact_event(touch_event_t *event, bool touching)\n{\n\tevent->x = (event->raw[2] << 4) | ((event->raw[4] & STMFTS_MASK_Y_LSB) >> 4);\n\n\t// Normally, GUI elements have bigger horizontal estate.\n\t// Avoid parsing y axis when finger is removed to minimize touch noise.\n\tif (touching)\n\t{\n\t\tevent->y = (event->raw[3] << 4) | (event->raw[4] & STMFTS_MASK_X_MSB);\n\t\tevent->z = event->raw[5];\n\t\tevent->fingers = ((event->raw[1] & STMFTS_MASK_TOUCH_ID) >> 4) + 1;\n\t}\n\telse\n\t\tevent->fingers = 0;\n}\n\nstatic void _touch_parse_event(touch_event_t *event) \n{\n\tevent->type = event->raw[1] & STMFTS_MASK_EVENT_ID;\n\n\tswitch (event->type) \n\t{\n\tcase STMFTS_EV_MULTI_TOUCH_ENTER:\n\tcase STMFTS_EV_MULTI_TOUCH_MOTION:\n\t\t_touch_process_contact_event(event, true);\n\t\tif (event->z > 52) // Discard noisy hover touch.\n\t\t\tevent->touch = true;\n\t\telse\n\t\t{\n\t\t\tevent->touch = false;\n\t\t\tevent->type = STMFTS_EV_MULTI_TOUCH_LEAVE;\n\t\t}\n\t\tbreak;\n\tcase STMFTS_EV_MULTI_TOUCH_LEAVE:\n\t\tevent->touch = false;\n\t\t_touch_process_contact_event(event, false);\n\t\tbreak;\n\tcase STMFTS_EV_NO_EVENT:\n\t\tif (event->touch)\n\t\t\tevent->type = STMFTS_EV_MULTI_TOUCH_MOTION;\n\t\tbreak;\n\tdefault:\n\t\tif (event->touch && event->raw[0] == STMFTS_EV_MULTI_TOUCH_MOTION)\n\t\t\tevent->type = STMFTS_EV_MULTI_TOUCH_MOTION;\n\t\telse\n\t\t\tevent->type = STMFTS_EV_MULTI_TOUCH_LEAVE;\n\t}\n\n\t// gfx_con_setpos(&gfx_con, 0, 300);\n\t// DPRINTF(\"x = %d    \\ny = %d    \\nz: %d  \\n\", event->x, event->y, event->z);\n\t// DPRINTF(\"0 = %02X\\n1 = %02x\\n2 = %02x\\n3 = %02x\\n\", event->raw[0], event->raw[1], event->raw[2], event->raw[3]);\n\t// DPRINTF(\"4 = %02X\\n5 = %02x\\n6 = %02x\\n7 = %02x\\n\", event->raw[4], event->raw[5], event->raw[6], event->raw[7]);\n}\n\nvoid touch_poll(touch_event_t *event)\n{\n\ti2c_recv_buf_small(event->raw, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_LATEST_EVENT);\n\n\t_touch_parse_event(event);\n}\n\ntouch_event_t touch_poll_wait()\n{\n\ttouch_event_t event;\n\tdo \n\t{\n\t\ttouch_poll(&event);\n\t} while (event.type != STMFTS_EV_MULTI_TOUCH_LEAVE);\n\n\treturn event;\n}\n\ntouch_info_t touch_get_info()\n{\n\ttouch_info_t info;\n\tu8 buf[8];\n\tmemset(&buf, 0, 8);\n\ti2c_recv_buf_small(buf, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_INFO);\n\n\tinfo.chip_id = buf[0] << 8 | buf[1];\n\tinfo.fw_ver = buf[2] << 8 | buf[3];\n\tinfo.config_id = buf[4];\n\tinfo.config_ver = buf[5];\n\n\t//DPRINTF(\"ID: %04X, FW Ver: %d.%02d\\nCfg ID: %02x, Cfg Ver: %d\\n\",\n\t//\tinfo.chip_id, info.fw_ver >> 8, info.fw_ver & 0xFF, info.config_id, info.config_ver);\n\n\treturn info;\n}\n\nint touch_power_on()\n{\n\t// Configure touchscreen GPIO.\n\tPINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 3;\n\tgpio_config(GPIO_PORT_J, GPIO_PIN_7, GPIO_MODE_GPIO);\n\tgpio_output_enable(GPIO_PORT_J, GPIO_PIN_7, GPIO_OUTPUT_ENABLE);\n\tgpio_write(GPIO_PORT_J, GPIO_PIN_7, GPIO_HIGH);\n\n\t// IRQ and more.\n\t// PINMUX_AUX(PINMUX_AUX_TOUCH_INT) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 3;\n\t// gpio_config(GPIO_PORT_X, GPIO_PIN_1, GPIO_MODE_GPIO);\n\t// gpio_write(GPIO_PORT_X, GPIO_PIN_1, GPIO_LOW);\n\n\t// Configure Touscreen and GCAsic shared GPIO.\n\tPINMUX_AUX(PINMUX_AUX_CAM_I2C_SDA) = PINMUX_TRISTATE | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP | 3;\n\tPINMUX_AUX(PINMUX_AUX_CAM_I2C_SCL) = PINMUX_INPUT_ENABLE | 1;\n\tgpio_config(GPIO_PORT_S, GPIO_PIN_3, GPIO_MODE_GPIO);\n\n\t// Initialize I2C3.\n\tpinmux_config_i2c(I2C_3);\n\tclock_enable_i2c(I2C_3);\n\ti2c_init(I2C_3);\n\n\t// Enables LDO6 for touchscreen VDD/AVDD supply\n\tmax77620_regulator_set_volt_and_flags(REGULATOR_LDO6, 2900000, MAX77620_POWER_MODE_NORMAL);\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2,\n\t\tMAX77620_LDO_CFG2_ADE_ENABLE | (3 << 3) | (MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT)); \n\n\tmsleep(20);\n\n\t// Initialize touchscreen module.\n\tif (touch_command(STMFTS_SYSTEM_RESET))\n\t\treturn 0;\n\n\tif (touch_command(STMFTS_SLEEP_OUT))\n\t\treturn 0;\n\n\tif (touch_command(STMFTS_MS_CX_TUNING))\n\t\treturn 0;\n\n\tif (touch_command(STMFTS_SS_CX_TUNING))\n\t\treturn 0;\n\n\tif (touch_command(STMFTS_FULL_FORCE_CALIBRATION))\n\t\treturn 0;\n\n\tif (touch_command(STMFTS_MS_MT_SENSE_ON))\n\t\treturn 0;\n\n\tif (touch_command(STMFTS_SS_HOVER_SENSE_OFF))\n\t\treturn 0;\n\n\treturn 1;\n}\n\nvoid touch_power_off() \n{\n\ttouch_command(STMFTS_SLEEP_IN);\n\n\t// Disable touchscreen power.\n\tgpio_write(GPIO_PORT_J, GPIO_PIN_7, GPIO_LOW);\n\n\t// Disables LDO6 for touchscreen VDD, AVDD supply\n\tmax77620_regulator_enable(REGULATOR_LDO6, 0);\n\ti2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2,\n\t\tMAX77620_LDO_CFG2_ADE_ENABLE | (2 << 3) | (MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT));\n\n\tclock_disable_i2c(I2C_3);\n}"
  },
  {
    "path": "argon-nx-gui/src/utils/util.c",
    "content": "/*\n* Copyright (c) 2018 naehrwert\n* Copyright (C) 2018 CTCaer\n* Copyright (C) 2018 Guillem96\n*\n* This program is free software; you can redistribute it and/or modify it\n* under the terms and conditions of the GNU General Public License,\n* version 2, as published by the Free Software Foundation.\n*\n* This program is distributed in the hope it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include \"utils/util.h\"\n#include \"utils/btn.h\"\n#include \"utils/fs_utils.h\"\n\n#include \"soc/t210.h\"\n#include \"soc/bpmp.h\"\n#include \"soc/pmc.h\"\n#include \"soc/i2c.h\"\n\n#include \"power/max77620.h\"\n\n#include \"gfx/di.h\"\n#include \"gfx/gfx.h\"\n\n#include \"mem/heap.h\"\n\n#include <string.h>\n\n#include \"libs/lvgl/lvgl.h\"\n\nu32 get_tmr_s()\n{\n    return RTC(APBDEV_RTC_SECONDS);\n}\n\nu32 get_tmr_ms()\n{\n    // The registers must be read with the following order:\n    // -> RTC_MILLI_SECONDS (0x10) -> RTC_SHADOW_SECONDS (0xC)\n    return (RTC(APBDEV_RTC_MILLI_SECONDS) | (RTC(APBDEV_RTC_SHADOW_SECONDS) << 10));\n}\n\nu32 get_tmr_us()\n{\n    return TMR(TIMERUS_CNTR_1US); //TIMERUS_CNTR_1US\n}\n\nvoid msleep(u32 milliseconds)\n{\n    u32 start = RTC(APBDEV_RTC_MILLI_SECONDS) | (RTC(APBDEV_RTC_SHADOW_SECONDS) << 10);\n    while (((RTC(APBDEV_RTC_MILLI_SECONDS) | (RTC(APBDEV_RTC_SHADOW_SECONDS) << 10)) - start) <= milliseconds)\n        ;\n}\n\nvoid usleep(u32 microseconds)\n{\n    u32 start = TMR(TIMERUS_CNTR_1US);\n    // Casting to u32 is important!\n    while ((u32)(TMR(TIMERUS_CNTR_1US) - start) <= microseconds)\n        ;\n}\n\nvoid exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops)\n{\n    for (u32 i = 0; i < num_ops; i++)\n        base[ops[i].off] = ops[i].val;\n}\n\n#define CRC32C_POLY 0x82F63B78\nu32 crc32c(const void *buf, u32 len)\n{\n    const u8 *cbuf = (const u8 *)buf;\n    u32 crc = 0xFFFFFFFF;\n    while (len--)\n    {\n        crc ^= *cbuf++;\n        for (int i = 0; i < 8; i++)\n            crc = crc & 1 ? (crc >> 1) ^ CRC32C_POLY : crc >> 1;\n    }\n    return ~crc;\n}\n\nu32 memcmp32sparse(const u32 *buf1, const u32 *buf2, u32 len)\n{\n    u32 len32 = len / 4;\n\n    if (!(len32 % 32))\n    {\n        while (len32)\n        {\n            len32 -= 32;\n            if (buf1[len32] != buf2[len32])\n                return 1;\n        }\n    }\n    else\n    {\n        while (len32)\n        {\n            len32 -= 32;\n            if (buf1[len32] != buf2[len32])\n                return 1;\n            if (len32 < 32)\n                return 0;\n        }\n    }\n\n    return 0;\n}\n\n__attribute__((noreturn)) void wait_for_button_and_reboot(void)\n{\n    u32 button;\n    while (true)\n    {\n        button = btn_read();\n        if (button & BTN_POWER)\n        {\n            reboot_rcm();\n        }\n    }\n}\n\nvoid reboot_normal()\n{\n    bpmp_mmu_disable();\n\n    sd_unmount();\n\n    display_end();\n    panic(0x21); // Bypass fuse programming in package1.\n}\n\nvoid reboot_rcm()\n{\n    bpmp_mmu_disable();\n    sd_unmount();\n    display_end();\n\n    PMC(APBDEV_PMC_SCRATCH0) = 2; // Reboot into rcm.\n    PMC(APBDEV_PMC_CNTRL) |= PMC_CNTRL_MAIN_RST;\n    while (true)\n        usleep(1);\n}\n\nvoid power_off()\n{\n    bpmp_mmu_disable();\n    sd_unmount();\n    display_end();\n    //TODO: we should probably make sure all regulators are powered off properly.\n    i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF);\n}\n\nchar *str_replace(char *orig, char *rep, char *with)\n{\n    char *result;  // the return string\n    char *ins;     // the next insert point\n    char *tmp;     // varies\n    int len_rep;   // length of rep (the string to remove)\n    int len_with;  // length of with (the string to replace rep with)\n    int len_front; // distance between rep and end of last rep\n    int count;     // number of replacements\n\n    // sanity checks and initialization\n    if (!orig || !rep)\n        return NULL;\n    len_rep = strlen(rep);\n    if (len_rep == 0)\n        return NULL; // empty rep causes infinite loop during count\n    if (!with)\n        with = \"\";\n    len_with = strlen(with);\n\n    // count the number of replacements needed\n    ins = orig;\n    for (count = 0; (tmp = strstr(ins, rep)); ++count)\n    {\n        ins = tmp + len_rep;\n    }\n\n    tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);\n\n    if (!result)\n        return NULL;\n\n    // first time through the loop, all the variable are set correctly\n    // from here on,\n    //    tmp points to the end of the result string\n    //    ins points to the next occurrence of rep in orig\n    //    orig points to the remainder of orig after \"end of rep\"\n    while (count--)\n    {\n        ins = strstr(orig, rep);\n        len_front = ins - orig;\n        tmp = strncpy(tmp, orig, len_front) + len_front;\n        tmp = strcpy(tmp, with) + len_with;\n        orig += len_front + len_rep; // move to next \"end of rep\"\n    }\n    strcpy(tmp, orig);\n    return result;\n}\n\nvoid panic(u32 val)\n{\n    // Set panic code.\n    PMC(APBDEV_PMC_SCRATCH200) = val;\n    TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN;\n    TMR(TIMER_TMR9_TMR_PTV) = TIMER_EN | TIMER_PER_EN;\n    TMR(TIMER_WDT4_CONFIG) = TIMER_SRC(9) | TIMER_PER(1) | TIMER_PMCRESET_EN;\n    TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT;\n    while (true)\n        ;\n}"
  },
  {
    "path": "docker-compose.yml",
    "content": "version: '3'\nservices:\n  gui:\n    build: argon-nx-gui\n    volumes:\n    - ./output:/output\n  first-stage:\n    build: argon-first-stage\n    volumes:\n    - ./output:/output\n  minerva:\n    build: modules/minerva\n    volumes:\n    - ./output:/output\nvolumes:\n  output: {}"
  },
  {
    "path": "modules/minerva/Dockerfile",
    "content": "FROM devkitpro/devkitarm\nWORKDIR /modules/minerva\nCOPY . .\nENTRYPOINT [\"make\"]"
  },
  {
    "path": "modules/minerva/Makefile",
    "content": "ifeq ($(strip $(DEVKITARM)),)\n$(error \"Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM\")\nendif\n\ninclude $(DEVKITARM)/base_rules\n\nTARGET := libsys_minerva\nBUILD := build/$(TARGET)\nOUTPUT := ../../output\nVPATH = $(dir $(wildcard ./*/)) $(dir $(wildcard ./*/*/))\n\nOBJS = $(addprefix $(BUILD)/,\\\n\tsys_sdrammtc.o \\\n)\n\nARCH := -march=armv4t -mtune=arm7tdmi -mthumb-interwork\nCFLAGS = $(ARCH) -O2 -nostdlib -fpie -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 -Wall $(CUSTOMDEFINES)\nLDFLAGS = $(ARCH) -fpie -pie -nostartfiles -lgcc\n\n.PHONY: clean all\n\nall: $(TARGET).bso\n$(BUILD)/%.o: ./%.c\n\t@mkdir -p \"$(BUILD)\"\n\t$(CC) $(CFLAGS) -c $< -o $@\n\t\n$(TARGET).bso: $(OBJS)\n\t$(CC) $(LDFLAGS) -e _minerva_init $^ -o $(OUTPUT)/$(TARGET).bso\n\t$(STRIP) -g $(OUTPUT)/$(TARGET).bso\n\nclean:\n\t@rm -rf $(OUTPUT)/$(TARGET).bso"
  },
  {
    "path": "modules/minerva/common.h",
    "content": "#ifndef _COMMON_H_\n#define _COMMON_H_\n#include <stddef.h>\n\n#include \"gfx.h\"\n#include \"heap.h\"\n\n// Module Callback\ntypedef void (*cbMainModule_t)(const char *s);\ntypedef void (*memcpy_t)(void *, void *, size_t);\ntypedef void (*memset_t)(void *, int, size_t);\n\ntypedef struct _bdkParams_t\n{\n\tgfx_con_t *gfxCon;\n\tgfx_ctxt_t *gfxCtx;\n\theap_t *sharedHeap;\n\tmemcpy_t memcpy;\n\tmemset_t memset;\n} *bdkParams_t;\n\n// Module Entrypoint\ntypedef void (*moduleEntrypoint_t)(void *, bdkParams_t);\n\n#endif"
  },
  {
    "path": "modules/minerva/gfx.h",
    "content": "#ifndef _GFX_H_\n#define _GFX_H_\n\n#include \"types.h\"\n\ntypedef struct _gfx_ctxt_t\n{\n\tu32 *fb;\n\tu32 width;\n\tu32 height;\n\tu32 stride;\n} gfx_ctxt_t;\n\ntypedef struct _gfx_con_t\n{\n\tgfx_ctxt_t *gfx_ctxt;\n\tu32 fntsz;\n\tu32 x;\n\tu32 y;\n\tu32 savedx;\n\tu32 savedy;\n\tu32 fgcol;\n\tint fillbg;\n\tu32 bgcol;\n\tbool mute;\n} gfx_con_t;\n\n#endif"
  },
  {
    "path": "modules/minerva/heap.h",
    "content": "#ifndef _HEAP_H_\n#define _HEAP_H_\n#include \"types.h\"\ntypedef struct _hnode\n{\n\tint used;\n\tu32 size;\n\tstruct _hnode *prev;\n\tstruct _hnode *next;\n} hnode_t;\n\ntypedef struct _heap\n{\n\tu32 start;\n\thnode_t *first;\n} heap_t;\n\n#endif"
  },
  {
    "path": "modules/minerva/mtc.h",
    "content": "/*\n * Minerva Training Cell\n * DRAM Training for Tegra X1 SoC. Supports DDR2/3 and LPDDR3/4.\n *\n * Copyright (c) 2018 CTCaer  <ctcaer@gmail.com>\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _MTC_H_\n#define _MTC_H_\n\n#include \"mtc_table.h\"\n#include \"types.h\"\n\n/* Address bases and access macros - Change these for mapped access */\n#define TMR_BASE   0x60005000\n#define CLOCK_BASE 0x60006000\n#define MC_BASE    0x70019000\n#define EMC_BASE   0x7001B000\n#define EMC0_BASE  0x7001E000\n#define EMC1_BASE  0x7001F000\n#define MTC_TABLE  0x8F000000\n\n#define _REG(base, off) *(vu32 *)((base) + (off))\n\n#define TMR(off) _REG(TMR_BASE, off)\n#define CLOCK(off) _REG(CLOCK_BASE, off)\n#define MC(off) _REG(MC_BASE, off)\n#define EMC(off) _REG(EMC_BASE, off)\n#define EMC_CH0(off) _REG(EMC0_BASE, off)\n#define EMC_CH1(off) _REG(EMC1_BASE, off)\n/* End of addresses and access macros */\n\n#define EMC_TABLE_SIZE_R7         49280\n#define EMC_TABLE_ENTRY_SIZE_R7   4928\n#define EMC_STATUS_UPDATE_TIMEOUT 1000\n#define EMC_PERIODIC_TRAIN_MS     100\n#define EMC_TEMP_COMP_MS          1000\n\ntypedef struct\n{\n\ts32 rate_to;\n\ts32 rate_from;\n\temc_table_t *mtc_table;\n\tu32 table_entries;\n\temc_table_t *current_emc_table;\n\tu32 train_mode;\n\tu32 sdram_id;\n\tu32 prev_temp;\n\tbool emc_2X_clk_src_is_pllmb;\n\tbool fsp_for_src_freq;\n\tbool train_ram_patterns;\n} mtc_config_t;\n\nenum train_mode_t\n{\n\tOP_SWITCH         = 0,\n\tOP_TRAIN          = 1,\n\tOP_TRAIN_SWITCH   = 2,\n\tOP_PERIODIC_TRAIN = 3,\n\tOP_TEMP_COMP      = 4\n};\n\nenum comp_seq_t\n{\n\tDVFS_SEQUENCE              = 1,\n\tWRITE_TRAINING_SEQUENCE    = 2,\n\tPERIODIC_TRAINING_SEQUENCE = 3\n};\n\nenum tree_update_mode_t\n{\n\tDVFS_PT1                 = 10,\n\tDVFS_UPDATE              = 11,\n\tTRAINING_PT1             = 12,\n\tTRAINING_UPDATE          = 13,\n\tPERIODIC_TRAINING_UPDATE = 14\n};\n\nenum emc_channels\n{\n\tEMC_CH0 = 0,\n\tEMC_CH1 = 1\n};\n\nenum EMC_2X_CLK_SRC\n{\n\tPLLM_OUT0  = 0x0,\n\tPLLC_OUT0  = 0x1,\n\tPLLP_OUT0  = 0x2,\n\tCLK_M      = 0x3,\n\tPLLM_UD    = 0x4,\n\tPLLMB_UD   = 0x5,\n\tPLLMB_OUT0 = 0x6,\n\tPLLP_UD    = 0x7\n};\n\nenum DRAM_TYPE\n{\n\tDRAM_TYPE_DDR3   = 0,\n\tDRAM_TYPE_LPDDR4 = 1,\n\tDRAM_TYPE_LPDDR2 = 2,\n\tDRAM_TYPE_DDR2   = 3\n};\n\nenum DRAM_DEV_NO\n{\n\tONE_RANK = 1,\n\tTWO_RANK = 2\n};\n\nenum DRAM_OVER_TEMP_REF\n{\n\tREFRESH_X2 = 1,\n\tREFRESH_X4 = 2\n};\n\n/* Timers for the below two compensation functions should be paused when changing timings. */\n\n/* Change refresh rate based on dram temps. Run every 1000ms. */\n/* Timer should be run only when another component reports over temperature. */\nvoid _minerva_do_over_temp_compensation(mtc_config_t *mtc_cfg);\n\n/* Periodic compensation only for tight timings that need it. Run every 100ms. */\n/* Over temp and periodic compensation, should not access EMC_MRR at the same time. */\nu32  _minerva_do_periodic_compensation(emc_table_t *mtc_table_entry);\n\n/* Main function used to access all Minerva functions. */\nvoid _minerva_init(mtc_config_t *mtc_cfg, void* bp);\n\n#endif\n"
  },
  {
    "path": "modules/minerva/mtc_mc_emc_regs.h",
    "content": "/*\n * Minerva Training Cell\n * DRAM Training for Tegra X1 SoC. Supports DDR2/3 and LPDDR3/4.\n *\n * Copyright (c) 2018 CTCaer  <ctcaer@gmail.com>\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _MTC_MC_EMC_REGS_H_\n#define _MTC_MC_EMC_REGS_H_\n\n/* Clock controller registers */\n#define CLK_RST_CONTROLLER_PLLM_BASE           0x90\n#define CLK_RST_CONTROLLER_PLLM_MISC2          0x9C\n#define  PLLM_ENABLE (1 << 30)\n#define  PLLM_LOCK   (1 << 27)\n\n#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC      0x19C\n#define  EMC_2X_CLK_SRC_SHIFT 29\n\n#define CLK_RST_CONTROLLER_CLK_OUT_ENB_X       0x280\n#define CLK_RST_CONTROLLER_CLK_ENB_X_SET       0x284\n#define CLK_RST_CONTROLLER_CLK_ENB_X_CLR       0x288\n#define CLK_RST_CONTROLLER_PLLMB_BASE          0x5E8\n#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL  0x664\n#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_SAFE 0x724\n\n/* Memory controller registers */\n#define MC_EMEM_ADR_CFG               0x54\n#define MC_EMEM_ARB_CFG               0x90\n#define MC_EMEM_ARB_OUTSTANDING_REQ   0x94\n#define MC_EMEM_ARB_TIMING_RCD        0x98\n#define MC_EMEM_ARB_TIMING_RP         0x9C\n#define MC_EMEM_ARB_TIMING_RC         0xA0\n#define MC_EMEM_ARB_TIMING_RAS        0xA4\n#define MC_EMEM_ARB_TIMING_FAW        0xA8\n#define MC_EMEM_ARB_TIMING_RRD        0xAC\n#define MC_EMEM_ARB_TIMING_RAP2PRE    0xB0\n#define MC_EMEM_ARB_TIMING_WAP2PRE    0xB4\n#define MC_EMEM_ARB_TIMING_R2R        0xB8\n#define MC_EMEM_ARB_TIMING_W2W        0xBC\n#define MC_EMEM_ARB_TIMING_R2W        0xC0\n#define MC_EMEM_ARB_TIMING_W2R        0xC4\n#define MC_EMEM_ARB_MISC2             0xC8\n#define MC_EMEM_ARB_DA_TURNS          0xD0\n#define MC_EMEM_ARB_DA_COVERS         0xD4\n#define MC_EMEM_ARB_MISC0             0xD8\n#define MC_EMEM_ARB_MISC1             0xDC\n#define MC_EMEM_ARB_RING1_THROTTLE    0xE0\n\n#define MC_LATENCY_ALLOWANCE_AVPC_0    0x2E4\n#define MC_LATENCY_ALLOWANCE_HC_0      0x310\n#define MC_LATENCY_ALLOWANCE_HC_1      0x314\n#define MC_LATENCY_ALLOWANCE_MPCORE_0  0x320\n#define MC_LATENCY_ALLOWANCE_NVENC_0   0x328\n#define MC_LATENCY_ALLOWANCE_PPCS_0    0x344\n#define MC_LATENCY_ALLOWANCE_PPCS_1    0x348\n#define MC_LATENCY_ALLOWANCE_ISP2_0    0x370\n#define MC_LATENCY_ALLOWANCE_ISP2_1    0x374\n#define MC_LATENCY_ALLOWANCE_XUSB_0    0x37C\n#define MC_LATENCY_ALLOWANCE_XUSB_1    0x380\n#define MC_LATENCY_ALLOWANCE_TSEC_0    0x390\n#define MC_LATENCY_ALLOWANCE_VIC_0     0x394\n#define MC_LATENCY_ALLOWANCE_VI2_0     0x398\n#define MC_LATENCY_ALLOWANCE_GPU_0     0x3AC\n#define MC_LATENCY_ALLOWANCE_SDMMCA_0  0x3B8\n#define MC_LATENCY_ALLOWANCE_SDMMCAA_0 0x3BC\n#define MC_LATENCY_ALLOWANCE_SDMMC_0   0x3C0\n#define MC_LATENCY_ALLOWANCE_SDMMCAB_0 0x3C4\n#define MC_LATENCY_ALLOWANCE_NVDEC_0   0x3D8\n#define MC_LATENCY_ALLOWANCE_GPU2_0    0x3E8\n\n#define MC_MLL_MPCORER_PTSA_RATE  0x44C\n#define MC_FTOP_PTSA_RATE         0x50C\n\n#define MC_EMEM_ARB_TIMING_RFCPB      0x6C0\n#define MC_EMEM_ARB_TIMING_CCDMW      0x6C4\n#define MC_EMEM_ARB_REFPB_HP_CTRL     0x6F0\n#define MC_EMEM_ARB_REFPB_BANK_CTRL   0x6F4\n\n#define MC_PTSA_GRANT_DECREMENT       0x960\n\n#define MC_EMEM_ARB_DHYST_CTRL           0xBCC\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0 0xBD0\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1 0xBD4\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2 0xBD8\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3 0xBDC\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4 0xBE0\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5 0xBE4\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6 0xBE8\n#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7 0xBEC\n\n/* External Memory controller registers */\n#define EMC_INTSTATUS                 0x0\n#define  CLKCHANGE_COMPLETE_INT (1 << 4)\n\n#define EMC_DBG                       0x8\n#define EMC_CFG                       0xC\n#define EMC_PIN                       0x24\n#define EMC_TIMING_CONTROL            0x28\n#define EMC_RC                        0x2C\n#define EMC_RFC                       0x30\n#define EMC_RAS                       0x34\n#define EMC_RP                        0x38\n#define EMC_R2W                       0x3C\n#define EMC_W2R                       0x40\n#define EMC_R2P                       0x44\n#define EMC_W2P                       0x48\n#define EMC_RD_RCD                    0x4C\n#define EMC_WR_RCD                    0x50\n#define EMC_RRD                       0x54\n#define EMC_REXT                      0x58\n#define EMC_WDV                       0x5C\n#define EMC_QUSE                      0x60\n#define EMC_QRST                      0x64\n#define EMC_QSAFE                     0x68\n#define EMC_RDV                       0x6C\n#define EMC_REFRESH                   0x70\n#define EMC_BURST_REFRESH_NUM         0x74\n#define EMC_PDEX2WR                   0x78\n#define EMC_PDEX2RD                   0x7C\n#define EMC_PCHG2PDEN                 0x80\n#define EMC_ACT2PDEN                  0x84\n#define EMC_AR2PDEN                   0x88\n#define EMC_RW2PDEN                   0x8C\n#define EMC_TXSR                      0x90\n#define EMC_TCKE                      0x94\n#define EMC_TFAW                      0x98\n#define EMC_TRPAB                     0x9C\n#define EMC_TCLKSTABLE                0xA0\n#define EMC_TCLKSTOP                  0xA4\n#define EMC_TREFBW                    0xA8\n#define EMC_TPPD                      0xAC\n#define EMC_ODT_WRITE                 0xB0\n#define EMC_PDEX2MRR                  0xB4\n#define EMC_WEXT                      0xB8\n#define EMC_RFC_SLR                   0xC0\n#define EMC_MRS_WAIT_CNT2             0xC4\n#define EMC_MRS_WAIT_CNT              0xC8\n#define EMC_MRS                       0xCC\n#define EMC_EMRS                      0xD0\n#define EMC_REF                       0xD4\n#define EMC_MRW                       0xE8\n#define EMC_SELF_REF                  0xE0\n#define EMC_MRR                       0xEC\n#define EMC_FBIO_SPARE                0x100\n#define EMC_FBIO_CFG5                 0x104\n#define EMC_PDEX2CKE                  0x118\n#define EMC_CKE2PDEN                  0x11C\n#define EMC_MPC                       0x128\n#define EMC_EMRS2                     0x12C\n#define EMC_MRW2                      0x134\n#define EMC_MRW3                      0x138\n#define EMC_MRW4                      0x13C\n#define EMC_R2R                       0x144\n#define EMC_EINPUT                    0x14C\n#define EMC_EINPUT_DURATION           0x150\n#define EMC_PUTERM_EXTRA              0x154\n#define EMC_TCKESR                    0x158\n#define EMC_TPD                       0x15C\n#define EMC_AUTO_CAL_CONFIG           0x2A4\n\n#define EMC_EMC_STATUS                0x2B4\n#define  TIMING_UPDATE_STALLED  (1 << 23)\n#define  MRR_DIVLD              (1 << 20)\n#define  IN_SELF_REFRESH_MASK   (3 << 8)\n#define  IN_POWERDOWN_MASK      (3 << 4)\n#define  REQ_FIFO_EMPTY         (1 << 0)\n\n#define EMC_CFG_2                     0x2B8\n#define EMC_CFG_DIG_DLL               0x2BC\n#define EMC_CFG_DIG_DLL_PERIOD        0x2C0\n#define EMC_DIG_DLL_STATUS            0x2C4\n#define EMC_RDV_MASK                  0x2CC\n#define EMC_WDV_MASK                  0x2D0\n#define EMC_RDV_EARLY_MASK            0x2D4\n#define EMC_RDV_EARLY                 0x2D8\n#define EMC_AUTO_CAL_CONFIG8          0x2DC\n#define EMC_ZCAL_INTERVAL             0x2E0\n#define EMC_ZCAL_WAIT_CNT             0x2E4\n#define EMC_ZQ_CAL                    0x2EC\n#define EMC_FDPD_CTRL_DQ              0x310\n#define EMC_FDPD_CTRL_CMD             0x314\n#define EMC_PMACRO_CMD_BRICK_CTRL_FDPD     0x318\n#define EMC_PMACRO_DATA_BRICK_CTRL_FDPD    0x31C\n#define EMC_SCRATCH0                  0x324\n#define EMC_PMACRO_BRICK_CTRL_RFU1    0x330\n#define EMC_PMACRO_BRICK_CTRL_RFU2    0x334\n#define EMC_TR_TIMING_0               0x3B4\n#define EMC_TR_CTRL_0                 0x3B8\n#define EMC_TR_CTRL_1                 0x3BC\n#define EMC_SWITCH_BACK_CTRL          0x3C0\n#define EMC_TR_RDV                    0x3C4\n#define EMC_STALL_THEN_EXE_AFTER_CLKCHANGE 0x3CC\n#define EMC_SEL_DPD_CTRL              0x3D8\n#define EMC_PRE_REFRESH_REQ_CNT       0x3DC\n#define EMC_DYN_SELF_REF_CONTROL      0x3E0\n#define EMC_TXSRDLL                   0x3E4\n#define EMC_CCFIFO_ADDR               0x3E8\n#define EMC_CCFIFO_DATA               0x3EC\n#define EMC_CCFIFO_STATUS             0x3F0\n#define EMC_TR_QPOP                   0x3F4\n#define EMC_TR_RDV_MASK               0x3F8\n#define EMC_TR_QSAFE                  0x3FC\n#define EMC_TR_QRST                   0x400\n#define EMC_AUTO_CAL_CONFIG2          0x458\n#define EMC_AUTO_CAL_CONFIG3          0x45C\n#define EMC_TR_DVFS                   0x460\n#define EMC_AUTO_CAL_CHANNEL          0x464\n#define EMC_IBDLY                     0x468\n#define EMC_OBDLY                     0x46c\n#define EMC_TXDSRVTTGEN               0x480\n#define EMC_WE_DURATION               0x48C\n#define EMC_WS_DURATION               0x490\n#define EMC_WEV                       0x494\n#define EMC_WSV                       0x498\n#define EMC_CFG_3                     0x49C\n#define EMC_MRW6                      0x4A4\n#define EMC_MRW7                      0x4A8\n#define EMC_MRW8                      0x4AC\n#define EMC_MRW14                     0x4C4\n#define EMC_MRW15                     0x4D0\n#define EMC_CFG_SYNC                  0x4D4\n#define EMC_FDPD_CTRL_CMD_NO_RAMP     0x4D8\n#define EMC_WDV_CHK                   0x4E0\n#define EMC_CFG_PIPE_2                0x554\n#define EMC_CFG_PIPE_CLK              0x558\n#define EMC_CFG_PIPE_1                0x55C\n#define EMC_CFG_PIPE                  0x560\n#define EMC_QPOP                      0x564\n#define EMC_QUSE_WIDTH                0x568\n#define EMC_PUTERM_WIDTH              0x56C\n#define EMC_AUTO_CAL_CONFIG7          0x574\n#define EMC_REFCTRL2                  0x580\n#define EMC_FBIO_CFG7                 0x584\n\n#define EMC_DATA_BRLSHFT_0            0x588\n#define  EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_SHIFT 0\n#define  EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_SHIFT 3\n#define  EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_SHIFT 6\n#define  EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_SHIFT 9\n#define  EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_SHIFT 12\n#define  EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_SHIFT 15\n#define  EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_SHIFT 18\n#define  EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_SHIFT 21\n\n#define EMC_DATA_BRLSHFT_1            0x58C\n#define  EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_SHIFT 0\n#define  EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_SHIFT 3\n#define  EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_SHIFT 6\n#define  EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_SHIFT 9\n#define  EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_SHIFT 12\n#define  EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_SHIFT 15\n#define  EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_SHIFT 18\n#define  EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_SHIFT 21\n\n#define EMC_RFCPB                     0x590\n#define EMC_DQS_BRLSHFT_0             0x594\n#define EMC_DQS_BRLSHFT_1             0x598\n#define EMC_CMD_BRLSHFT_0             0x59C\n#define EMC_CMD_BRLSHFT_1             0x5A0\n#define EMC_CMD_BRLSHFT_2             0x5A4\n#define EMC_CMD_BRLSHFT_3             0x5A8\n#define EMC_QUSE_BRLSHFT_0            0x5AC\n#define EMC_AUTO_CAL_CONFIG4          0x5B0\n#define EMC_AUTO_CAL_CONFIG5          0x5B4\n#define EMC_QUSE_BRLSHFT_1            0x5B8\n#define EMC_QUSE_BRLSHFT_2            0x5BC\n#define EMC_CCDMW                     0x5C0\n#define EMC_QUSE_BRLSHFT_3            0x5C4\n#define EMC_AUTO_CAL_CONFIG6          0x5CC\n#define EMC_DLL_CFG_0                 0x5E4\n#define EMC_DLL_CFG_1                 0x5E8\n#define EMC_CONFIG_SAMPLE_DELAY       0x5F0\n#define EMC_CFG_UPDATE                0x5F4\n\n#define EMC_PMACRO_QUSE_DDLL_RANK0_0 0x600\n#define EMC_PMACRO_QUSE_DDLL_RANK0_1 0x604\n#define EMC_PMACRO_QUSE_DDLL_RANK0_2 0x608\n#define EMC_PMACRO_QUSE_DDLL_RANK0_3 0x60C\n#define EMC_PMACRO_QUSE_DDLL_RANK0_4 0x610\n#define EMC_PMACRO_QUSE_DDLL_RANK0_5 0x614\n#define EMC_PMACRO_QUSE_DDLL_RANK1_4 0x630\n#define EMC_PMACRO_QUSE_DDLL_RANK1_5 0x634\n#define EMC_PMACRO_QUSE_DDLL_RANK1_0 0x620\n#define EMC_PMACRO_QUSE_DDLL_RANK1_1 0x624\n#define EMC_PMACRO_QUSE_DDLL_RANK1_2 0x628\n#define EMC_PMACRO_QUSE_DDLL_RANK1_3 0x62C\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0 0x640\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1 0x644\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2 0x648\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3 0x64C\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4 0x650\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5 0x654\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0 0x660\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1 0x664\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2 0x668\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3 0x66C\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4 0x670\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5 0x674\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0 0x680\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1 0x684\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2 0x688\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3 0x68C\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4 0x690\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5 0x694\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0 0x6A0\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1 0x6A4\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2 0x6A8\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3 0x6AC\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4 0x6B0\n#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5 0x6B4\n\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0 0x6C0\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1 0x6C4\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2 0x6C8\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3 0x6CC\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0 0x6E0\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1 0x6E4\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2 0x6E8\n#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3 0x6EC\n\n#define EMC_PMACRO_TX_PWRD_0 0x720\n#define EMC_PMACRO_TX_PWRD_1 0x724\n#define EMC_PMACRO_TX_PWRD_2 0x728\n#define EMC_PMACRO_TX_PWRD_3 0x72C\n#define EMC_PMACRO_TX_PWRD_4 0x730\n#define EMC_PMACRO_TX_PWRD_5 0x734\n\n#define EMC_PMACRO_TX_SEL_CLK_SRC_0 0x740\n#define EMC_PMACRO_TX_SEL_CLK_SRC_1 0x744\n#define EMC_PMACRO_TX_SEL_CLK_SRC_3 0x74C\n#define EMC_PMACRO_TX_SEL_CLK_SRC_2 0x748\n#define EMC_PMACRO_TX_SEL_CLK_SRC_4 0x750\n#define EMC_PMACRO_TX_SEL_CLK_SRC_5 0x754\n\n#define EMC_PMACRO_DDLL_BYPASS 0x760\n#define EMC_PMACRO_DDLL_PWRD_0 0x770\n#define EMC_PMACRO_DDLL_PWRD_1 0x774\n#define EMC_PMACRO_DDLL_PWRD_2 0x778\n\n#define EMC_PMACRO_CMD_CTRL_0 0x780\n#define EMC_PMACRO_CMD_CTRL_1 0x784\n#define EMC_PMACRO_CMD_CTRL_2 0x788\n\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_0 0x800\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_1 0x804\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_2 0x808\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_3 0x80C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_0 0x810\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_1 0x814\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_2 0x818\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_3 0x81C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_0 0x820\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_1 0x824\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_2 0x828\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_3 0x82C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_0 0x830\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_1 0x834\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_2 0x838\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_3 0x83C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_0 0x840\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_1 0x844\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_2 0x848\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_3 0x84C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_0 0x850\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_1 0x854\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_2 0x858\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_3 0x85C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_0 0x860\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_1 0x864\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_2 0x868\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_3 0x86C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_0 0x870\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_1 0x874\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_2 0x878\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_3 0x87C\n\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_0 0x880\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_1 0x884\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_2 0x888\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_3 0x88C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_0 0x890\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_1 0x894\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_2 0x898\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_3 0x89C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_0 0x8A0\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_1 0x8A4\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_2 0x8A8\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_3 0x8AC\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_0 0x8B0\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_1 0x8B4\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_2 0x8B8\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_3 0x8BC\n\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_0 0x900\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_1 0x904\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_2 0x908\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_3 0x90C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_0 0x910\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_1 0x914\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_2 0x918\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_3 0x91C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_0 0x920\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_1 0x924\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_2 0x928\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_3 0x92C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_0 0x930\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_1 0x934\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_2 0x938\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_3 0x93C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_0 0x940\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_1 0x944\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_2 0x948\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_3 0x94C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_0 0x950\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_1 0x954\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_2 0x958\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_3 0x95C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_0 0x960\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_1 0x964\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_2 0x968\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_3 0x96C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_0 0x970\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_1 0x974\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_2 0x978\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_3 0x97C\n\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_0 0x980\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_1 0x984\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_2 0x988\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_3 0x98C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_0 0x990\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_1 0x994\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_2 0x998\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_3 0x99C\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_0 0x9A0\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_1 0x9A4\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_2 0x9A8\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_3 0x9AC\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_0 0x9B0\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_1 0x9B4\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_2 0x9B8\n#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_3 0x9BC\n\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_0 0xA00\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_1 0xA04\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_2 0xA08\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_0 0xA10\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_1 0xA14\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_2 0xA18\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_0 0xA20\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_1 0xA24\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_2 0xA28\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_0 0xA30\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_1 0xA34\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_2 0xA38\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_0 0xA40\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_1 0xA44\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_2 0xA48\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_0 0xA50\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_1 0xA54\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_2 0xA58\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_0 0xA60\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_1 0xA64\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_2 0xA68\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_0 0xA70\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_1 0xA74\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_2 0xA78\n\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_0 0xB00\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_1 0xB04\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_2 0xB08\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_0 0xB10\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_1 0xB14\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_2 0xB18\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_0 0xB20\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_1 0xB24\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_2 0xB28\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_0 0xB30\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_1 0xB34\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_2 0xB38\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_0 0xB40\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_1 0xB44\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_2 0xB48\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_0 0xB50\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_1 0xB54\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_2 0xB58\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_0 0xB60\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_1 0xB64\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_2 0xB68\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_0 0xB70\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_1 0xB74\n#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_2 0xB78\n\n#define EMC_PMACRO_IB_VREF_DQ_0  0xBE0\n#define EMC_PMACRO_IB_VREF_DQ_1  0xBE4\n#define EMC_PMACRO_IB_VREF_DQS_0 0xBF0\n#define EMC_PMACRO_IB_VREF_DQS_1 0xBF4\n\n#define EMC_PMACRO_DDLL_LONG_CMD_0 0xC00\n#define EMC_PMACRO_DDLL_LONG_CMD_1 0xC04\n#define EMC_PMACRO_DDLL_LONG_CMD_2 0xC08\n#define EMC_PMACRO_DDLL_LONG_CMD_3 0xC0C\n#define EMC_PMACRO_DDLL_LONG_CMD_4 0xC10\n\n#define EMC_PMACRO_DDLL_SHORT_CMD_0 0xC20\n#define EMC_PMACRO_DDLL_SHORT_CMD_1 0xC24\n#define EMC_PMACRO_DDLL_SHORT_CMD_2 0xC28\n\n#define EMC_PMACRO_CFG_PM_GLOBAL_0    0xC30\n#define EMC_PMACRO_VTTGEN_CTRL_0      0xC34\n#define EMC_PMACRO_VTTGEN_CTRL_1      0xC38\n#define EMC_PMACRO_BG_BIAS_CTRL_0     0xC3C\n#define EMC_PMACRO_PAD_CFG_CTRL       0xC40\n#define EMC_PMACRO_ZCTRL              0xC44\n#define EMC_PMACRO_CMD_PAD_RX_CTRL    0xC50\n#define EMC_PMACRO_DATA_PAD_RX_CTRL   0xC54\n#define EMC_PMACRO_CMD_RX_TERM_MODE   0xC58\n#define EMC_PMACRO_DATA_RX_TERM_MODE  0xC5C\n#define EMC_PMACRO_CMD_PAD_TX_CTRL    0xC60\n#define EMC_PMACRO_DATA_PAD_TX_CTRL   0xC64\n#define EMC_PMACRO_COMMON_PAD_TX_CTRL 0xC68\n#define EMC_PMACRO_AUTOCAL_CFG_COMMON 0xC78\n#define EMC_PMACRO_VTTGEN_CTRL_2      0xCF0\n#define EMC_PMACRO_IB_RXRT            0xCF4\n#define EMC_PMACRO_TRAINING_CTRL_0    0xCF8\n#define  CH0_TRAINING_E_WRPTR (1 << 3)\n#define EMC_PMACRO_TRAINING_CTRL_1    0xCFC\n\n#define EMC_TRAINING_CMD              0xE00\n#define EMC_TRAINING_CTRL             0xE04\n#define EMC_TRAINING_STATUS           0xE08\n#define EMC_TRAINING_QUSE_CORS_CTRL   0xE0C\n#define EMC_TRAINING_QUSE_FINE_CTRL   0xE10\n#define EMC_TRAINING_QUSE_CTRL_MISC   0xE14\n#define EMC_TRAINING_WRITE_FINE_CTRL  0xE18\n#define EMC_TRAINING_WRITE_CTRL_MISC  0xE1C\n#define EMC_TRAINING_WRITE_VREF_CTRL  0xE20\n#define EMC_TRAINING_READ_FINE_CTRL   0xE24\n#define EMC_TRAINING_READ_CTRL_MISC   0xE28\n#define EMC_TRAINING_READ_VREF_CTRL   0xE2C\n#define EMC_TRAINING_CA_FINE_CTRL     0xE30\n#define EMC_TRAINING_CA_CTRL_MISC     0xE34\n#define EMC_TRAINING_CA_CTRL_MISC1    0xE38\n#define EMC_TRAINING_CA_VREF_CTRL     0xE3C\n#define EMC_TRAINING_SETTLE           0xE44\n#define EMC_TRAINING_MPC              0xE5C\n#define EMC_TRAINING_PATRAM_CTRL      0xE60\n#define EMC_TRAINING_PATRAM_DQ        0xE64\n#define EMC_TRAINING_PATRAM_DMI       0xE68\n#define EMC_TRAINING_VREF_SETTLE      0xE6C\n#define EMC_TRAINING_OPT_CA_VREF      0xEC0\n#define EMC_TRAINING_OPT_DQ_OB_VREF   0xEC4\n#define EMC_TRAINING_QUSE_VREF_CTRL   0xED0\n#define EMC_TRAINING_OPT_DQS_IB_VREF_RANK0 0xED4\n#define EMC_TRAINING_OPT_DQS_IB_VREF_RANK1 0xED8\n\n/* Per channel registers offsets. Should be used with EMC_BASE */\n#define EMC0_MRW10 0x34B4\n#define EMC0_MRW11 0x34B8\n#define EMC0_MRW12 0x34BC\n#define EMC0_MRW13 0x34C0\n#define EMC0_DATA_BRLSHFT_0 0x3588\n#define EMC0_DATA_BRLSHFT_1 0x358C\n#define EMC0_CMD_BRLSHFT_0  0x359C\n#define EMC0_QUSE_BRLSHFT_0 0x35AC\n#define EMC0_QUSE_BRLSHFT_2 0x35BC\n#define EMC0_TRAINING_RW_OFFSET_IB_BYTE0 0x3E98\n#define EMC0_TRAINING_RW_OFFSET_IB_BYTE1 0x3E9C\n#define EMC0_TRAINING_RW_OFFSET_IB_BYTE2 0x3EA0\n#define EMC0_TRAINING_RW_OFFSET_IB_BYTE3 0x3EA4\n#define EMC0_TRAINING_RW_OFFSET_IB_MISC  0x3EA8\n#define EMC0_TRAINING_RW_OFFSET_OB_BYTE0 0x3EAC\n#define EMC0_TRAINING_RW_OFFSET_OB_BYTE1 0x3EB0\n#define EMC0_TRAINING_RW_OFFSET_OB_BYTE2 0x3EB4\n#define EMC0_TRAINING_RW_OFFSET_OB_BYTE3 0x3EB8\n#define EMC0_TRAINING_RW_OFFSET_OB_MISC  0x3EBC\n#define EMC0_TRAINING_OPT_DQS_IB_VREF_RANK0 0x3ED4\n#define EMC0_TRAINING_OPT_DQS_IB_VREF_RANK1 0x3ED8\n\n#define EMC1_MRW10 0x44B4\n#define EMC1_MRW11 0x44B8\n#define EMC1_MRW12 0x44BC\n#define EMC1_MRW13 0x44C0\n#define EMC1_DATA_BRLSHFT_0 0x4588\n#define EMC1_DATA_BRLSHFT_1 0x458C\n#define EMC1_CMD_BRLSHFT_1  0x45A0\n#define EMC1_QUSE_BRLSHFT_1 0x45B8\n#define EMC1_QUSE_BRLSHFT_3 0x45C4\n#define EMC1_TRAINING_RW_OFFSET_IB_BYTE0 0x4E98\n#define EMC1_TRAINING_RW_OFFSET_IB_BYTE1 0x4E9C\n#define EMC1_TRAINING_RW_OFFSET_IB_BYTE2 0x4EA0\n#define EMC1_TRAINING_RW_OFFSET_IB_BYTE3 0x4EA4\n#define EMC1_TRAINING_RW_OFFSET_IB_MISC  0x4EA8\n#define EMC1_TRAINING_RW_OFFSET_OB_BYTE0 0x4EAC\n#define EMC1_TRAINING_RW_OFFSET_OB_BYTE1 0x4EB0\n#define EMC1_TRAINING_RW_OFFSET_OB_BYTE2 0x4EB4\n#define EMC1_TRAINING_RW_OFFSET_OB_BYTE3 0x4EB8\n#define EMC1_TRAINING_RW_OFFSET_OB_MISC  0x4EBC\n#define EMC1_TRAINING_OPT_DQS_IB_VREF_RANK0 0x4ED4\n#define EMC1_TRAINING_OPT_DQS_IB_VREF_RANK1 0x4ED8\n\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_BYTE0_SHIFT 0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_BYTE1_SHIFT 16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_BYTE2_SHIFT 0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_BYTE3_SHIFT 16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_BYTE4_SHIFT 0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_BYTE5_SHIFT 16\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_BYTE6_SHIFT 0\n#define EMC_PMACRO_OB_DDLL_LONG_DQ_BYTE7_SHIFT 16\n\n#endif"
  },
  {
    "path": "modules/minerva/mtc_switch_tables.h",
    "content": "/*\n * Minerva Training Cell\n * DRAM Training for Tegra X1 SoC. Supports DDR2/3 and LPDDR3/4.\n *\n * Copyright (c) 2018 CTCaer  <ctcaer@gmail.com>\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _MTC_SWITCH_TABLES_H_\n#define _MTC_SWITCH_TABLES_H_\n\n// nx_abca2_0_3 and nx_abca2_1. For sdram ids 0,2,3,4\nstatic const unsigned char nx_abca2_0_3_10NoCfgVersion_V9_8_7_V1_6[49280] =\n{\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x34, 0x30, 0x38, 0x30, 0x30, 0x5F, 0x4E, 0x6F, 0x43,\n\t0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E, 0x37,\n\t0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x60, 0x9F, 0x00, 0x00, 0x20, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x70,\n\t0x5F, 0x6F, 0x75, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x18, 0x40,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0A, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00,\n\t0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08,\n\t0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x29, 0x00, 0x09, 0x00,\n\t0x15, 0x00, 0x29, 0x00, 0x0A, 0x00, 0x0B, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F,\n\t0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0x3A, 0x02, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0B, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x11, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x14, 0x00, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C,\n\t0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08,\n\t0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0xA0, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00,\n\t0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,\n\t0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00,\n\t0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x29, 0x00, 0x09, 0x00, 0x15, 0x00, 0x29, 0x00, 0x0A, 0x00, 0x0B, 0x00, 0x02, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x3A, 0x02, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x14, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x08, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x02, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x26, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48,\n\t0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00,\n\t0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,\n\t0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x29, 0x00, 0x09, 0x00, 0x15, 0x00, 0x29, 0x00, 0x0A, 0x00, 0x0B, 0x00,\n\t0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x3A, 0x02, 0x00, 0x80,\n\t0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x37, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00,\n\t0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x1B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x14, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x30,\n\t0x04, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x9A, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x48, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,\n\t0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00,\n\t0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00,\n\t0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x29, 0x00, 0x09, 0x00, 0x15, 0x00, 0x29, 0x00,\n\t0x0A, 0x00, 0x0B, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,\n\t0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0x3A, 0x02, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, 0x00, 0x05, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,\n\t0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x60, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x14, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07,\n\t0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x28, 0x00,\n\t0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,\n\t0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00,\n\t0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x7A, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x02, 0x40, 0x13, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00,\n\t0x03, 0x03, 0xC3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x76, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,\n\t0x3D, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x3D, 0x00, 0xFF, 0x00, 0x49, 0x00, 0xFF, 0x00,\n\t0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x12, 0x80, 0x18, 0x40, 0x01, 0x00, 0x00, 0x00, 0x72, 0x51, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x36, 0x38, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, 0x43,\n\t0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E, 0x37,\n\t0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xA0, 0x09, 0x01, 0x00, 0x20, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x70,\n\t0x5F, 0x6F, 0x75, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x80, 0x18, 0x40,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0A, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00,\n\t0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08,\n\t0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x44, 0x00, 0x09, 0x00,\n\t0x15, 0x00, 0x44, 0x00, 0x0A, 0x00, 0x11, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F,\n\t0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0x09, 0x03, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x11, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x11, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x22, 0x00, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C,\n\t0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08,\n\t0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x0A, 0x01, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00,\n\t0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,\n\t0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00,\n\t0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x44, 0x00, 0x09, 0x00, 0x15, 0x00, 0x44, 0x00, 0x0A, 0x00, 0x11, 0x00, 0x02, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x09, 0x03, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x11, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x22, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x08, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x02, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48,\n\t0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00,\n\t0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,\n\t0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x44, 0x00, 0x09, 0x00, 0x15, 0x00, 0x44, 0x00, 0x0A, 0x00, 0x11, 0x00,\n\t0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x09, 0x03, 0x00, 0x80,\n\t0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x37, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00,\n\t0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x11, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x1B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x22, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x30,\n\t0x04, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x48, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,\n\t0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00,\n\t0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00,\n\t0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x44, 0x00, 0x09, 0x00, 0x15, 0x00, 0x44, 0x00,\n\t0x0A, 0x00, 0x11, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,\n\t0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0x09, 0x03, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, 0x00, 0x05, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,\n\t0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x11, 0x60, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x22, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07,\n\t0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x28, 0x00,\n\t0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,\n\t0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00,\n\t0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0xF0, 0x24, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00,\n\t0x03, 0x03, 0x63, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0xC4, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,\n\t0x25, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x25, 0x00, 0xFF, 0x00, 0x49, 0x00, 0xFF, 0x00,\n\t0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x0A, 0x80, 0x18, 0x40, 0x01, 0x00, 0x00, 0x00, 0xE0, 0x29, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x31, 0x30, 0x32, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F,\n\t0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E,\n\t0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x70, 0x8E, 0x01, 0x00, 0x20, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x70,\n\t0x5F, 0x6F, 0x75, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x18, 0x40,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x82, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x8E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00,\n\t0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08,\n\t0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x66, 0x00, 0x09, 0x00,\n\t0x15, 0x00, 0x66, 0x00, 0x0A, 0x00, 0x1A, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F,\n\t0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0x0B, 0x04, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x1A, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x11, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x32, 0x00, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C,\n\t0x0C, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08,\n\t0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x82, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x8E, 0x01, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00,\n\t0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,\n\t0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00,\n\t0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x66, 0x00, 0x09, 0x00, 0x15, 0x00, 0x66, 0x00, 0x0A, 0x00, 0x1A, 0x00, 0x02, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x0B, 0x04, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x1A, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x32, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x0C, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x01, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x82, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x60, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48,\n\t0x8E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00,\n\t0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,\n\t0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x66, 0x00, 0x09, 0x00, 0x15, 0x00, 0x66, 0x00, 0x0A, 0x00, 0x1A, 0x00,\n\t0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x0B, 0x04, 0x00, 0x80,\n\t0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x37, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00,\n\t0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x1A, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x32, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x0C, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x30,\n\t0x03, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x82, 0x01, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x48, 0x8E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,\n\t0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00,\n\t0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00,\n\t0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x66, 0x00, 0x09, 0x00, 0x15, 0x00, 0x66, 0x00,\n\t0x0A, 0x00, 0x1A, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,\n\t0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0x0B, 0x04, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, 0x00, 0x05, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,\n\t0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x1A, 0x60, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x32, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07,\n\t0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x28, 0x00,\n\t0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,\n\t0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00,\n\t0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x50, 0x33, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00,\n\t0x03, 0x03, 0x03, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x26, 0x01, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,\n\t0x18, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x18, 0x00, 0xFF, 0x00, 0x49, 0x00, 0xFE, 0x00,\n\t0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x06, 0x80, 0x18, 0x40, 0x01, 0x00, 0x00, 0x00, 0xEA, 0x1A, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F,\n\t0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E,\n\t0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xE0, 0x1C, 0x03, 0x00, 0x20, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x70,\n\t0x5F, 0x6F, 0x75, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00,\n\t0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08,\n\t0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00,\n\t0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F,\n\t0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x33, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C,\n\t0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08,\n\t0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,\n\t0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00,\n\t0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,\n\t0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00,\n\t0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x08, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,\n\t0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48,\n\t0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00,\n\t0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,\n\t0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00,\n\t0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80,\n\t0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x37, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00,\n\t0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, 0x30,\n\t0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,\n\t0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,\n\t0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00,\n\t0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00,\n\t0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00,\n\t0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,\n\t0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, 0x00, 0x05, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,\n\t0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07,\n\t0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x28, 0x00,\n\t0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,\n\t0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00,\n\t0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00,\n\t0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00,\n\t0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,\n\t0x0C, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x0C, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x7F, 0x00,\n\t0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0xFF, 0x00, 0xC6, 0x00, 0xFF, 0x00, 0xC6, 0x00, 0xFF, 0x00, 0x6D, 0x00, 0xFF, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0xE2, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x01, 0x00, 0x00, 0x00, 0x5C, 0x0D, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x34, 0x30, 0x38, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F,\n\t0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E,\n\t0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xC0, 0x39, 0x06, 0x00, 0x2C, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x70,\n\t0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0xE0,\n\t0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,\n\t0x4A, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x12, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x30, 0x07, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0F, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x19, 0x00, 0x00, 0x00,\n\t0x21, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,\n\t0x07, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x1A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x4D, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x38, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x03, 0x1C, 0xC0, 0x00, 0x80, 0x00, 0x00,\n\t0xBE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08,\n\t0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00,\n\t0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x98, 0x01, 0x0E, 0x00,\n\t0x1B, 0x00, 0x98, 0x01, 0x0A, 0x00, 0x66, 0x00, 0x04, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F,\n\t0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0x00, 0x00, 0x00, 0x00, 0x22, 0x0D, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x35, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xFF, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x66, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x19, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0xCB, 0x00, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C,\n\t0x19, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x07, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08,\n\t0x0F, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00,\n\t0x19, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x21, 0x00, 0x00, 0x00, 0x07, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x38, 0x06, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x03, 0x1C, 0xC0,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x0B, 0x08, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,\n\t0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x98, 0x01, 0x0E, 0x00, 0x1B, 0x00, 0x98, 0x01, 0x0A, 0x00, 0x66, 0x00, 0x04, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x22, 0x0D, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x66, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x23, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0xCB, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x19, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x12, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x01, 0x00, 0x05, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x07, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x81, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48,\n\t0x38, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00,\n\t0xBB, 0x03, 0x1C, 0xC0, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x98, 0x01, 0x0E, 0x00, 0x1B, 0x00, 0x98, 0x01, 0x0A, 0x00, 0x66, 0x00,\n\t0x04, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x22, 0x0D, 0x00, 0x80,\n\t0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x35, 0x80, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00,\n\t0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE2, 0xFF, 0xEF,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x66, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0xCB, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x19, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00,\n\t0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30,\n\t0x07, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0F, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,\n\t0x23, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x07, 0x06, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00,\n\t0x4D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x48, 0x38, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x03, 0x1C, 0xC0, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x03, 0x00, 0x02, 0x00,\n\t0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,\n\t0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x98, 0x01, 0x0E, 0x00, 0x1B, 0x00, 0x98, 0x01,\n\t0x0A, 0x00, 0x66, 0x00, 0x04, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,\n\t0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00,\n\t0x22, 0x0D, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x35, 0x00, 0x05, 0x05,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,\n\t0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xFF, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x66, 0x60, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x23, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0xCB, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07,\n\t0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x21, 0x00, 0x20, 0x00,\n\t0x22, 0x00, 0x21, 0x00, 0x22, 0x00, 0x21, 0x00, 0x21, 0x00, 0x20, 0x00, 0x03, 0x00, 0x02, 0x00,\n\t0x02, 0x00, 0x03, 0x00, 0x21, 0x00, 0x20, 0x00, 0x22, 0x00, 0x21, 0x00, 0x22, 0x00, 0x21, 0x00,\n\t0x21, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x01, 0x7F, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x02, 0x03, 0x02, 0x04, 0x00,\n\t0x07, 0x0A, 0xA4, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x35, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x98, 0x04, 0x00, 0x00,\n\t0x59, 0x00, 0xFF, 0x00, 0x6D, 0x00, 0xFF, 0x00, 0x4F, 0x00, 0xFF, 0x00, 0xAF, 0x00, 0xFF, 0x00,\n\t0x06, 0x00, 0xFF, 0x00, 0xAF, 0x00, 0xFF, 0x00, 0x06, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x40, 0x00,\n\t0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0x57, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0xFF, 0x00, 0x63, 0x00, 0xFF, 0x00, 0x63, 0x00, 0xFF, 0x00, 0x36, 0x00, 0xFF, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0x71, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x14, 0x00, 0x01, 0x08, 0x09, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0xE0, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x06, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x36, 0x36, 0x35, 0x36, 0x30, 0x30, 0x5F, 0x4E, 0x6F,\n\t0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E,\n\t0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x28, 0x0A, 0x00, 0x39, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D,\n\t0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80,\n\t0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x2A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,\n\t0x78, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x30, 0x0A, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x11, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x1E, 0x00, 0x00, 0x00,\n\t0x26, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,\n\t0xE4, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x23, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,\n\t0x7D, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x24, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x0B, 0xC0, 0x00, 0x80, 0x00, 0x00,\n\t0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08,\n\t0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,\n\t0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00,\n\t0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x9A, 0x02, 0x15, 0x00,\n\t0x1F, 0x00, 0x9A, 0x02, 0x0A, 0x00, 0xA7, 0x00, 0x05, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F,\n\t0x14, 0x00, 0x01, 0x00, 0x06, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0x00, 0x00, 0x00, 0x00, 0xC9, 0x14, 0x00, 0x80, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x33, 0x00, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xFF, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0xA7, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,\n\t0x16, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x1E, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x4C, 0x01, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C,\n\t0x28, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0A, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08,\n\t0x11, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00,\n\t0x1E, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,\n\t0x26, 0x00, 0x00, 0x00, 0xE4, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x02, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x24, 0x0A, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x0B, 0xC0,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x0B, 0x08, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,\n\t0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x9A, 0x02, 0x15, 0x00, 0x1F, 0x00, 0x9A, 0x02, 0x0A, 0x00, 0xA7, 0x00, 0x05, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x06, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC9, 0x14, 0x00, 0x80, 0x16, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0xA7, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x29, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x1B, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x4C, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x16, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x0B, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x08, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x04, 0x00, 0x05, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,\n\t0x24, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0xE4, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x79, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x0E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48,\n\t0x24, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00,\n\t0xBB, 0x02, 0x0B, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,\n\t0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x9A, 0x02, 0x15, 0x00, 0x1F, 0x00, 0x9A, 0x02, 0x0A, 0x00, 0xA7, 0x00,\n\t0x05, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x06, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC9, 0x14, 0x00, 0x80,\n\t0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05,\n\t0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02,\n\t0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00,\n\t0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE2, 0xFF, 0xEF,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xA7, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x4C, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,\n\t0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30,\n\t0x0A, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x11, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,\n\t0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0xE4, 0x09, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x79, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00,\n\t0x7D, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x48, 0x24, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x0B, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x05, 0x00, 0x04, 0x00,\n\t0x04, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00,\n\t0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x9A, 0x02, 0x15, 0x00, 0x1F, 0x00, 0x9A, 0x02,\n\t0x0A, 0x00, 0xA7, 0x00, 0x05, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,\n\t0x06, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00,\n\t0xC9, 0x14, 0x00, 0x80, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x05, 0x05,\n\t0x00, 0x00, 0x05, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,\n\t0x11, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xFF, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xA7, 0x60, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,\n\t0x28, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x1E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x4C, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07,\n\t0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x22, 0x00, 0x20, 0x00,\n\t0x24, 0x00, 0x21, 0x00, 0x24, 0x00, 0x21, 0x00, 0x22, 0x00, 0x20, 0x00, 0x05, 0x00, 0x04, 0x00,\n\t0x04, 0x00, 0x05, 0x00, 0x22, 0x00, 0x20, 0x00, 0x24, 0x00, 0x21, 0x00, 0x24, 0x00, 0x21, 0x00,\n\t0x22, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x04, 0x03, 0x06, 0x00,\n\t0x0A, 0x0F, 0xA5, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x57, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x7E, 0x07, 0x00, 0x00,\n\t0x3D, 0x00, 0xFF, 0x00, 0x43, 0x00, 0xFF, 0x00, 0x41, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00,\n\t0x05, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00, 0x05, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x34, 0x00,\n\t0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0x35, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0xFF, 0x00, 0x3D, 0x00, 0xFF, 0x00, 0x3D, 0x00, 0xFF, 0x00, 0x29, 0x00, 0xFF, 0x00,\n\t0xD8, 0x00, 0xFF, 0x00, 0x45, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0x08, 0x12, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x04, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F,\n\t0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E,\n\t0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x35, 0x0C, 0x00, 0x39, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D,\n\t0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80,\n\t0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n\t0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x13, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,\n\t0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,\n\t0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00,\n\t0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08,\n\t0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,\n\t0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00,\n\t0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00,\n\t0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0xC8, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,\n\t0x17, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x20, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C,\n\t0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08,\n\t0x13, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,\n\t0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00,\n\t0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x2D, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,\n\t0x16, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,\n\t0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x0A, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x08, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x03, 0x00, 0x05, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,\n\t0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48,\n\t0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00,\n\t0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,\n\t0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00,\n\t0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80,\n\t0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02,\n\t0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00,\n\t0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00,\n\t0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,\n\t0x0F, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30,\n\t0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x13, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,\n\t0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00,\n\t0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00,\n\t0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00,\n\t0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03,\n\t0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00,\n\t0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,\n\t0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,\n\t0x29, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07,\n\t0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x23, 0x00, 0x1F, 0x00,\n\t0x24, 0x00, 0x22, 0x00, 0x24, 0x00, 0x22, 0x00, 0x23, 0x00, 0x20, 0x00, 0x06, 0x00, 0x05, 0x00,\n\t0x05, 0x00, 0x06, 0x00, 0x23, 0x00, 0x1F, 0x00, 0x24, 0x00, 0x22, 0x00, 0x24, 0x00, 0x22, 0x00,\n\t0x23, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x06, 0x04, 0x07, 0x00,\n\t0x0D, 0x12, 0x86, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x68, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x02, 0x09, 0x00, 0x00,\n\t0x3D, 0x00, 0xFF, 0x00, 0x38, 0x00, 0xFF, 0x00, 0x41, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00,\n\t0x05, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00, 0x05, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x34, 0x00,\n\t0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0x2C, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0xFF, 0x00, 0x32, 0x00, 0xFF, 0x00, 0x32, 0x00, 0xFF, 0x00, 0x22, 0x00, 0xFF, 0x00,\n\t0xB4, 0x00, 0xFF, 0x00, 0x3A, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0x08, 0x12, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x04, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x31, 0x30, 0x36, 0x35, 0x36, 0x30, 0x30, 0x5F, 0x4E,\n\t0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38,\n\t0x2E, 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x80, 0x42, 0x10, 0x00, 0x45, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D,\n\t0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80,\n\t0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0xC0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x2D, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,\n\t0x16, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x10, 0x0D, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x17, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x27, 0x00, 0x00, 0x00,\n\t0x2F, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00,\n\t0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x29, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,\n\t0xC8, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x10, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x01, 0xC0, 0x00, 0x80, 0x00, 0x00,\n\t0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x0B, 0x08,\n\t0x08, 0x00, 0x07, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03, 0x00,\n\t0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x07, 0x00, 0x07, 0x00,\n\t0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x2A, 0x04, 0x21, 0x00,\n\t0x25, 0x00, 0x2A, 0x04, 0x0F, 0x00, 0x0B, 0x01, 0x07, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x09, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0x00, 0x00, 0x00, 0x00, 0xAB, 0x20, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0B, 0x61, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x27, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x14, 0x02, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x03, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x4C, 0x48, 0x48, 0x0E, 0x4C,\n\t0x40, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x17, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x0D, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08,\n\t0x17, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00,\n\t0x27, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,\n\t0x2F, 0x00, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x21, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x3C, 0x10, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x01, 0xC0,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x06, 0x0B, 0x08, 0x08, 0x00, 0x07, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x01, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00,\n\t0x07, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x2A, 0x04, 0x21, 0x00, 0x25, 0x00, 0x2A, 0x04, 0x0F, 0x00, 0x0B, 0x01, 0x07, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x09, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xAB, 0x20, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x26, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x14, 0x02, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x40, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00, 0x00, 0x00,\n\t0xF1, 0xF1, 0x03, 0x08, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x07, 0x00, 0x05, 0x00, 0x27, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00,\n\t0x2D, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xFF, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,\n\t0x17, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48,\n\t0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xFF, 0x3B, 0x00, 0x00,\n\t0xBB, 0x01, 0x01, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x0B, 0x08, 0x08, 0x00, 0x07, 0x00, 0x06, 0x00, 0x08, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03, 0x00,\n\t0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x08, 0x00, 0x07, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x08, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x2A, 0x04, 0x21, 0x00, 0x25, 0x00, 0x2A, 0x04, 0x0F, 0x00, 0x0B, 0x01,\n\t0x07, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x09, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xAB, 0x20, 0x00, 0x80,\n\t0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02,\n\t0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00,\n\t0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x31, 0x00, 0x00, 0x00, 0x07, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x14, 0x02, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x40, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,\n\t0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,\n\t0x0D, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x17, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x27, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00,\n\t0x31, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,\n\t0xC8, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x2B, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n\t0xF1, 0xF1, 0x03, 0x48, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x01, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x0B, 0x08, 0x08, 0x00, 0x07, 0x00,\n\t0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x01, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x07, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00,\n\t0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x2A, 0x04, 0x21, 0x00, 0x25, 0x00, 0x2A, 0x04,\n\t0x0F, 0x00, 0x0B, 0x01, 0x07, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x09, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00,\n\t0xAB, 0x20, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,\n\t0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x61, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x31, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x27, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x14, 0x02, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07,\n\t0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x24, 0x00, 0x1F, 0x00,\n\t0x26, 0x00, 0x23, 0x00, 0x26, 0x00, 0x23, 0x00, 0x24, 0x00, 0x20, 0x00, 0x08, 0x00, 0x07, 0x00,\n\t0x06, 0x00, 0x08, 0x00, 0x24, 0x00, 0x1F, 0x00, 0x26, 0x00, 0x23, 0x00, 0x26, 0x00, 0x23, 0x00,\n\t0x24, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x03, 0x03, 0x04, 0x03, 0x08, 0x05, 0x09, 0x00,\n\t0x11, 0x18, 0x88, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x8B, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0xFF, 0x0B, 0x00, 0x00,\n\t0x3D, 0x00, 0xC0, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x41, 0x00, 0xC0, 0x00, 0x90, 0x00, 0xC0, 0x00,\n\t0x05, 0x00, 0xC0, 0x00, 0x90, 0x00, 0xC0, 0x00, 0x05, 0x00, 0xC0, 0x00, 0x49, 0x00, 0x34, 0x00,\n\t0x80, 0x00, 0xC0, 0x00, 0x04, 0x00, 0xC0, 0x00, 0x21, 0x00, 0x08, 0x00, 0xC0, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0xC0, 0x00, 0x26, 0x00, 0xC0, 0x00, 0x26, 0x00, 0xC0, 0x00, 0x19, 0x00, 0xC0, 0x00,\n\t0x95, 0x00, 0xC0, 0x00, 0x2B, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,\n\t0xC0, 0x00, 0xC0, 0x00, 0x25, 0x00, 0x00, 0x00, 0x34, 0x00, 0x01, 0x08, 0x1B, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x48, 0x48, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x25, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x04, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x31, 0x33, 0x33, 0x31, 0x32, 0x30, 0x30, 0x5F, 0x4E,\n\t0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38,\n\t0x2E, 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x50, 0x14, 0x00, 0x52, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D,\n\t0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80,\n\t0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,\n\t0xF0, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,\n\t0x18, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x10, 0x11, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1A, 0x00, 0x00, 0x00,\n\t0x1A, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x09, 0x00, 0x06, 0x00, 0x2E, 0x00, 0x00, 0x00,\n\t0x36, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,\n\t0x08, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,\n\t0x0E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x30, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,\n\t0xFA, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x12, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00,\n\t0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x0B, 0x08,\n\t0x0A, 0x00, 0x09, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00,\n\t0x07, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x09, 0x00,\n\t0x08, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x34, 0x05, 0x29, 0x00,\n\t0x2B, 0x00, 0x34, 0x05, 0x13, 0x00, 0x4D, 0x01, 0x08, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0x00, 0x00, 0x00, 0x00, 0x8F, 0x28, 0x00, 0x80, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x4D, 0x61, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,\n\t0x26, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x2E, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x99, 0x02, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x4C, 0x48, 0x48, 0x0E, 0x4C,\n\t0x50, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x0E, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x17, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x11, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08,\n\t0x1A, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x09, 0x00, 0x06, 0x00,\n\t0x2E, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x36, 0x00, 0x00, 0x00, 0x08, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00,\n\t0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x27, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x48, 0x14, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x06, 0x0B, 0x08, 0x0A, 0x00, 0x09, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x02, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x0A, 0x00,\n\t0x09, 0x00, 0x09, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x34, 0x05, 0x29, 0x00, 0x2B, 0x00, 0x34, 0x05, 0x13, 0x00, 0x4D, 0x01, 0x08, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8F, 0x28, 0x00, 0x80, 0x26, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x4D, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x3A, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x2C, 0x00, 0x00, 0x00, 0x09, 0x00, 0x06, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x99, 0x02, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x50, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x26, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x18, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x12, 0x00, 0x00, 0x00,\n\t0xF1, 0xF1, 0x03, 0x08, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x0A, 0x00, 0x06, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x08, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x02, 0x05, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,\n\t0x1C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48,\n\t0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xFF, 0x3B, 0x00, 0x00,\n\t0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x0B, 0x08, 0x0A, 0x00, 0x09, 0x00, 0x08, 0x00, 0x0A, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00,\n\t0x07, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x09, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x0A, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x34, 0x05, 0x29, 0x00, 0x2B, 0x00, 0x34, 0x05, 0x13, 0x00, 0x4D, 0x01,\n\t0x08, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8F, 0x28, 0x00, 0x80,\n\t0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02,\n\t0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00,\n\t0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x4D, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x38, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x99, 0x02, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x50, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00,\n\t0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,\n\t0x18, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,\n\t0x11, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1A, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x09, 0x00, 0x06, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,\n\t0x38, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x08, 0x14, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x00,\n\t0xFA, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x36, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0xF1, 0xF1, 0x03, 0x48, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x0B, 0x08, 0x0A, 0x00, 0x09, 0x00,\n\t0x08, 0x00, 0x0A, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x02, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x09, 0x00, 0x08, 0x00, 0x08, 0x00,\n\t0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x34, 0x05, 0x29, 0x00, 0x2B, 0x00, 0x34, 0x05,\n\t0x13, 0x00, 0x4D, 0x01, 0x08, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x0B, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00,\n\t0x8F, 0x28, 0x00, 0x80, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,\n\t0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x4D, 0x61, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,\n\t0x38, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x2E, 0x00, 0x00, 0x00, 0x09, 0x00, 0x06, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x99, 0x02, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07,\n\t0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x25, 0x00, 0x1F, 0x00,\n\t0x28, 0x00, 0x23, 0x00, 0x28, 0x00, 0x23, 0x00, 0x25, 0x00, 0x20, 0x00, 0x0A, 0x00, 0x09, 0x00,\n\t0x08, 0x00, 0x0A, 0x00, 0x25, 0x00, 0x1F, 0x00, 0x28, 0x00, 0x23, 0x00, 0x28, 0x00, 0x23, 0x00,\n\t0x25, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x03, 0x03, 0x05, 0x04, 0x09, 0x07, 0x0B, 0x00,\n\t0x14, 0x1E, 0x8A, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0xAD, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0xFC, 0x0E, 0x00, 0x00,\n\t0x3D, 0x00, 0x99, 0x00, 0x38, 0x00, 0x99, 0x00, 0x41, 0x00, 0x99, 0x00, 0x90, 0x00, 0x99, 0x00,\n\t0x05, 0x00, 0x99, 0x00, 0x90, 0x00, 0x99, 0x00, 0x05, 0x00, 0x99, 0x00, 0x49, 0x00, 0x34, 0x00,\n\t0x80, 0x00, 0x99, 0x00, 0x04, 0x00, 0x99, 0x00, 0x1B, 0x00, 0x08, 0x00, 0x99, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x99, 0x00, 0x1E, 0x00, 0x99, 0x00, 0x1E, 0x00, 0x99, 0x00, 0x18, 0x00, 0x99, 0x00,\n\t0x95, 0x00, 0x99, 0x00, 0x23, 0x00, 0x99, 0x00, 0x99, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,\n\t0x99, 0x00, 0x99, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x44, 0x00, 0x01, 0x08, 0x24, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x48, 0x48, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x2D, 0x08, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x31, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5F, 0x4E,\n\t0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38,\n\t0x2E, 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x6A, 0x18, 0x00, 0x77, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D,\n\t0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80,\n\t0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,\n\t0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n\t0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10,\n\t0x02, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,\n\t0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n\t0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00,\n\t0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00,\n\t0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x0B, 0x08,\n\t0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00,\n\t0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00,\n\t0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00,\n\t0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x90, 0x61, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,\n\t0x2C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x34, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x48, 0x48, 0x0C, 0x88, 0x48, 0x48, 0x0C, 0x88, 0x48, 0x48, 0x0C, 0x48, 0x48, 0x48, 0x0C, 0x48,\n\t0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x4C, 0x48, 0x48, 0x0E, 0x4C,\n\t0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,\n\t0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,\n\t0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x1C, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08,\n\t0x1D, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00,\n\t0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00,\n\t0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00,\n\t0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x42, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x34, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,\n\t0x29, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,\n\t0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x16, 0x00, 0x00, 0x00,\n\t0xF1, 0xF1, 0x03, 0x08, 0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x0E, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00,\n\t0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48,\n\t0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00,\n\t0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00,\n\t0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01,\n\t0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80,\n\t0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02,\n\t0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00,\n\t0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x3E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,\n\t0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,\n\t0x1D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,\n\t0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10,\n\t0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,\n\t0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,\n\t0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00,\n\t0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99,\n\t0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00,\n\t0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00,\n\t0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06,\n\t0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00,\n\t0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,\n\t0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,\n\t0x3E, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x34, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07,\n\t0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x26, 0x00, 0x1E, 0x00,\n\t0x29, 0x00, 0x24, 0x00, 0x29, 0x00, 0x24, 0x00, 0x26, 0x00, 0x20, 0x00, 0x0C, 0x00, 0x0B, 0x00,\n\t0x0A, 0x00, 0x0C, 0x00, 0x26, 0x00, 0x1E, 0x00, 0x29, 0x00, 0x24, 0x00, 0x29, 0x00, 0x24, 0x00,\n\t0x26, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,\n\t0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x03, 0x03, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00,\n\t0x19, 0x24, 0x8C, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x03, 0x12, 0x00, 0x00,\n\t0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00,\n\t0x05, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x00, 0x80, 0x00, 0x49, 0x00, 0x34, 0x00,\n\t0x80, 0x00, 0x80, 0x00, 0x04, 0x00, 0x80, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x80, 0x00, 0x19, 0x00, 0x80, 0x00, 0x19, 0x00, 0x80, 0x00, 0x18, 0x00, 0x80, 0x00,\n\t0x95, 0x00, 0x80, 0x00, 0x1D, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,\n\t0x80, 0x00, 0x80, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x54, 0x00, 0x01, 0x08, 0x2D, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x48, 0x48, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x04, 0x00, 0x00\n};\n\n// nx_abca2_2. For sdram id 1.\nstatic const unsigned char nx_abca2_2_10NoCfgVersion_V9_8_7_V1_6[49280] =\n{\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x34, 0x30, 0x38, 0x30, 0x30, 0x5F, 0x4E, 0x6F, 0x43,\n\t0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E, 0x37,\n\t0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x60, 0x9F, 0x00, 0x00, 0x20, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x70,\n\t0x5F, 0x6F, 0x75, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x18, 0x40,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0A, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00,\n\t0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08,\n\t0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x29, 0x00, 0x09, 0x00,\n\t0x15, 0x00, 0x29, 0x00, 0x0A, 0x00, 0x0B, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F,\n\t0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0x3A, 0x02, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0B, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x11, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x14, 0x00, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C,\n\t0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08,\n\t0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0xA0, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00,\n\t0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,\n\t0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00,\n\t0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x29, 0x00, 0x09, 0x00, 0x15, 0x00, 0x29, 0x00, 0x0A, 0x00, 0x0B, 0x00, 0x02, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x3A, 0x02, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x02, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x14, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x08, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x02, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x26, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48,\n\t0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00,\n\t0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,\n\t0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x29, 0x00, 0x09, 0x00, 0x15, 0x00, 0x29, 0x00, 0x0A, 0x00, 0x0B, 0x00,\n\t0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x3A, 0x02, 0x00, 0x80,\n\t0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x37, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00,\n\t0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x1B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x14, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x30,\n\t0x04, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x9A, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x48, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,\n\t0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00,\n\t0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00,\n\t0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x29, 0x00, 0x09, 0x00, 0x15, 0x00, 0x29, 0x00,\n\t0x0A, 0x00, 0x0B, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,\n\t0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0x3A, 0x02, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, 0x00, 0x05, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,\n\t0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x60, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x14, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07,\n\t0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x28, 0x00,\n\t0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,\n\t0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00,\n\t0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x7A, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x02, 0x40, 0x13, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00,\n\t0x03, 0x03, 0xC3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x76, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,\n\t0x3D, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x3D, 0x00, 0xFF, 0x00, 0x49, 0x00, 0xFF, 0x00,\n\t0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x12, 0x80, 0x18, 0x40, 0x01, 0x00, 0x00, 0x00, 0x72, 0x51, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x36, 0x38, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, 0x43,\n\t0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E, 0x37,\n\t0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xA0, 0x09, 0x01, 0x00, 0x20, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x70,\n\t0x5F, 0x6F, 0x75, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x80, 0x18, 0x40,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0A, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00,\n\t0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08,\n\t0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x44, 0x00, 0x09, 0x00,\n\t0x15, 0x00, 0x44, 0x00, 0x0A, 0x00, 0x11, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F,\n\t0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0x09, 0x03, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x11, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x11, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x22, 0x00, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C,\n\t0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08,\n\t0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x0A, 0x01, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00,\n\t0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,\n\t0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00,\n\t0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x44, 0x00, 0x09, 0x00, 0x15, 0x00, 0x44, 0x00, 0x0A, 0x00, 0x11, 0x00, 0x02, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x09, 0x03, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x02, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x11, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x22, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x08, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x02, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48,\n\t0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00,\n\t0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,\n\t0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x44, 0x00, 0x09, 0x00, 0x15, 0x00, 0x44, 0x00, 0x0A, 0x00, 0x11, 0x00,\n\t0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x09, 0x03, 0x00, 0x80,\n\t0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x37, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00,\n\t0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x11, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x1B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x22, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x30,\n\t0x04, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x48, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,\n\t0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00,\n\t0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00,\n\t0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x44, 0x00, 0x09, 0x00, 0x15, 0x00, 0x44, 0x00,\n\t0x0A, 0x00, 0x11, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,\n\t0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0x09, 0x03, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, 0x00, 0x05, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,\n\t0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x11, 0x60, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x22, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07,\n\t0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x28, 0x00,\n\t0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,\n\t0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00,\n\t0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0xF0, 0x24, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00,\n\t0x03, 0x03, 0x63, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0xC4, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,\n\t0x25, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x25, 0x00, 0xFF, 0x00, 0x49, 0x00, 0xFF, 0x00,\n\t0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x0A, 0x80, 0x18, 0x40, 0x01, 0x00, 0x00, 0x00, 0xE0, 0x29, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x31, 0x30, 0x32, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F,\n\t0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E,\n\t0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x70, 0x8E, 0x01, 0x00, 0x20, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x70,\n\t0x5F, 0x6F, 0x75, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x18, 0x40,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0B, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x82, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x8E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00,\n\t0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08,\n\t0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x66, 0x00, 0x09, 0x00,\n\t0x15, 0x00, 0x66, 0x00, 0x0A, 0x00, 0x1A, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F,\n\t0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0x0B, 0x04, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x1A, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x11, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x32, 0x00, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C,\n\t0x0C, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08,\n\t0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x82, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x8E, 0x01, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00,\n\t0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,\n\t0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00,\n\t0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x66, 0x00, 0x09, 0x00, 0x15, 0x00, 0x66, 0x00, 0x0A, 0x00, 0x1A, 0x00, 0x02, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x0B, 0x04, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x02, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x1A, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x32, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x0C, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x01, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x82, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x60, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48,\n\t0x8E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00,\n\t0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,\n\t0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x66, 0x00, 0x09, 0x00, 0x15, 0x00, 0x66, 0x00, 0x0A, 0x00, 0x1A, 0x00,\n\t0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x0B, 0x04, 0x00, 0x80,\n\t0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x37, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x04, 0x04, 0x10, 0x00,\n\t0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x1A, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x32, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x0C, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x30,\n\t0x03, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x82, 0x01, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x48, 0x8E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,\n\t0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00,\n\t0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00,\n\t0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x66, 0x00, 0x09, 0x00, 0x15, 0x00, 0x66, 0x00,\n\t0x0A, 0x00, 0x1A, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,\n\t0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0x0B, 0x04, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, 0x00, 0x05, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,\n\t0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x04, 0x04, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x1A, 0x60, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x32, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07,\n\t0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x28, 0x00,\n\t0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,\n\t0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00,\n\t0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x50, 0x33, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00,\n\t0x03, 0x03, 0x03, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x26, 0x01, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,\n\t0x18, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x18, 0x00, 0xFF, 0x00, 0x49, 0x00, 0xFE, 0x00,\n\t0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x06, 0x80, 0x18, 0x40, 0x01, 0x00, 0x00, 0x00, 0xEA, 0x1A, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F,\n\t0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E,\n\t0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xE0, 0x1C, 0x03, 0x00, 0x20, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x70,\n\t0x5F, 0x6F, 0x75, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00,\n\t0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08,\n\t0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00,\n\t0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F,\n\t0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x33, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C,\n\t0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08,\n\t0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00,\n\t0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00,\n\t0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,\n\t0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00,\n\t0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x02, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x08, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,\n\t0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48,\n\t0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00,\n\t0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,\n\t0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,\n\t0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00,\n\t0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80,\n\t0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x37, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00,\n\t0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, 0x30,\n\t0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,\n\t0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00,\n\t0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,\n\t0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00,\n\t0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00,\n\t0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00,\n\t0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,\n\t0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F,\n\t0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, 0x00, 0x05, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,\n\t0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07,\n\t0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x28, 0x00,\n\t0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,\n\t0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00,\n\t0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00,\n\t0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00,\n\t0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00,\n\t0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,\n\t0x0C, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x0C, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x7F, 0x00,\n\t0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0xFF, 0x00, 0xC6, 0x00, 0xFF, 0x00, 0xC6, 0x00, 0xFF, 0x00, 0x6D, 0x00, 0xFF, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0xE2, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x01, 0x00, 0x00, 0x00, 0x5C, 0x0D, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x34, 0x30, 0x38, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F,\n\t0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E,\n\t0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xC0, 0x39, 0x06, 0x00, 0x2C, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x70,\n\t0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0xE0,\n\t0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,\n\t0x4A, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x12, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x30, 0x07, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0F, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0x01, 0x00, 0x19, 0x00, 0x00, 0x00,\n\t0x21, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,\n\t0x07, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x1A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x4D, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x38, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x03, 0x1C, 0xC0, 0x00, 0x80, 0x00, 0x00,\n\t0xBE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08,\n\t0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00,\n\t0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x98, 0x01, 0x0E, 0x00,\n\t0x1B, 0x00, 0x98, 0x01, 0x0A, 0x00, 0x66, 0x00, 0x04, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F,\n\t0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0x00, 0x00, 0x00, 0x00, 0x22, 0x0D, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x35, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xFF, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x66, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x19, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0xCB, 0x00, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C,\n\t0x19, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,\n\t0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x07, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08,\n\t0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0x01, 0x00,\n\t0x19, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x21, 0x00, 0x00, 0x00, 0x07, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x38, 0x06, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x03, 0x1C, 0xC0,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x0B, 0x08, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,\n\t0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x98, 0x01, 0x0E, 0x00, 0x1B, 0x00, 0x98, 0x01, 0x0A, 0x00, 0x66, 0x00, 0x04, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x22, 0x0D, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x02, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x66, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x23, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0xCB, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x19, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x01, 0x00, 0x05, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x07, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x81, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48,\n\t0x38, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00,\n\t0xBB, 0x03, 0x1C, 0xC0, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x98, 0x01, 0x0E, 0x00, 0x1B, 0x00, 0x98, 0x01, 0x0A, 0x00, 0x66, 0x00,\n\t0x04, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x22, 0x0D, 0x00, 0x80,\n\t0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x35, 0x80, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00,\n\t0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE2, 0xFF, 0xEF,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x66, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0xCB, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x19, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00,\n\t0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30,\n\t0x07, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,\n\t0x23, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x07, 0x06, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00,\n\t0x4D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x48, 0x38, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x03, 0x1C, 0xC0, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x03, 0x00, 0x02, 0x00,\n\t0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,\n\t0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x98, 0x01, 0x0E, 0x00, 0x1B, 0x00, 0x98, 0x01,\n\t0x0A, 0x00, 0x66, 0x00, 0x04, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,\n\t0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00,\n\t0x22, 0x0D, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x35, 0x00, 0x05, 0x05,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,\n\t0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xFF, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x66, 0x60, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x23, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0xCB, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07,\n\t0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x21, 0x00, 0x20, 0x00,\n\t0x22, 0x00, 0x21, 0x00, 0x22, 0x00, 0x21, 0x00, 0x21, 0x00, 0x20, 0x00, 0x03, 0x00, 0x02, 0x00,\n\t0x02, 0x00, 0x03, 0x00, 0x21, 0x00, 0x20, 0x00, 0x22, 0x00, 0x21, 0x00, 0x22, 0x00, 0x21, 0x00,\n\t0x21, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x01, 0x7F, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x02, 0x03, 0x02, 0x04, 0x00,\n\t0x07, 0x0A, 0xA4, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x35, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x98, 0x04, 0x00, 0x00,\n\t0x59, 0x00, 0xFF, 0x00, 0x6D, 0x00, 0xFF, 0x00, 0x4F, 0x00, 0xFF, 0x00, 0xAF, 0x00, 0xFF, 0x00,\n\t0x06, 0x00, 0xFF, 0x00, 0xAF, 0x00, 0xFF, 0x00, 0x06, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x40, 0x00,\n\t0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0x57, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0xFF, 0x00, 0x63, 0x00, 0xFF, 0x00, 0x63, 0x00, 0xFF, 0x00, 0x36, 0x00, 0xFF, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0x71, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x14, 0x00, 0x01, 0x08, 0x09, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0xE0, 0x01, 0x00, 0x00, 0x00, 0xD6, 0x06, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x36, 0x36, 0x35, 0x36, 0x30, 0x30, 0x5F, 0x4E, 0x6F,\n\t0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E,\n\t0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x28, 0x0A, 0x00, 0x39, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D,\n\t0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80,\n\t0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x2A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,\n\t0x78, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x30, 0x0A, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x11, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x01, 0x00, 0x1E, 0x00, 0x00, 0x00,\n\t0x26, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,\n\t0xE4, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x23, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,\n\t0x7D, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x24, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x0B, 0xC0, 0x00, 0x80, 0x00, 0x00,\n\t0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08,\n\t0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,\n\t0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00,\n\t0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x9A, 0x02, 0x15, 0x00,\n\t0x1F, 0x00, 0x9A, 0x02, 0x0A, 0x00, 0xA7, 0x00, 0x05, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F,\n\t0x14, 0x00, 0x01, 0x00, 0x06, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0x00, 0x00, 0x00, 0x00, 0xC9, 0x14, 0x00, 0x80, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x33, 0x00, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xFF, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0xA7, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,\n\t0x16, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x1E, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x4C, 0x01, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C,\n\t0x28, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0A, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08,\n\t0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x01, 0x00,\n\t0x1E, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,\n\t0x26, 0x00, 0x00, 0x00, 0xE4, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x02, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x24, 0x0A, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x0B, 0xC0,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x0B, 0x08, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,\n\t0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x9A, 0x02, 0x15, 0x00, 0x1F, 0x00, 0x9A, 0x02, 0x0A, 0x00, 0xA7, 0x00, 0x05, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x06, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC9, 0x14, 0x00, 0x80, 0x16, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x02, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0xA7, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x29, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x1B, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x4C, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x0B, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x08, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x04, 0x00, 0x05, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,\n\t0x24, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0xE4, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x79, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x0E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48,\n\t0x24, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00,\n\t0xBB, 0x02, 0x0B, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,\n\t0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x9A, 0x02, 0x15, 0x00, 0x1F, 0x00, 0x9A, 0x02, 0x0A, 0x00, 0xA7, 0x00,\n\t0x05, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x06, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC9, 0x14, 0x00, 0x80,\n\t0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05,\n\t0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02,\n\t0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00,\n\t0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE2, 0xFF, 0xEF,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xA7, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x4C, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,\n\t0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30,\n\t0x0A, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x05, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,\n\t0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0xE4, 0x09, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x79, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00,\n\t0x7D, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x48, 0x24, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x0B, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x05, 0x00, 0x04, 0x00,\n\t0x04, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00,\n\t0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x9A, 0x02, 0x15, 0x00, 0x1F, 0x00, 0x9A, 0x02,\n\t0x0A, 0x00, 0xA7, 0x00, 0x05, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,\n\t0x06, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00,\n\t0xC9, 0x14, 0x00, 0x80, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x05, 0x05,\n\t0x00, 0x00, 0x05, 0x05, 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,\n\t0x11, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xFF, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xA7, 0x60, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,\n\t0x28, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x1E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x4C, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07,\n\t0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x22, 0x00, 0x20, 0x00,\n\t0x24, 0x00, 0x21, 0x00, 0x24, 0x00, 0x21, 0x00, 0x22, 0x00, 0x20, 0x00, 0x05, 0x00, 0x04, 0x00,\n\t0x04, 0x00, 0x05, 0x00, 0x22, 0x00, 0x20, 0x00, 0x24, 0x00, 0x21, 0x00, 0x24, 0x00, 0x21, 0x00,\n\t0x22, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x01, 0x03, 0x04, 0x03, 0x04, 0x03, 0x06, 0x00,\n\t0x0A, 0x0F, 0xA5, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x57, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x7E, 0x07, 0x00, 0x00,\n\t0x3D, 0x00, 0xFF, 0x00, 0x43, 0x00, 0xFF, 0x00, 0x41, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00,\n\t0x05, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00, 0x05, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x34, 0x00,\n\t0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0x35, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0xFF, 0x00, 0x3D, 0x00, 0xFF, 0x00, 0x3D, 0x00, 0xFF, 0x00, 0x29, 0x00, 0xFF, 0x00,\n\t0xD8, 0x00, 0xFF, 0x00, 0x45, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0x08, 0x12, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x04, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F,\n\t0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E,\n\t0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x35, 0x0C, 0x00, 0x39, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D,\n\t0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80,\n\t0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n\t0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x13, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,\n\t0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,\n\t0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00,\n\t0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08,\n\t0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,\n\t0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00,\n\t0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00,\n\t0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0xC8, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,\n\t0x17, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x20, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C,\n\t0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08,\n\t0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x05, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,\n\t0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00,\n\t0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x2D, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,\n\t0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,\n\t0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x0A, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x08, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x03, 0x00, 0x05, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,\n\t0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48,\n\t0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00,\n\t0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,\n\t0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00,\n\t0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80,\n\t0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02,\n\t0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00,\n\t0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00,\n\t0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,\n\t0x0F, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30,\n\t0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,\n\t0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00,\n\t0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00,\n\t0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00,\n\t0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03,\n\t0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00,\n\t0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,\n\t0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,\n\t0x29, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07,\n\t0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x23, 0x00, 0x1F, 0x00,\n\t0x24, 0x00, 0x22, 0x00, 0x24, 0x00, 0x22, 0x00, 0x23, 0x00, 0x20, 0x00, 0x06, 0x00, 0x05, 0x00,\n\t0x05, 0x00, 0x06, 0x00, 0x23, 0x00, 0x1F, 0x00, 0x24, 0x00, 0x22, 0x00, 0x24, 0x00, 0x22, 0x00,\n\t0x23, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x03, 0x03, 0x04, 0x03, 0x06, 0x04, 0x07, 0x00,\n\t0x0D, 0x12, 0x86, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x68, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x02, 0x09, 0x00, 0x00,\n\t0x3D, 0x00, 0xFF, 0x00, 0x38, 0x00, 0xFF, 0x00, 0x41, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00,\n\t0x05, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00, 0x05, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x34, 0x00,\n\t0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0x2C, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0xFF, 0x00, 0x32, 0x00, 0xFF, 0x00, 0x32, 0x00, 0xFF, 0x00, 0x22, 0x00, 0xFF, 0x00,\n\t0xB4, 0x00, 0xFF, 0x00, 0x3A, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,\n\t0xFF, 0x00, 0xFF, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0x08, 0x12, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x04, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x31, 0x30, 0x36, 0x35, 0x36, 0x30, 0x30, 0x5F, 0x4E,\n\t0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38,\n\t0x2E, 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x80, 0x42, 0x10, 0x00, 0x45, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D,\n\t0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80,\n\t0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0xC0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x2D, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,\n\t0x16, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x10, 0x0D, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x17, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x06, 0x00, 0x05, 0x00, 0x27, 0x00, 0x00, 0x00,\n\t0x2F, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00,\n\t0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x29, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,\n\t0xC8, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x10, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x01, 0xC0, 0x00, 0x80, 0x00, 0x00,\n\t0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x0B, 0x08,\n\t0x08, 0x00, 0x07, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03, 0x00,\n\t0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x07, 0x00, 0x07, 0x00,\n\t0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x2A, 0x04, 0x21, 0x00,\n\t0x25, 0x00, 0x2A, 0x04, 0x0F, 0x00, 0x0B, 0x01, 0x07, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x09, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0x00, 0x00, 0x00, 0x00, 0xAB, 0x20, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0B, 0x61, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x27, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x14, 0x02, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x03, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x4C, 0x48, 0x48, 0x0E, 0x4C,\n\t0x40, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,\n\t0x17, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x11, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x0D, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08,\n\t0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x06, 0x00, 0x05, 0x00,\n\t0x27, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,\n\t0x2F, 0x00, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x21, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x3C, 0x10, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x01, 0xC0,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x06, 0x0B, 0x08, 0x08, 0x00, 0x07, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x01, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00,\n\t0x07, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x2A, 0x04, 0x21, 0x00, 0x25, 0x00, 0x2A, 0x04, 0x0F, 0x00, 0x0B, 0x01, 0x07, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x09, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xAB, 0x20, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x26, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x14, 0x02, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x40, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x21, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00, 0x00, 0x00,\n\t0xF1, 0xF1, 0x03, 0x08, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x07, 0x00, 0x05, 0x00, 0x27, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00,\n\t0x2D, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xFF, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,\n\t0x17, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48,\n\t0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xFF, 0x3B, 0x00, 0x00,\n\t0xBB, 0x01, 0x01, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x0B, 0x08, 0x08, 0x00, 0x07, 0x00, 0x06, 0x00, 0x08, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03, 0x00,\n\t0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x08, 0x00, 0x07, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x08, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x2A, 0x04, 0x21, 0x00, 0x25, 0x00, 0x2A, 0x04, 0x0F, 0x00, 0x0B, 0x01,\n\t0x07, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x09, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xAB, 0x20, 0x00, 0x80,\n\t0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02,\n\t0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00,\n\t0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF,\n\t0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x31, 0x00, 0x00, 0x00, 0x07, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x14, 0x02, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x40, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,\n\t0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,\n\t0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,\n\t0x0D, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x80, 0x06, 0x00, 0x05, 0x00, 0x27, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00,\n\t0x31, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,\n\t0xC8, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x2B, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n\t0xF1, 0xF1, 0x03, 0x48, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x01, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x0B, 0x08, 0x08, 0x00, 0x07, 0x00,\n\t0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x01, 0x00,\n\t0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x07, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00,\n\t0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x2A, 0x04, 0x21, 0x00, 0x25, 0x00, 0x2A, 0x04,\n\t0x0F, 0x00, 0x0B, 0x01, 0x07, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x09, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00,\n\t0xAB, 0x20, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,\n\t0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x61, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x31, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x27, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x14, 0x02, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07,\n\t0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x24, 0x00, 0x1F, 0x00,\n\t0x26, 0x00, 0x23, 0x00, 0x26, 0x00, 0x23, 0x00, 0x24, 0x00, 0x20, 0x00, 0x08, 0x00, 0x07, 0x00,\n\t0x06, 0x00, 0x08, 0x00, 0x24, 0x00, 0x1F, 0x00, 0x26, 0x00, 0x23, 0x00, 0x26, 0x00, 0x23, 0x00,\n\t0x24, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x03, 0x03, 0x05, 0x03, 0x08, 0x05, 0x09, 0x00,\n\t0x11, 0x18, 0x88, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x8B, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0xFF, 0x0B, 0x00, 0x00,\n\t0x3D, 0x00, 0xC0, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x41, 0x00, 0xC0, 0x00, 0x90, 0x00, 0xC0, 0x00,\n\t0x05, 0x00, 0xC0, 0x00, 0x90, 0x00, 0xC0, 0x00, 0x05, 0x00, 0xC0, 0x00, 0x49, 0x00, 0x34, 0x00,\n\t0x80, 0x00, 0xC0, 0x00, 0x04, 0x00, 0xC0, 0x00, 0x21, 0x00, 0x08, 0x00, 0xC0, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0xC0, 0x00, 0x26, 0x00, 0xC0, 0x00, 0x26, 0x00, 0xC0, 0x00, 0x19, 0x00, 0xC0, 0x00,\n\t0x95, 0x00, 0xC0, 0x00, 0x2B, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,\n\t0xC0, 0x00, 0xC0, 0x00, 0x25, 0x00, 0x00, 0x00, 0x34, 0x00, 0x01, 0x08, 0x1B, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x48, 0x48, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x25, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x04, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x31, 0x33, 0x33, 0x31, 0x32, 0x30, 0x30, 0x5F, 0x4E,\n\t0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38,\n\t0x2E, 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x50, 0x14, 0x00, 0x52, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D,\n\t0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80,\n\t0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,\n\t0xF0, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,\n\t0x18, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x10, 0x11, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1A, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x09, 0x00, 0x06, 0x00, 0x2E, 0x00, 0x00, 0x00,\n\t0x36, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,\n\t0x08, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,\n\t0x0E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x30, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,\n\t0xFA, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x12, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x91, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00,\n\t0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x0B, 0x08,\n\t0x0A, 0x00, 0x09, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00,\n\t0x07, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x09, 0x00,\n\t0x08, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x34, 0x05, 0x29, 0x00,\n\t0x2B, 0x00, 0x34, 0x05, 0x13, 0x00, 0x4D, 0x01, 0x08, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0x00, 0x00, 0x00, 0x00, 0x8F, 0x28, 0x00, 0x80, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x4D, 0x61, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,\n\t0x26, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x2E, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x99, 0x02, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48,\n\t0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x4C, 0x48, 0x48, 0x0E, 0x4C,\n\t0x50, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x0E, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x17, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x11, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08,\n\t0x1A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x09, 0x00, 0x06, 0x00,\n\t0x2E, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x36, 0x00, 0x00, 0x00, 0x08, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00,\n\t0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x27, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x48, 0x14, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x06, 0x06, 0x0B, 0x08, 0x0A, 0x00, 0x09, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x02, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x0A, 0x00,\n\t0x09, 0x00, 0x09, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x34, 0x05, 0x29, 0x00, 0x2B, 0x00, 0x34, 0x05, 0x13, 0x00, 0x4D, 0x01, 0x08, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8F, 0x28, 0x00, 0x80, 0x26, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x4D, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x3A, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x2C, 0x00, 0x00, 0x00, 0x09, 0x00, 0x06, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x99, 0x02, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x50, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x28, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x18, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x12, 0x00, 0x00, 0x00,\n\t0xF1, 0xF1, 0x03, 0x08, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x0A, 0x00, 0x06, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x08, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x02, 0x05, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x00,\n\t0x0B, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,\n\t0x1C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48,\n\t0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xFF, 0x3B, 0x00, 0x00,\n\t0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x0B, 0x08, 0x0A, 0x00, 0x09, 0x00, 0x08, 0x00, 0x0A, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00,\n\t0x07, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x09, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x0A, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x34, 0x05, 0x29, 0x00, 0x2B, 0x00, 0x34, 0x05, 0x13, 0x00, 0x4D, 0x01,\n\t0x08, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8F, 0x28, 0x00, 0x80,\n\t0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02,\n\t0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00,\n\t0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x4D, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x38, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x99, 0x02, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x50, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00,\n\t0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,\n\t0x18, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,\n\t0x11, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x80, 0x09, 0x00, 0x06, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,\n\t0x38, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x08, 0x14, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x00,\n\t0xFA, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x36, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0xF1, 0xF1, 0x03, 0x48, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,\n\t0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x0B, 0x08, 0x0A, 0x00, 0x09, 0x00,\n\t0x08, 0x00, 0x0A, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x02, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x09, 0x00, 0x08, 0x00, 0x08, 0x00,\n\t0x0A, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x34, 0x05, 0x29, 0x00, 0x2B, 0x00, 0x34, 0x05,\n\t0x13, 0x00, 0x4D, 0x01, 0x08, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x0B, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00,\n\t0x8F, 0x28, 0x00, 0x80, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,\n\t0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x4D, 0x61, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,\n\t0x38, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x2E, 0x00, 0x00, 0x00, 0x09, 0x00, 0x06, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x99, 0x02, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07,\n\t0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x25, 0x00, 0x1F, 0x00,\n\t0x28, 0x00, 0x23, 0x00, 0x28, 0x00, 0x23, 0x00, 0x25, 0x00, 0x20, 0x00, 0x0A, 0x00, 0x09, 0x00,\n\t0x08, 0x00, 0x0A, 0x00, 0x25, 0x00, 0x1F, 0x00, 0x28, 0x00, 0x23, 0x00, 0x28, 0x00, 0x23, 0x00,\n\t0x25, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x03, 0x03, 0x06, 0x04, 0x09, 0x07, 0x0B, 0x00,\n\t0x14, 0x1E, 0x8A, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0xAD, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0xFC, 0x0E, 0x00, 0x00,\n\t0x3D, 0x00, 0x99, 0x00, 0x38, 0x00, 0x99, 0x00, 0x41, 0x00, 0x99, 0x00, 0x90, 0x00, 0x99, 0x00,\n\t0x05, 0x00, 0x99, 0x00, 0x90, 0x00, 0x99, 0x00, 0x05, 0x00, 0x99, 0x00, 0x49, 0x00, 0x34, 0x00,\n\t0x80, 0x00, 0x99, 0x00, 0x04, 0x00, 0x99, 0x00, 0x1B, 0x00, 0x08, 0x00, 0x99, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x99, 0x00, 0x1E, 0x00, 0x99, 0x00, 0x1E, 0x00, 0x99, 0x00, 0x18, 0x00, 0x99, 0x00,\n\t0x95, 0x00, 0x99, 0x00, 0x23, 0x00, 0x99, 0x00, 0x99, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,\n\t0x99, 0x00, 0x99, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x44, 0x00, 0x01, 0x08, 0x24, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x48, 0x48, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x2D, 0x08, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x31, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5F, 0x4E,\n\t0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38,\n\t0x2E, 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x6A, 0x18, 0x00, 0x77, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D,\n\t0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80,\n\t0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,\n\t0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n\t0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10,\n\t0x02, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0C, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,\n\t0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n\t0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00,\n\t0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00,\n\t0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x0B, 0x08,\n\t0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00,\n\t0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00,\n\t0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80,\n\t0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00,\n\t0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3,\n\t0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\n\t0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00,\n\t0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x90, 0x61, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,\n\t0x2C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x34, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00,\n\t0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00,\n\t0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11,\n\t0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48,\n\t0x48, 0x48, 0x0C, 0x88, 0x48, 0x48, 0x0C, 0x88, 0x48, 0x48, 0x0C, 0x48, 0x48, 0x48, 0x0C, 0x48,\n\t0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x4C, 0x48, 0x48, 0x0E, 0x4C,\n\t0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,\n\t0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,\n\t0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,\n\t0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,\n\t0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,\n\t0x1C, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08,\n\t0x1D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0C, 0x00, 0x06, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00,\n\t0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00,\n\t0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,\n\t0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0,\n\t0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00,\n\t0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00,\n\t0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1,\n\t0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,\n\t0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,\n\t0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00,\n\t0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,\n\t0x42, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08,\n\t0x34, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07,\n\t0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00,\n\t0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55,\n\t0x14, 0x14, 0x16, 0x48, 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,\n\t0x2B, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,\n\t0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,\n\t0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,\n\t0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x16, 0x00, 0x00, 0x00,\n\t0xF1, 0xF1, 0x03, 0x08, 0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,\n\t0x0E, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00,\n\t0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,\n\t0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00,\n\t0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,\n\t0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48,\n\t0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00,\n\t0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00,\n\t0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00,\n\t0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01,\n\t0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00,\n\t0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80,\n\t0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02,\n\t0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00,\n\t0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\n\t0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00,\n\t0x1F, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,\n\t0x14, 0x14, 0x16, 0x08, 0x3E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00,\n\t0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F,\n\t0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01,\n\t0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F,\n\t0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00,\n\t0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,\n\t0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,\n\t0x1D, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,\n\t0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10,\n\t0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x80, 0x0C, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,\n\t0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\n\t0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,\n\t0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00,\n\t0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,\n\t0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,\n\t0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99,\n\t0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00,\n\t0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,\n\t0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00,\n\t0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02,\n\t0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06,\n\t0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00,\n\t0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00,\n\t0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,\n\t0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,\n\t0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\n\t0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC,\n\t0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,\n\t0x3E, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x34, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00,\n\t0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05,\n\t0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01,\n\t0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11,\n\t0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07,\n\t0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00,\n\t0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\n\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x26, 0x00, 0x1E, 0x00,\n\t0x29, 0x00, 0x24, 0x00, 0x29, 0x00, 0x24, 0x00, 0x26, 0x00, 0x20, 0x00, 0x0C, 0x00, 0x0B, 0x00,\n\t0x0A, 0x00, 0x0C, 0x00, 0x26, 0x00, 0x1E, 0x00, 0x29, 0x00, 0x24, 0x00, 0x29, 0x00, 0x24, 0x00,\n\t0x26, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,\n\t0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,\n\t0x0C, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80,\n\t0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,\n\t0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,\n\t0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,\n\t0x0A, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x03, 0x03, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00,\n\t0x19, 0x24, 0x8C, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00,\n\t0x1A, 0x00, 0x80, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x03, 0x12, 0x00, 0x00,\n\t0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00,\n\t0x05, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x00, 0x80, 0x00, 0x49, 0x00, 0x34, 0x00,\n\t0x80, 0x00, 0x80, 0x00, 0x04, 0x00, 0x80, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00,\n\t0x04, 0x00, 0x80, 0x00, 0x19, 0x00, 0x80, 0x00, 0x19, 0x00, 0x80, 0x00, 0x18, 0x00, 0x80, 0x00,\n\t0x95, 0x00, 0x80, 0x00, 0x1D, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,\n\t0x80, 0x00, 0x80, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x54, 0x00, 0x01, 0x08, 0x2D, 0x00, 0x02, 0x08,\n\t0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x48, 0x48, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,\n\t0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x04, 0x00, 0x00\n};\n\n#endif"
  },
  {
    "path": "modules/minerva/mtc_table.h",
    "content": "/*\n * Minerva Training Cell\n * DRAM Training for Tegra X1 SoC. Supports DDR2/3 and LPDDR3/4.\n *\n * Copyright (c) 2018 CTCaer  <ctcaer@gmail.com>\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _MTC_TABLE_H_\n#define _MTC_TABLE_H_\n\n#include \"types.h\"\n\ntypedef struct \n{\n\ts32 pll_osc_in;\n\ts32 pll_out;\n\tu32 pll_feedback_div;\n\tu32 pll_input_div;\n\tu32 pll_post_div;\n} pllm_clk_config_t;\n\ntypedef struct\n{\n\tu32 emc_rc_idx;\n\tu32 emc_rfc_idx;\n\tu32 emc_rfcpb_idx;\n\tu32 emc_refctrl2_idx;\n\tu32 emc_rfc_slr_idx;\n\tu32 emc_ras_idx;\n\tu32 emc_rp_idx;\n\tu32 emc_r2w_idx;\n\tu32 emc_w2r_idx;\n\tu32 emc_r2p_idx;\n\tu32 emc_w2p_idx;\n\tu32 emc_r2r_idx;\n\tu32 emc_tppd_idx;\n\tu32 emc_ccdmw_idx;\n\tu32 emc_rd_rcd_idx;\n\tu32 emc_wr_rcd_idx;\n\tu32 emc_rrd_idx;\n\tu32 emc_rext_idx;\n\tu32 emc_wext_idx;\n\tu32 emc_wdv_chk_idx;\n\tu32 emc_wdv_idx;\n\tu32 emc_wsv_idx;\n\tu32 emc_wev_idx;\n\tu32 emc_wdv_mask_idx;\n\tu32 emc_ws_duration_idx;\n\tu32 emc_we_duration_idx;\n\tu32 emc_quse_idx;\n\tu32 emc_quse_width_idx;\n\tu32 emc_ibdly_idx;\n\tu32 emc_obdly_idx;\n\tu32 emc_einput_idx;\n\tu32 emc_mrw6_idx;\n\tu32 emc_einput_duration_idx;\n\tu32 emc_puterm_extra_idx;\n\tu32 emc_puterm_width_idx;\n\tu32 emc_qrst_idx;\n\tu32 emc_qsafe_idx;\n\tu32 emc_rdv_idx;\n\tu32 emc_rdv_mask_idx;\n\tu32 emc_rdv_early_idx;\n\tu32 emc_rdv_early_mask_idx;\n\tu32 emc_refresh_idx;\n\tu32 emc_burst_refresh_num_idx;\n\tu32 emc_pre_refresh_req_cnt_idx;\n\tu32 emc_pdex2wr_idx;\n\tu32 emc_pdex2rd_idx;\n\tu32 emc_pchg2pden_idx;\n\tu32 emc_act2pden_idx;\n\tu32 emc_ar2pden_idx;\n\tu32 emc_rw2pden_idx;\n\tu32 emc_cke2pden_idx;\n\tu32 emc_pdex2cke_idx;\n\tu32 emc_pdex2mrr_idx;\n\tu32 emc_txsr_idx;\n\tu32 emc_txsrdll_idx;\n\tu32 emc_tcke_idx;\n\tu32 emc_tckesr_idx;\n\tu32 emc_tpd_idx;\n\tu32 emc_tfaw_idx;\n\tu32 emc_trpab_idx;\n\tu32 emc_tclkstable_idx;\n\tu32 emc_tclkstop_idx;\n\tu32 emc_mrw7_idx;\n\tu32 emc_trefbw_idx;\n\tu32 emc_odt_write_idx;\n\tu32 emc_fbio_cfg5_idx;\n\tu32 emc_fbio_cfg7_idx;\n\tu32 emc_cfg_dig_dll_idx;\n\tu32 emc_cfg_dig_dll_period_idx;\n\tu32 emc_pmacro_ib_rxrt_idx;\n\tu32 emc_cfg_pipe_1_idx;\n\tu32 emc_cfg_pipe_2_idx;\n\tu32 emc_pmacro_quse_ddll_rank0_4_idx;\n\tu32 emc_pmacro_quse_ddll_rank0_5_idx;\n\tu32 emc_pmacro_quse_ddll_rank1_4_idx;\n\tu32 emc_pmacro_quse_ddll_rank1_5_idx;\n\tu32 emc_mrw8_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_4_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_5_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_0_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_1_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_2_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_3_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_4_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank0_5_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_0_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_1_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_2_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_3_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_4_idx;\n\tu32 emc_pmacro_ob_ddll_long_dqs_rank1_5_idx;\n\tu32 emc_pmacro_ddll_long_cmd_0_idx;\n\tu32 emc_pmacro_ddll_long_cmd_1_idx;\n\tu32 emc_pmacro_ddll_long_cmd_2_idx;\n\tu32 emc_pmacro_ddll_long_cmd_3_idx;\n\tu32 emc_pmacro_ddll_long_cmd_4_idx;\n\tu32 emc_pmacro_ddll_short_cmd_0_idx;\n\tu32 emc_pmacro_ddll_short_cmd_1_idx;\n\tu32 emc_pmacro_ddll_short_cmd_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte0_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte1_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte2_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte3_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte4_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte5_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte6_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte7_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd0_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd1_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd2_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd3_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte0_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte1_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte2_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte3_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte4_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte5_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte6_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte7_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd0_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd0_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd0_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd0_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd1_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd1_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd1_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd1_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd2_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd2_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd2_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd2_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd3_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd3_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd3_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_cmd3_3_idx;\n\tu32 emc_txdsrvttgen_idx;\n\tu32 emc_fdpd_ctrl_dq_idx;\n\tu32 emc_fdpd_ctrl_cmd_idx;\n\tu32 emc_fbio_spare_idx;\n\tu32 emc_zcal_interval_idx;\n\tu32 emc_zcal_wait_cnt_idx;\n\tu32 emc_mrs_wait_cnt_idx;\n\tu32 emc_mrs_wait_cnt2_idx;\n\tu32 emc_auto_cal_channel_idx;\n\tu32 emc_dll_cfg_0_idx;\n\tu32 emc_dll_cfg_1_idx;\n\tu32 emc_pmacro_autocal_cfg_common_idx;\n\tu32 emc_pmacro_zctrl_idx;\n\tu32 emc_cfg_idx;\n\tu32 emc_cfg_pipe_idx;\n\tu32 emc_dyn_self_ref_control_idx;\n\tu32 emc_qpop_idx;\n\tu32 emc_dqs_brlshft_0_idx;\n\tu32 emc_dqs_brlshft_1_idx;\n\tu32 emc_cmd_brlshft_2_idx;\n\tu32 emc_cmd_brlshft_3_idx;\n\tu32 emc_pmacro_pad_cfg_ctrl_idx;\n\tu32 emc_pmacro_data_pad_rx_ctrl_idx;\n\tu32 emc_pmacro_cmd_pad_rx_ctrl_idx;\n\tu32 emc_pmacro_data_rx_term_mode_idx;\n\tu32 emc_pmacro_cmd_rx_term_mode_idx;\n\tu32 emc_pmacro_cmd_pad_tx_ctrl_idx;\n\tu32 emc_pmacro_data_pad_tx_ctrl_idx;\n\tu32 emc_pmacro_common_pad_tx_ctrl_idx;\n\tu32 emc_pmacro_vttgen_ctrl_0_idx;\n\tu32 emc_pmacro_vttgen_ctrl_1_idx;\n\tu32 emc_pmacro_vttgen_ctrl_2_idx;\n\tu32 emc_pmacro_brick_ctrl_rfu1_idx;\n\tu32 emc_pmacro_cmd_brick_ctrl_fdpd_idx;\n\tu32 emc_pmacro_brick_ctrl_rfu2_idx;\n\tu32 emc_pmacro_data_brick_ctrl_fdpd_idx;\n\tu32 emc_pmacro_bg_bias_ctrl_0_idx;\n\tu32 emc_cfg_3_idx;\n\tu32 emc_pmacro_tx_pwrd_0_idx;\n\tu32 emc_pmacro_tx_pwrd_1_idx;\n\tu32 emc_pmacro_tx_pwrd_2_idx;\n\tu32 emc_pmacro_tx_pwrd_3_idx;\n\tu32 emc_pmacro_tx_pwrd_4_idx;\n\tu32 emc_pmacro_tx_pwrd_5_idx;\n\tu32 emc_config_sample_delay_idx;\n\tu32 emc_pmacro_tx_sel_clk_src_0_idx;\n\tu32 emc_pmacro_tx_sel_clk_src_1_idx;\n\tu32 emc_pmacro_tx_sel_clk_src_2_idx;\n\tu32 emc_pmacro_tx_sel_clk_src_3_idx;\n\tu32 emc_pmacro_tx_sel_clk_src_4_idx;\n\tu32 emc_pmacro_tx_sel_clk_src_5_idx;\n\tu32 emc_pmacro_ddll_bypass_idx;\n\tu32 emc_pmacro_ddll_pwrd_0_idx;\n\tu32 emc_pmacro_ddll_pwrd_1_idx;\n\tu32 emc_pmacro_ddll_pwrd_2_idx;\n\tu32 emc_pmacro_cmd_ctrl_0_idx;\n\tu32 emc_pmacro_cmd_ctrl_1_idx;\n\tu32 emc_pmacro_cmd_ctrl_2_idx;\n\tu32 emc_tr_timing_0_idx;\n\tu32 emc_tr_dvfs_idx;\n\tu32 emc_tr_ctrl_1_idx;\n\tu32 emc_tr_rdv_idx;\n\tu32 emc_tr_qpop_idx;\n\tu32 emc_tr_rdv_mask_idx;\n\tu32 emc_mrw14_idx;\n\tu32 emc_tr_qsafe_idx;\n\tu32 emc_tr_qrst_idx;\n\tu32 emc_training_ctrl_idx;\n\tu32 emc_training_settle_idx;\n\tu32 emc_training_vref_settle_idx;\n\tu32 emc_training_ca_fine_ctrl_idx;\n\tu32 emc_training_ca_ctrl_misc_idx;\n\tu32 emc_training_ca_ctrl_misc1_idx;\n\tu32 emc_training_ca_vref_ctrl_idx;\n\tu32 emc_training_quse_cors_ctrl_idx;\n\tu32 emc_training_quse_fine_ctrl_idx;\n\tu32 emc_training_quse_ctrl_misc_idx;\n\tu32 emc_training_quse_vref_ctrl_idx;\n\tu32 emc_training_read_fine_ctrl_idx;\n\tu32 emc_training_read_ctrl_misc_idx;\n\tu32 emc_training_read_vref_ctrl_idx;\n\tu32 emc_training_write_fine_ctrl_idx;\n\tu32 emc_training_write_ctrl_misc_idx;\n\tu32 emc_training_write_vref_ctrl_idx;\n\tu32 emc_training_mpc_idx;\n\tu32 emc_mrw15_idx;\n} burst_regs_t;\n\n\ntypedef struct \n{\n\tu32 burst_regs[221];\n\tu32 burst_reg_per_ch[8];\n\tu32 shadow_regs_ca_train[221];\n\tu32 shadow_regs_quse_train[221];\n\tu32 shadow_regs_rdwr_train[221];\n} burst_regs_table_t;\n\ntypedef struct \n{\n\tu32 ptfv_dqsosc_movavg_c0d0u0_idx;\n\tu32 ptfv_dqsosc_movavg_c0d0u1_idx;\n\tu32 ptfv_dqsosc_movavg_c0d1u0_idx;\n\tu32 ptfv_dqsosc_movavg_c0d1u1_idx;\n\tu32 ptfv_dqsosc_movavg_c1d0u0_idx;\n\tu32 ptfv_dqsosc_movavg_c1d0u1_idx;\n\tu32 ptfv_dqsosc_movavg_c1d1u0_idx;\n\tu32 ptfv_dqsosc_movavg_c1d1u1_idx;\n\tu32 ptfv_write_samples_idx;\n\tu32 ptfv_dvfs_samples_idx;\n\tu32 ptfv_movavg_weight_idx;\n\tu32 ptfv_config_ctrl_idx;\n} ptfv_list_table_t;\n\ntypedef struct\n{\n\tu32 emc0_mrw10_idx;\n\tu32 emc1_mrw10_idx;\n\tu32 emc0_mrw11_idx;\n\tu32 emc1_mrw11_idx;\n\tu32 emc0_mrw12_idx;\n\tu32 emc1_mrw12_idx;\n\tu32 emc0_mrw13_idx;\n\tu32 emc1_mrw13_idx;\n} burst_reg_per_ch_t;\n\ntypedef struct\n{\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank0_0_idx;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank0_1_idx;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank0_2_idx;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank0_3_idx;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank1_0_idx;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank1_1_idx;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank1_2_idx;\n\tu32 emc_pmacro_ib_ddll_long_dqs_rank1_3_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte0_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte0_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte0_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte1_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte1_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte1_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte2_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte2_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte2_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte3_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte3_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte3_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte4_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte4_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte4_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte5_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte5_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte5_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte6_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte6_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte6_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte7_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte7_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank0_byte7_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte0_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte0_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte0_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte1_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte1_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte1_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte2_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte2_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte2_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte3_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte3_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte3_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte4_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte4_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte4_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte5_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte5_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte5_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte6_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte6_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte6_2_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte7_0_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte7_1_idx;\n\tu32 emc_pmacro_ib_ddll_short_dq_rank1_byte7_2_idx;\n\tu32 emc_pmacro_ib_vref_dqs_0_idx;\n\tu32 emc_pmacro_ib_vref_dqs_1_idx;\n\tu32 emc_pmacro_ib_vref_dq_0_idx;\n\tu32 emc_pmacro_ib_vref_dq_1_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_0_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_1_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_2_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_3_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_4_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank0_5_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_0_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_1_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_2_idx;\n\tu32 emc_pmacro_ob_ddll_long_dq_rank1_3_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte0_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte0_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte0_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte1_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte1_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte1_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte2_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte2_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte2_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte3_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte3_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte3_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte4_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte4_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte4_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte5_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte5_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte5_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte6_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte6_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte6_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte7_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte7_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_byte7_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd0_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd0_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd0_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd1_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd1_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd1_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd2_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd2_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd2_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd3_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd3_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank0_cmd3_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte0_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte0_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte0_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte1_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte1_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte1_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte2_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte2_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte2_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte3_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte3_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte3_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte4_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte4_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte4_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte5_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte5_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte5_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte6_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte6_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte6_2_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte7_0_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte7_1_idx;\n\tu32 emc_pmacro_ob_ddll_short_dq_rank1_byte7_2_idx;\n\tu32 emc_pmacro_quse_ddll_rank0_0_idx;\n\tu32 emc_pmacro_quse_ddll_rank0_1_idx;\n\tu32 emc_pmacro_quse_ddll_rank0_2_idx;\n\tu32 emc_pmacro_quse_ddll_rank0_3_idx;\n\tu32 emc_pmacro_quse_ddll_rank1_0_idx;\n\tu32 emc_pmacro_quse_ddll_rank1_1_idx;\n\tu32 emc_pmacro_quse_ddll_rank1_2_idx;\n\tu32 emc_pmacro_quse_ddll_rank1_3_idx;\n} trim_regs_t;\n\ntypedef struct\n{\n\tu32 emc_cmd_brlshft_0_idx;\n\tu32 emc_cmd_brlshft_1_idx;\n\tu32 emc0_data_brlshft_0_idx;\n\tu32 emc1_data_brlshft_0_idx;\n\tu32 emc0_data_brlshft_1_idx;\n\tu32 emc1_data_brlshft_1_idx;\n\tu32 emc_quse_brlshft_0_idx;\n\tu32 emc_quse_brlshft_1_idx;\n\tu32 emc_quse_brlshft_2_idx;\n\tu32 emc_quse_brlshft_3_idx;\n} trim_perch_regs_t;\n\ntypedef struct\n{\n\tu32 t_rp;\n\tu32 t_fc_lpddr4;\n\tu32 t_rfc;\n\tu32 t_pdex;\n\tu32 rl;\n} dram_timings_t;\n\ntypedef struct\n{\n\tu32 emc0_training_opt_dqs_ib_vref_rank0_idx;\n\tu32 emc1_training_opt_dqs_ib_vref_rank0_idx;\n\tu32 emc0_training_opt_dqs_ib_vref_rank1_idx;\n\tu32 emc1_training_opt_dqs_ib_vref_rank1_idx;\n} vref_perch_regs_t;\n\ntypedef struct\n{\n\tu32 trim_regs[138];\n\tu32 trim_perch_regs[10];\n\tu32 vref_perch_regs[4];\n} trim_regs_table_t;\n\ntypedef struct\n{\n\tu32 rev;\n\tchar dvfs_ver[60];\n\tu32 rate_khz;\n\tu32 min_volt;\n\tu32 gpu_min_volt;\n\tchar clock_src[32];\n\tu32 clk_src_emc;\n\tu32 needs_training;\n\tu32 training_pattern;\n\tu32 trained;\n\tu32 periodic_training;\n\tu32 trained_dram_clktree_c0d0u0;\n\tu32 trained_dram_clktree_c0d0u1;\n\tu32 trained_dram_clktree_c0d1u0;\n\tu32 trained_dram_clktree_c0d1u1;\n\tu32 trained_dram_clktree_c1d0u0;\n\tu32 trained_dram_clktree_c1d0u1;\n\tu32 trained_dram_clktree_c1d1u0;\n\tu32 trained_dram_clktree_c1d1u1;\n\tu32 current_dram_clktree_c0d0u0;\n\tu32 current_dram_clktree_c0d0u1;\n\tu32 current_dram_clktree_c0d1u0;\n\tu32 current_dram_clktree_c0d1u1;\n\tu32 current_dram_clktree_c1d0u0;\n\tu32 current_dram_clktree_c1d0u1;\n\tu32 current_dram_clktree_c1d1u0;\n\tu32 current_dram_clktree_c1d1u1;\n\tu32 run_clocks;\n\tu32 tree_margin;\n\tu32 num_burst;\n\tu32 num_burst_per_ch;\n\tu32 num_trim;\n\tu32 num_trim_per_ch;\n\tu32 num_mc_regs;\n\tu32 num_up_down;\n\tu32 vref_num;\n\tu32 training_mod_num;\n\tu32 dram_timing_num;\n\n\tptfv_list_table_t ptfv_list;\n\n\tburst_regs_t burst_regs;\n\tburst_reg_per_ch_t burst_reg_per_ch;\n\tburst_regs_t shadow_regs_ca_train;\n\tburst_regs_t shadow_regs_quse_train;\n\tburst_regs_t shadow_regs_rdwr_train;\n\ttrim_regs_t trim_regs;\n\ttrim_perch_regs_t trim_perch_regs;\n\tvref_perch_regs_t vref_perch_regs;\n\tdram_timings_t dram_timings;\n\n\tu32 training_mod_regs[20];\n\tu32 save_restore_mod_regs[12];\n\tu32 burst_mc_regs[33];\n\tu32 la_scale_regs[24];\n\n\tu32 min_mrs_wait;\n\tu32 emc_mrw;\n\tu32 emc_mrw2;\n\tu32 emc_mrw3;\n\tu32 emc_mrw4;\n\tu32 emc_mrw9;\n\tu32 emc_mrs;\n\tu32 emc_emrs;\n\tu32 emc_emrs2;\n\tu32 emc_auto_cal_config;\n\tu32 emc_auto_cal_config2;\n\tu32 emc_auto_cal_config3;\n\tu32 emc_auto_cal_config4;\n\tu32 emc_auto_cal_config5;\n\tu32 emc_auto_cal_config6;\n\tu32 emc_auto_cal_config7;\n\tu32 emc_auto_cal_config8;\n\tu32 emc_cfg_2;\n\tu32 emc_sel_dpd_ctrl;\n\tu32 emc_fdpd_ctrl_cmd_no_ramp;\n\tu32 dll_clk_src;\n\tu32 clk_out_enb_x_0_clk_enb_emc_dll;\n\tu32 latency;\n} emc_table_t;\n\n#endif"
  },
  {
    "path": "modules/minerva/sys_sdrammtc.c",
    "content": "/*\n * Minerva Training Cell\n * DRAM Training for Tegra X1 SoC. Supports DDR2/3 and LPDDR3/4.\n *\n * Copyright (c) 2018 CTCaer  <ctcaer@gmail.com>\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms and conditions of the GNU General Public License,\n * version 2, as published by the Free Software Foundation.\n *\n * This program is distributed in the hope it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>\n#include <stdlib.h>\n#include \"mtc.h\"\n#include \"mtc_mc_emc_regs.h\"\n#include \"mtc_switch_tables.h\"\n#include \"types.h\"\n#include \"common.h\"\n\n#define EPRINTF(...)\n#define EPRINTFARGS(...)\n\nbool emc_2X_clk_src_is_pllmb;\nbool fsp_for_src_freq;\nbool train_ram_patterns;\n\n/*\n * REF:  PLL Input reference (OSC_FREQ).\n * DIVN: PLL feedback divider.\n * DIVM: PLL input divider.\n * DIVP: PLL post divider.\n * PLL_OUT = (REF / DIVM) * DIVN / DIVP\n * \n * DIVP    | DIVP\n * Encoded | Real\n * ----------------------\n * 0       | 1 (DIVP off)\n * 1       | 2\n * 2       | 3\n * 3       | 4\n * 4       | 5\n * 5       | 6\n * 6       | 8\n * 7       | 10\n * 8       | 12\n * 9       | 16\n * 10      | 12\n * 11      | 16\n * 12      | 20\n * 13      | 24\n * 14      | 32\n */\nstatic pllm_clk_config_t pllm_clk_config_table[] =\n{\n\t// pll_osc_in, pll_out, pll_feedback_div, pll_input_div, pll_post_div.\n\t{38400, 297600,  93,  4, 2}, // ((38400 / 4) * 93)  / 3\n\t{38400, 400000,  125, 4, 2}, // ((38400 / 4) * 125) / 3\n\t{38400, 408000,  85,  4, 1}, // ((38400 / 4) * 85)  / 2\n\t{38400, 532800,  111, 4, 1}, // ((38400 / 4) * 111) / 2\n\t{38400, 665600,  104, 3, 1}, // ((38400 / 3) * 104) / 2\n\t{38400, 800000,  125, 3, 1}, // ((38400 / 3) * 125) / 2\n\t{38400, 931200,  97,  4, 0}, // (38400 / 4) * 97\n\t{38400, 1065600, 111, 4, 0}, // (38400 / 4) * 111\n\t{38400, 1200000, 125, 4, 0}, // (38400 / 4) * 125\n\t{38400, 1331200, 104, 3, 0}, // (38400 / 3) * 104\n\t{38400, 1459200, 76,  2, 0}, // (38400 / 2) * 76\n\t{38400, 1600000, 125, 3, 0}, // (38400 / 3) * 125\n\t{38400, 1862400, 97,  2, 0}, // (38400 / 2) * 97\n\t{38400, 2131200, 111, 2, 0}, // (38400 / 2) * 111\n \t{0,     0,       0,   0, 0}\n};\n\nstatic const u32 burst_regs_emc_addr_table[221] = {\n\tEMC_RC,\n\tEMC_RFC,\n\tEMC_RFCPB,\n\tEMC_REFCTRL2,\n\tEMC_RFC_SLR,\n\tEMC_RAS,\n\tEMC_RP,\n\tEMC_R2W,\n\tEMC_W2R,\n\tEMC_R2P,\n\tEMC_W2P,\n\tEMC_R2R,\n\tEMC_TPPD,\n\tEMC_CCDMW,\n\tEMC_RD_RCD,\n\tEMC_WR_RCD,\n\tEMC_RRD,\n\tEMC_REXT,\n\tEMC_WEXT,\n\tEMC_WDV_CHK,\n\tEMC_WDV,\n\tEMC_WSV,\n\tEMC_WEV,\n\tEMC_WDV_MASK,\n\tEMC_WS_DURATION,\n\tEMC_WE_DURATION,\n\tEMC_QUSE,\n\tEMC_QUSE_WIDTH,\n\tEMC_IBDLY,\n\tEMC_OBDLY,\n\tEMC_EINPUT,\n\tEMC_MRW6,\n\tEMC_EINPUT_DURATION,\n\tEMC_PUTERM_EXTRA,\n\tEMC_PUTERM_WIDTH,\n\tEMC_QRST,\n\tEMC_QSAFE,\n\tEMC_RDV,\n\tEMC_RDV_MASK,\n\tEMC_RDV_EARLY,\n\tEMC_RDV_EARLY_MASK,\n\tEMC_REFRESH,\n\tEMC_BURST_REFRESH_NUM,\n\tEMC_PRE_REFRESH_REQ_CNT,\n\tEMC_PDEX2WR,\n\tEMC_PDEX2RD,\n\tEMC_PCHG2PDEN,\n\tEMC_ACT2PDEN,\n\tEMC_AR2PDEN,\n\tEMC_RW2PDEN,\n\tEMC_CKE2PDEN,\n\tEMC_PDEX2CKE,\n\tEMC_PDEX2MRR,\n\tEMC_TXSR,\n\tEMC_TXSRDLL,\n\tEMC_TCKE,\n\tEMC_TCKESR,\n\tEMC_TPD,\n\tEMC_TFAW,\n\tEMC_TRPAB,\n\tEMC_TCLKSTABLE,\n\tEMC_TCLKSTOP,\n\tEMC_MRW7,\n\tEMC_TREFBW,\n\tEMC_ODT_WRITE,\n\tEMC_FBIO_CFG5,\n\tEMC_FBIO_CFG7,\n\tEMC_CFG_DIG_DLL,\n\tEMC_CFG_DIG_DLL_PERIOD,\n\tEMC_PMACRO_IB_RXRT,\n\tEMC_CFG_PIPE_1,\n\tEMC_CFG_PIPE_2,\n\tEMC_PMACRO_QUSE_DDLL_RANK0_4,\n\tEMC_PMACRO_QUSE_DDLL_RANK0_5,\n\tEMC_PMACRO_QUSE_DDLL_RANK1_4,\n\tEMC_PMACRO_QUSE_DDLL_RANK1_5,\n\tEMC_MRW8,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5,\n\tEMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0,\n\tEMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1,\n\tEMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2,\n\tEMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3,\n\tEMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4,\n\tEMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5,\n\tEMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0,\n\tEMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1,\n\tEMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2,\n\tEMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3,\n\tEMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4,\n\tEMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5,\n\tEMC_PMACRO_DDLL_LONG_CMD_0,\n\tEMC_PMACRO_DDLL_LONG_CMD_1,\n\tEMC_PMACRO_DDLL_LONG_CMD_2,\n\tEMC_PMACRO_DDLL_LONG_CMD_3,\n\tEMC_PMACRO_DDLL_LONG_CMD_4,\n\tEMC_PMACRO_DDLL_SHORT_CMD_0,\n\tEMC_PMACRO_DDLL_SHORT_CMD_1,\n\tEMC_PMACRO_DDLL_SHORT_CMD_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_3,\n\tEMC_TXDSRVTTGEN,\n\tEMC_FDPD_CTRL_DQ,\n\tEMC_FDPD_CTRL_CMD,\n\tEMC_FBIO_SPARE,\n\tEMC_ZCAL_INTERVAL,\n\tEMC_ZCAL_WAIT_CNT,\n\tEMC_MRS_WAIT_CNT,\n\tEMC_MRS_WAIT_CNT2,\n\tEMC_AUTO_CAL_CHANNEL,\n\tEMC_DLL_CFG_0,\n\tEMC_DLL_CFG_1,\n\tEMC_PMACRO_AUTOCAL_CFG_COMMON,\n\tEMC_PMACRO_ZCTRL,\n\tEMC_CFG,\n\tEMC_CFG_PIPE,\n\tEMC_DYN_SELF_REF_CONTROL,\n\tEMC_QPOP,\n\tEMC_DQS_BRLSHFT_0,\n\tEMC_DQS_BRLSHFT_1,\n\tEMC_CMD_BRLSHFT_2,\n\tEMC_CMD_BRLSHFT_3,\n\tEMC_PMACRO_PAD_CFG_CTRL,\n\tEMC_PMACRO_DATA_PAD_RX_CTRL,\n\tEMC_PMACRO_CMD_PAD_RX_CTRL,\n\tEMC_PMACRO_DATA_RX_TERM_MODE,\n\tEMC_PMACRO_CMD_RX_TERM_MODE,\n\tEMC_PMACRO_CMD_PAD_TX_CTRL,\n\tEMC_PMACRO_DATA_PAD_TX_CTRL,\n\tEMC_PMACRO_COMMON_PAD_TX_CTRL,\n\tEMC_PMACRO_VTTGEN_CTRL_0,\n\tEMC_PMACRO_VTTGEN_CTRL_1,\n\tEMC_PMACRO_VTTGEN_CTRL_2,\n\tEMC_PMACRO_BRICK_CTRL_RFU1,\n\tEMC_PMACRO_CMD_BRICK_CTRL_FDPD,\n\tEMC_PMACRO_BRICK_CTRL_RFU2,\n\tEMC_PMACRO_DATA_BRICK_CTRL_FDPD,\n\tEMC_PMACRO_BG_BIAS_CTRL_0,\n\tEMC_CFG_3,\n\tEMC_PMACRO_TX_PWRD_0,\n\tEMC_PMACRO_TX_PWRD_1,\n\tEMC_PMACRO_TX_PWRD_2,\n\tEMC_PMACRO_TX_PWRD_3,\n\tEMC_PMACRO_TX_PWRD_4,\n\tEMC_PMACRO_TX_PWRD_5,\n\tEMC_CONFIG_SAMPLE_DELAY,\n\tEMC_PMACRO_TX_SEL_CLK_SRC_0,\n\tEMC_PMACRO_TX_SEL_CLK_SRC_1,\n\tEMC_PMACRO_TX_SEL_CLK_SRC_2,\n\tEMC_PMACRO_TX_SEL_CLK_SRC_3,\n\tEMC_PMACRO_TX_SEL_CLK_SRC_4,\n\tEMC_PMACRO_TX_SEL_CLK_SRC_5,\n\tEMC_PMACRO_DDLL_BYPASS,\n\tEMC_PMACRO_DDLL_PWRD_0,\n\tEMC_PMACRO_DDLL_PWRD_1,\n\tEMC_PMACRO_DDLL_PWRD_2,\n\tEMC_PMACRO_CMD_CTRL_0,\n\tEMC_PMACRO_CMD_CTRL_1,\n\tEMC_PMACRO_CMD_CTRL_2,\n\tEMC_TR_TIMING_0,\n\tEMC_TR_DVFS,\n\tEMC_TR_CTRL_1,\n\tEMC_TR_RDV,\n\tEMC_TR_QPOP,\n\tEMC_TR_RDV_MASK,\n\tEMC_MRW14,\n\tEMC_TR_QSAFE,\n\tEMC_TR_QRST,\n\tEMC_TRAINING_CTRL,\n\tEMC_TRAINING_SETTLE,\n\tEMC_TRAINING_VREF_SETTLE,\n\tEMC_TRAINING_CA_FINE_CTRL,\n\tEMC_TRAINING_CA_CTRL_MISC,\n\tEMC_TRAINING_CA_CTRL_MISC1,\n\tEMC_TRAINING_CA_VREF_CTRL,\n\tEMC_TRAINING_QUSE_CORS_CTRL,\n\tEMC_TRAINING_QUSE_FINE_CTRL,\n\tEMC_TRAINING_QUSE_CTRL_MISC,\n\tEMC_TRAINING_QUSE_VREF_CTRL,\n\tEMC_TRAINING_READ_FINE_CTRL,\n\tEMC_TRAINING_READ_CTRL_MISC,\n\tEMC_TRAINING_READ_VREF_CTRL,\n\tEMC_TRAINING_WRITE_FINE_CTRL,\n\tEMC_TRAINING_WRITE_CTRL_MISC,\n\tEMC_TRAINING_WRITE_VREF_CTRL,\n\tEMC_TRAINING_MPC,\n\tEMC_MRW15\n};\n\nstatic const u32 burst_reg_per_ch_emc01_addr_table[8] = {\n\tEMC0_MRW10,\n\tEMC1_MRW10,\n\tEMC0_MRW11,\n\tEMC1_MRW11,\n\tEMC0_MRW12,\n\tEMC1_MRW12,\n\tEMC0_MRW13,\n\tEMC1_MRW13\n};\n\nstatic const u32 vref_perch_regs_emc01_addr_table[4] = {\n\tEMC0_TRAINING_OPT_DQS_IB_VREF_RANK0,\n\tEMC1_TRAINING_OPT_DQS_IB_VREF_RANK0,\n\tEMC0_TRAINING_OPT_DQS_IB_VREF_RANK1,\n\tEMC1_TRAINING_OPT_DQS_IB_VREF_RANK1\n};\n\nstatic const u32 training_mod_regs_emc01_addr_table[20] = {\n\tEMC0_TRAINING_RW_OFFSET_IB_BYTE0,\n\tEMC1_TRAINING_RW_OFFSET_IB_BYTE0,\n\tEMC0_TRAINING_RW_OFFSET_IB_BYTE1,\n\tEMC1_TRAINING_RW_OFFSET_IB_BYTE1,\n\tEMC0_TRAINING_RW_OFFSET_IB_BYTE2,\n\tEMC1_TRAINING_RW_OFFSET_IB_BYTE2,\n\tEMC0_TRAINING_RW_OFFSET_IB_BYTE3,\n\tEMC1_TRAINING_RW_OFFSET_IB_BYTE3,\n\tEMC0_TRAINING_RW_OFFSET_IB_MISC,\n\tEMC1_TRAINING_RW_OFFSET_IB_MISC,\n\tEMC0_TRAINING_RW_OFFSET_OB_BYTE0,\n\tEMC1_TRAINING_RW_OFFSET_OB_BYTE0,\n\tEMC0_TRAINING_RW_OFFSET_OB_BYTE1,\n\tEMC1_TRAINING_RW_OFFSET_OB_BYTE1,\n\tEMC0_TRAINING_RW_OFFSET_OB_BYTE2,\n\tEMC1_TRAINING_RW_OFFSET_OB_BYTE2,\n\tEMC0_TRAINING_RW_OFFSET_OB_BYTE3,\n\tEMC1_TRAINING_RW_OFFSET_OB_BYTE3,\n\tEMC0_TRAINING_RW_OFFSET_OB_MISC,\n\tEMC1_TRAINING_RW_OFFSET_OB_MISC\n};\n\nstatic const u32 trim_regs_emc_addr_table[138] = {\n\tEMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0,\n\tEMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1,\n\tEMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2,\n\tEMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3,\n\tEMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0,\n\tEMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1,\n\tEMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2,\n\tEMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_0,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_1,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_2,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_0,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_1,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_2,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_0,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_1,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_2,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_0,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_1,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_2,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_0,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_1,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_2,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_0,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_1,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_2,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_0,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_1,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_2,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_0,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_1,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_2,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_0,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_1,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_2,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_0,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_1,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_2,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_0,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_1,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_2,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_0,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_1,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_2,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_0,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_1,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_2,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_0,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_1,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_2,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_0,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_1,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_2,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_0,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_1,\n\tEMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_2,\n\tEMC_PMACRO_IB_VREF_DQS_0,\n\tEMC_PMACRO_IB_VREF_DQS_1,\n\tEMC_PMACRO_IB_VREF_DQ_0,\n\tEMC_PMACRO_IB_VREF_DQ_1,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_2,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_0,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_1,\n\tEMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_2,\n\tEMC_PMACRO_QUSE_DDLL_RANK0_0,\n\tEMC_PMACRO_QUSE_DDLL_RANK0_1,\n\tEMC_PMACRO_QUSE_DDLL_RANK0_2,\n\tEMC_PMACRO_QUSE_DDLL_RANK0_3,\n\tEMC_PMACRO_QUSE_DDLL_RANK1_0,\n\tEMC_PMACRO_QUSE_DDLL_RANK1_1,\n\tEMC_PMACRO_QUSE_DDLL_RANK1_2,\n\tEMC_PMACRO_QUSE_DDLL_RANK1_3\n};\n\nstatic const u32 trim_perch_regs_emc01_addr_table[10] = {\n\tEMC0_CMD_BRLSHFT_0,\n\tEMC1_CMD_BRLSHFT_1,\n\tEMC0_DATA_BRLSHFT_0,\n\tEMC1_DATA_BRLSHFT_0,\n\tEMC0_DATA_BRLSHFT_1,\n\tEMC1_DATA_BRLSHFT_1,\n\tEMC0_QUSE_BRLSHFT_0,\n\tEMC1_QUSE_BRLSHFT_1,\n\tEMC0_QUSE_BRLSHFT_2,\n\tEMC1_QUSE_BRLSHFT_3\n};\n\nstatic const u32 burst_mc_regs_addr_table[33] = {\n\tMC_EMEM_ARB_CFG,\n\tMC_EMEM_ARB_OUTSTANDING_REQ,\n\tMC_EMEM_ARB_REFPB_HP_CTRL,\n\tMC_EMEM_ARB_REFPB_BANK_CTRL,\n\tMC_EMEM_ARB_TIMING_RCD,\n\tMC_EMEM_ARB_TIMING_RP,\n\tMC_EMEM_ARB_TIMING_RC,\n\tMC_EMEM_ARB_TIMING_RAS,\n\tMC_EMEM_ARB_TIMING_FAW,\n\tMC_EMEM_ARB_TIMING_RRD,\n\tMC_EMEM_ARB_TIMING_RAP2PRE,\n\tMC_EMEM_ARB_TIMING_WAP2PRE,\n\tMC_EMEM_ARB_TIMING_R2R,\n\tMC_EMEM_ARB_TIMING_W2W,\n\tMC_EMEM_ARB_TIMING_R2W,\n\tMC_EMEM_ARB_TIMING_CCDMW,\n\tMC_EMEM_ARB_TIMING_W2R,\n\tMC_EMEM_ARB_TIMING_RFCPB,\n\tMC_EMEM_ARB_DA_TURNS,\n\tMC_EMEM_ARB_DA_COVERS,\n\tMC_EMEM_ARB_MISC0,\n\tMC_EMEM_ARB_MISC1,\n\tMC_EMEM_ARB_MISC2,\n\tMC_EMEM_ARB_RING1_THROTTLE,\n\tMC_EMEM_ARB_DHYST_CTRL,\n\tMC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0,\n\tMC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1,\n\tMC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2,\n\tMC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3,\n\tMC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4,\n\tMC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5,\n\tMC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6,\n\tMC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7\n};\n\nstatic const u32 la_scale_regs_mc_addr_table[24] = {\n\tMC_MLL_MPCORER_PTSA_RATE,\n\tMC_FTOP_PTSA_RATE,\n\tMC_PTSA_GRANT_DECREMENT,\n\tMC_LATENCY_ALLOWANCE_XUSB_0,\n\tMC_LATENCY_ALLOWANCE_XUSB_1,\n\tMC_LATENCY_ALLOWANCE_TSEC_0,\n\tMC_LATENCY_ALLOWANCE_SDMMCA_0,\n\tMC_LATENCY_ALLOWANCE_SDMMCAA_0,\n\tMC_LATENCY_ALLOWANCE_SDMMC_0,\n\tMC_LATENCY_ALLOWANCE_SDMMCAB_0,\n\tMC_LATENCY_ALLOWANCE_PPCS_0,\n\tMC_LATENCY_ALLOWANCE_PPCS_1,\n\tMC_LATENCY_ALLOWANCE_MPCORE_0,\n\tMC_LATENCY_ALLOWANCE_HC_0,\n\tMC_LATENCY_ALLOWANCE_HC_1,\n\tMC_LATENCY_ALLOWANCE_AVPC_0,\n\tMC_LATENCY_ALLOWANCE_GPU_0,\n\tMC_LATENCY_ALLOWANCE_GPU2_0,\n\tMC_LATENCY_ALLOWANCE_NVENC_0,\n\tMC_LATENCY_ALLOWANCE_NVDEC_0,\n\tMC_LATENCY_ALLOWANCE_VIC_0,\n\tMC_LATENCY_ALLOWANCE_VI2_0,\n\tMC_LATENCY_ALLOWANCE_ISP2_0,\n\tMC_LATENCY_ALLOWANCE_ISP2_1\n};\n\nstatic const u32 periodic_training_addr[10] =\n{\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2,\n\tEMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3,\n\tEMC_DATA_BRLSHFT_0,\n\tEMC_DATA_BRLSHFT_1\n};\n\nstatic const u32 ram_pattern_dq_table[0x500] = {\n\t/* DQ RAM Patterns Table 0 */\n\t0x18181818, 0x61616161, 0x85858585, 0x14141414, 0x51515151,\n\t0x47474747, 0x1E1E1E1E, 0x79797979, 0xE5E5E5E5, 0x94949494,\n\t0x51515151, 0x46464646, 0x19191919, 0x67676767, 0x9C9C9C9C,\n\t0x71717171, 0xC5C5C5C5, 0x17171717, 0x5F5F5F5F, 0x7E7E7E7E,\n\t0xFBFBFBFB, 0xEDEDEDED, 0xB4B4B4B4, 0xD2D2D2D2, 0x48484848,\n\t0x21212121, 0x85858585, 0x16161616, 0x59595959, 0x66666666,\n\t0x9A9A9A9A, 0x69696969, 0xA4A4A4A4, 0x93939393, 0x4F4F4F4F,\n\t0x3F3F3F3F, 0xFCFCFCFC, 0xF3F3F3F3, 0xCDCDCDCD, 0x37373737,\n\t0xDCDCDCDC, 0x70707070, 0xC3C3C3C3, 0x0F0F0F0F, 0x3E3E3E3E,\n\t0xFAFAFAFA, 0xEBEBEBEB, 0xACACACAC, 0xB3B3B3B3, 0xCCCCCCCC,\n\t0x31313131, 0xC5C5C5C5, 0x15151515, 0x57575757, 0x5F5F5F5F,\n\t0x7F7F7F7F, 0xFDFDFDFD, 0xF4F4F4F4, 0xD0D0D0D0, 0x42424242,\n\t0x08080808, 0x23232323, 0x8F8F8F8F, 0x3F3F3F3F, 0x18181818,\n\t0x61616161, 0x85858585, 0x14141414, 0x51515151, 0x47474747,\n\t0x1E1E1E1E, 0x79797979, 0xE5E5E5E5, 0x94949494, 0x51515151,\n\t0x46464646, 0x19191919, 0x67676767, 0x9C9C9C9C, 0x71717171,\n\t0xC5C5C5C5, 0x17171717, 0x5F5F5F5F, 0x7E7E7E7E, 0xFBFBFBFB,\n\t0xEDEDEDED, 0xB4B4B4B4, 0xD2D2D2D2, 0x48484848, 0x21212121,\n\t0x85858585, 0x16161616, 0x59595959, 0x66666666, 0x9A9A9A9A,\n\t0x69696969, 0xA4A4A4A4, 0x93939393, 0x4F4F4F4F, 0x3F3F3F3F,\n\t0xFCFCFCFC, 0xF3F3F3F3, 0xCDCDCDCD, 0x37373737, 0xDCDCDCDC,\n\t0x70707070, 0xC3C3C3C3, 0x0F0F0F0F, 0x3E3E3E3E, 0xFAFAFAFA,\n\t0xEBEBEBEB, 0xACACACAC, 0xB3B3B3B3, 0xCCCCCCCC, 0x31313131,\n\t0xC5C5C5C5, 0x15151515, 0x57575757, 0x5F5F5F5F, 0x7F7F7F7F,\n\t0xFDFDFDFD, 0xF4F4F4F4, 0xD0D0D0D0, 0x42424242, 0x08080808,\n\t0x23232323, 0x8F8F8F8F, 0x3F3F3F3F, 0x06060606, 0x18181818,\n\t0x21212121, 0x05050505, 0x14141414, 0x11111111, 0x07070707,\n\t0x1E1E1E1E, 0x39393939, 0x25252525, 0x14141414, 0x11111111,\n\t0x06060606, 0x19191919, 0x27272727, 0x1C1C1C1C, 0x31313131,\n\t0x05050505, 0x17171717, 0x1F1F1F1F, 0x3E3E3E3E, 0x3B3B3B3B,\n\t0x2D2D2D2D, 0x34343434, 0x12121212, 0x08080808, 0x21212121,\n\t0x05050505, 0x16161616, 0x19191919, 0x26262626, 0x1A1A1A1A,\n\t0x29292929, 0x24242424, 0x13131313, 0x0F0F0F0F, 0x3F3F3F3F,\n\t0x3C3C3C3C, 0x33333333, 0x0D0D0D0D, 0x37373737, 0x1C1C1C1C,\n\t0x30303030, 0x03030303, 0x0F0F0F0F, 0x3E3E3E3E, 0x3A3A3A3A,\n\t0x2B2B2B2B, 0x2C2C2C2C, 0x33333333, 0x0C0C0C0C, 0x31313131,\n\t0x05050505, 0x15151515, 0x17171717, 0x1F1F1F1F, 0x3F3F3F3F,\n\t0x3D3D3D3D, 0x34343434, 0x10101010, 0x02020202, 0x08080808,\n\t0x23232323, 0x0F0F0F0F, 0x06060606, 0x18181818, 0x21212121,\n\t0x05050505, 0x14141414, 0x11111111, 0x07070707, 0x1E1E1E1E,\n\t0x39393939, 0x25252525, 0x14141414, 0x11111111, 0x06060606,\n\t0x19191919, 0x27272727, 0x1C1C1C1C, 0x31313131, 0x05050505,\n\t0x17171717, 0x1F1F1F1F, 0x3E3E3E3E, 0x3B3B3B3B, 0x2D2D2D2D,\n\t0x34343434, 0x12121212, 0x08080808, 0x21212121, 0x05050505,\n\t0x16161616, 0x19191919, 0x26262626, 0x1A1A1A1A, 0x29292929,\n\t0x24242424, 0x13131313, 0x0F0F0F0F, 0x3F3F3F3F, 0x3C3C3C3C,\n\t0x33333333, 0x0D0D0D0D, 0x37373737, 0x1C1C1C1C, 0x30303030,\n\t0x03030303, 0x0F0F0F0F, 0x3E3E3E3E, 0x3A3A3A3A, 0x2B2B2B2B,\n\t0x2C2C2C2C, 0x33333333, 0x0C0C0C0C, 0x31313131, 0x05050505,\n\t0x15151515, 0x17171717, 0x1F1F1F1F, 0x3F3F3F3F, 0x3D3D3D3D,\n\t0x34343434, 0x10101010, 0x02020202, 0x08080808, 0x23232323,\n\t0x0F0F0F0F,\n\n\t/* DQ RAM Patterns Table 1 */\n\t0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000,\n\t0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,\n\t0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,\n\t0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,\n\t0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000,\n\t0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,\n\t0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,\n\t0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,\n\t0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,\n\t0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF,\n\t0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF,\n\t0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,\n\t0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF,\n\t0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000,\n\t0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,\n\t0x3F3F3F3F, 0x00000000, 0x00000000, 0x00000000, 0x00000000,\n\t0x00000000, 0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x00000000,\n\t0x00000000, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F,\n\t0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x00000000, 0x3F3F3F3F,\n\t0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x3F3F3F3F, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F,\n\t0x3F3F3F3F, 0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F,\n\t0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x00000000, 0x00000000,\n\t0x3F3F3F3F, 0x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,\n\t0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x00000000, 0x00000000,\n\t0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F, 0x3F3F3F3F,\n\t0x3F3F3F3F, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x00000000, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,\n\t0x3F3F3F3F, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F,\n\t0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F, 0x3F3F3F3F,\n\t0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F,\n\t0x3F3F3F3F, 0x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F,\n\t0x00000000,\n\n\t/* DQ RAM Patterns Table 2 */\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,\n\t0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,\n\t0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,\n\t0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,\n\t0x3F3F3F3F,\n\n\t/* DQ RAM Patterns Table 3 */\n\t0x80808080, 0x00000000, 0x80808080, 0x00000000, 0x80808080,\n\t0x00000000, 0x80808080, 0x40404040, 0x00000000, 0x40404040,\n\t0x00000000, 0x40404040, 0x00000000, 0x40404040, 0x20202020,\n\t0x00000000, 0x20202020, 0x00000000, 0x20202020, 0x00000000,\n\t0x20202020, 0x10101010, 0x00000000, 0x10101010, 0x00000000,\n\t0x10101010, 0x00000000, 0x10101010, 0x08080808, 0x00000000,\n\t0x08080808, 0x00000000, 0x08080808, 0x00000000, 0x08080808,\n\t0x04040404, 0x00000000, 0x04040404, 0x00000000, 0x04040404,\n\t0x00000000, 0x04040404, 0x02020202, 0x00000000, 0x02020202,\n\t0x00000000, 0x02020202, 0x00000000, 0x02020202, 0x01010101,\n\t0x00000000, 0x01010101, 0x00000000, 0x01010101, 0x00000000,\n\t0x01010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000,\n\t0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80808080,\n\t0x00000000, 0x80808080, 0x00000000, 0x80808080, 0x00000000,\n\t0x80808080, 0x40404040, 0x00000000, 0x40404040, 0x00000000,\n\t0x40404040, 0x00000000, 0x40404040, 0x20202020, 0x00000000,\n\t0x20202020, 0x00000000, 0x20202020, 0x00000000, 0x20202020,\n\t0x10101010, 0x00000000, 0x10101010, 0x00000000, 0x10101010,\n\t0x00000000, 0x10101010, 0x08080808, 0x00000000, 0x08080808,\n\t0x00000000, 0x08080808, 0x00000000, 0x08080808, 0x04040404,\n\t0x00000000, 0x04040404, 0x00000000, 0x04040404, 0x00000000,\n\t0x04040404, 0x02020202, 0x00000000, 0x02020202, 0x00000000,\n\t0x02020202, 0x00000000, 0x02020202, 0x01010101, 0x00000000,\n\t0x01010101, 0x00000000, 0x01010101, 0x00000000, 0x01010101,\n\t0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,\n\t0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x20202020,\n\t0x00000000, 0x20202020, 0x00000000, 0x20202020, 0x00000000,\n\t0x20202020, 0x00000000, 0x20202020, 0x00000000, 0x10101010,\n\t0x00000000, 0x10101010, 0x00000000, 0x10101010, 0x00000000,\n\t0x10101010, 0x00000000, 0x10101010, 0x00000000, 0x08080808,\n\t0x00000000, 0x08080808, 0x00000000, 0x08080808, 0x00000000,\n\t0x08080808, 0x00000000, 0x08080808, 0x00000000, 0x04040404,\n\t0x00000000, 0x04040404, 0x00000000, 0x04040404, 0x00000000,\n\t0x04040404, 0x00000000, 0x04040404, 0x00000000, 0x02020202,\n\t0x00000000, 0x02020202, 0x00000000, 0x02020202, 0x00000000,\n\t0x02020202, 0x00000000, 0x02020202, 0x00000000, 0x01010101,\n\t0x00000000, 0x01010101, 0x00000000, 0x01010101, 0x00000000,\n\t0x01010101, 0x00000000, 0x01010101, 0x00000000, 0x00000000,\n\t0x00000000, 0x00000000, 0x00000000, 0x20202020, 0x00000000,\n\t0x20202020, 0x00000000, 0x20202020, 0x00000000, 0x20202020,\n\t0x00000000, 0x20202020, 0x00000000, 0x10101010, 0x00000000,\n\t0x10101010, 0x00000000, 0x10101010, 0x00000000, 0x10101010,\n\t0x00000000, 0x10101010, 0x00000000, 0x08080808, 0x00000000,\n\t0x08080808, 0x00000000, 0x08080808, 0x00000000, 0x08080808,\n\t0x00000000, 0x08080808, 0x00000000, 0x04040404, 0x00000000,\n\t0x04040404, 0x00000000, 0x04040404, 0x00000000, 0x04040404,\n\t0x00000000, 0x04040404, 0x00000000, 0x02020202, 0x00000000,\n\t0x02020202, 0x00000000, 0x02020202, 0x00000000, 0x02020202,\n\t0x00000000, 0x02020202, 0x00000000, 0x01010101, 0x00000000,\n\t0x01010101, 0x00000000, 0x01010101, 0x00000000, 0x01010101,\n\t0x00000000, 0x01010101, 0x00000000, 0x00000000, 0x00000000,\n\t0x00000000,\n\n\t/* DQ RAM Patterns Table 4 */\n\t0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,\n\t0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,\n\t0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,\n\t0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,\n\t0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,\n\t0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,\n\t0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,\n\t0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,\n\t0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,\n\t0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,\n\t0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,\n\t0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,\n\t0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,\n\t0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,\n\t0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,\n\t0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,\n\t0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,\n\t0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,\n\t0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,\n\t0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,\n\t0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,\n\t0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,\n\t0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,\n\t0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,\n\t0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,\n\t0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,\n\t0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,\n\t0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,\n\t0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,\n\t0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,\n\t0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,\n\t0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,\n\t0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,\n\t0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,\n\t0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,\n\t0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,\n\t0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,\n\t0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,\n\t0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,\n\t0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,\n\t0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,\n\t0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,\n\t0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,\n\t0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,\n\t0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,\n\t0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,\n\t0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,\n\t0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,\n\t0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,\n\t0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,\n\t0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,\n\t0x33333333\n};\n\nstatic const u32 ram_pattern_dmi_table[0x500] = {\n\t/* DMI RAM Patterns Table 0 */\n\t0xF, 0xF, 0x0, 0xF, 0xF, 0x0, 0xF, 0xF,\n\t0x0, 0xF, 0x0, 0xF, 0xF, 0x0, 0xF, 0xF,\n\t0xF, 0xF, 0x0, 0xF, 0xF, 0x0, 0x0, 0x0,\n\t0xF, 0xF, 0x0, 0xF, 0x0, 0x0, 0xF, 0x0,\n\t0xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0x0,\n\t0x0, 0xF, 0xF, 0x0, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF,\n\t0x0, 0x0, 0x0, 0x0, 0xF, 0xF, 0xF, 0x0,\n\t0xF, 0xF, 0x0, 0xF, 0xF, 0x0, 0xF, 0xF,\n\t0x0, 0xF, 0x0, 0xF, 0xF, 0x0, 0xF, 0xF,\n\t0xF, 0xF, 0x0, 0xF, 0xF, 0x0, 0x0, 0x0,\n\t0xF, 0xF, 0x0, 0xF, 0x0, 0x0, 0xF, 0x0,\n\t0xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0x0,\n\t0x0, 0xF, 0xF, 0x0, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF,\n\t0x0, 0x0, 0x0, 0x0, 0xF, 0xF, 0xF, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\n\t/* DMI RAM Patterns Table 1 */\n\t0x0, 0x0, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0xF, 0xF, 0x0, 0x0, 0x0, 0x0, 0xF, 0x0,\n\t0xF, 0x0, 0x0, 0x0, 0xF, 0xF, 0xF, 0xF,\n\t0x0, 0x0, 0xF, 0x0, 0x0, 0x0, 0xF, 0x0,\n\t0xF, 0xF, 0x0, 0x0, 0xF, 0xF, 0xF, 0x0,\n\t0xF, 0x0, 0xF, 0x0, 0x0, 0xF, 0xF, 0xF,\n\t0xF, 0xF, 0x0, 0xF, 0x0, 0x0, 0x0, 0x0,\n\t0xF, 0xF, 0xF, 0x0, 0x0, 0x0, 0xF, 0x0,\n\t0x0, 0x0, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0xF, 0xF, 0x0, 0x0, 0x0, 0x0, 0xF, 0x0,\n\t0xF, 0x0, 0x0, 0x0, 0xF, 0xF, 0xF, 0xF,\n\t0x0, 0x0, 0xF, 0x0, 0x0, 0x0, 0xF, 0x0,\n\t0xF, 0xF, 0x0, 0x0, 0xF, 0xF, 0xF, 0x0,\n\t0xF, 0x0, 0xF, 0x0, 0x0, 0xF, 0xF, 0xF,\n\t0xF, 0xF, 0x0, 0xF, 0x0, 0x0, 0x0, 0x0,\n\t0xF, 0xF, 0xF, 0x0, 0x0, 0x0, 0xF, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\n\t/* DMI RAM Patterns Table 2 */\n\t0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\n\t/* DMI RAM Patterns Table 3 */\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\t0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\n\n\t/* DMI RAM Patterns Table 4 */\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,\n\t0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3\n};\n\nstatic void _usleep(u32 microseconds)\n{\n\tu32 start = TMR(0x10);\n\twhile ((u32)(TMR(0x10) - start) <= microseconds)\n\t\t;\n}\n\nstatic s32 _fceil(float var)\n{\n\ts32 result = (s32)(var + 0.5f);\n\n\treturn result;\n}\n\nstatic u32 _actual_osc_clocks(u32 in)\n{\n\tu32 actual_clock;\n\n\tactual_clock = 16 * in;\n\tif (in > 63)\n\t{\n\t\tactual_clock = 2048;\n\t\tif (in > 127)\n\t\t{\n\t\t\tif (in >= 192)\n\t\t\t\tactual_clock = 8192;\n\t\t\telse\n\t\t\t\tactual_clock = 4096;\n\t\t}\n\t}\n\n\treturn actual_clock;\n}\n\nstatic void _ccfifo_write(u32 addr, u32 data_val, u32 delay) //addr and delay are u16\n{\n\tEMC(EMC_CCFIFO_DATA) = data_val;\n\tEMC(EMC_CCFIFO_ADDR) = (addr & 0xffff) | ((delay & 0x7FFF) << 16) | (1 << 31);\n}\n\nstatic bool _wait_emc_status(u32 reg_offset, u32 bit_mask, bool updated_state, s32 emc_channel)\n{\n\tbool err = true;\n\n\tfor (s32 i = 0; i < EMC_STATUS_UPDATE_TIMEOUT; i++)\n\t{\n\t\tif (emc_channel)\n\t\t{\n\t\t\tif (emc_channel != 1)\n\t\t\t\tgoto done;\n\t\t\tif (((EMC_CH1(reg_offset) & bit_mask) != 0) == updated_state)\n\t\t\t{\n\t\t\t\terr = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (((EMC(reg_offset) & bit_mask) != 0) == updated_state)\n\t\t\t{\n\t\t\t\terr = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t_usleep(1);\n\t}\ndone:\n\treturn err;\n}\n\nstatic void _request_mmr_data(u32 data, bool dual_channel)\n{\n\tEMC(EMC_MRR) = data;\n\t_wait_emc_status(EMC_EMC_STATUS, MRR_DIVLD, true, EMC_CH0);\n\tif (dual_channel)\n\t\t_wait_emc_status(EMC_EMC_STATUS, MRR_DIVLD, true, EMC_CH1);\n}\n\nstatic u32 _start_periodic_compensation()\n{\n\tEMC(EMC_MPC) = 0x4B;\n\n\treturn EMC(EMC_MPC);\n}\n\nstatic bool _timing_update(s32 dual_channel)\n{\n\tbool err = 0;\n\n\tEMC(EMC_TIMING_CONTROL) = 1;\n\terr = _wait_emc_status(EMC_EMC_STATUS, TIMING_UPDATE_STALLED, false, EMC_CH0);\n\tif (dual_channel)\n\t\terr |= _wait_emc_status(EMC_EMC_STATUS, TIMING_UPDATE_STALLED, false, EMC_CH1);\n\n\treturn err;\n}\n\nstatic s32 _get_dram_temperature()\n{\n\ts32 mr4_0 = 0;\n\ts32 mr4_1 = 0;\n\n\tbool channel1_enabled = (EMC(EMC_FBIO_CFG7) >> 2) & 1;\n\tu32 emc_cfg_o = EMC(EMC_CFG);\n\n\t_wait_emc_status(EMC_EMC_STATUS, MRR_DIVLD, false, EMC_CH0);\n\n\tif (emc_cfg_o & 0x20000000)\n\t{\n\t\tEMC(EMC_CFG) = emc_cfg_o & 0xDFFFFFFF;\n\t\t_timing_update(channel1_enabled);\n\t}\n\n\t_request_mmr_data(0x80040000, EMC_CH0);\n\tmr4_0 = EMC(EMC_MRR) & 0xFFFF;\n\n\tif (mr4_0 < 0xF001)\n\t\tmr4_0 &= 0x7;\n\telse\n\t{\n\t\tmr4_0 = -1;\n\t\tgoto out;\n\t}\n\n\tif (channel1_enabled)\n\t{\n\t\t_request_mmr_data(0x40040000, channel1_enabled);\n\t\tmr4_1 = EMC(EMC_MRR);\n\n\t\tif (mr4_1 < 0xF001)\n\t\t\tmr4_1 &= 0x7;\n\t\telse\n\t\t\tgoto out;\n\n\t\tif (mr4_1 > mr4_0)\n\t\t\tmr4_0 = mr4_1;\n\t}\n\nout:\n\tif (emc_cfg_o & 0x20000000)\n\t{\n\t\tEMC(EMC_CFG) = emc_cfg_o;\n\t\t_timing_update(channel1_enabled);\n\t}\n\n\treturn mr4_0;\n}\n\nstatic u32 _pllm_clk_base_cfg(s32 rate_KHz, u32 clk_src_emc, s32 emc_2X_clk_src_is_PLLMB)\n{\n\tu32 dividers = 0;\n\ts32 i = 0;\n\ts32 pll_ref = 38400; // Only 38.4MHz crystal is supported for T210.\n\n\tpllm_clk_config_t *pllm_clk_config;\n\n\tfor (i = 0; pllm_clk_config_table[i].pll_osc_in; i++)\n\t{\n\t\tif (pllm_clk_config_table[i].pll_osc_in == pll_ref && pllm_clk_config_table[i].pll_out == rate_KHz)\n\t\t\tbreak;\n\t}\n\n\tpllm_clk_config = &pllm_clk_config_table[i];\n\tif (pllm_clk_config->pll_osc_in)\n\t{\n\t\tdividers = pllm_clk_config->pll_input_div | (pllm_clk_config->pll_feedback_div << 8) | ((pllm_clk_config->pll_post_div & 0x1F) << 20);\n\t\tif (emc_2X_clk_src_is_PLLMB)\n\t\t{\n\t\t\tCLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) = dividers;\n\t\t\tCLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) |= PLLM_ENABLE;\n\t\t\tif ((clk_src_emc >> EMC_2X_CLK_SRC_SHIFT) == PLLM_UD)\n\t\t\t\tclk_src_emc = (clk_src_emc & 0x1FFFFFFF) | (PLLMB_UD << EMC_2X_CLK_SRC_SHIFT);\n\t\t\telse if (!(clk_src_emc >> EMC_2X_CLK_SRC_SHIFT))\n\t\t\t\tclk_src_emc |= (PLLMB_OUT0 << EMC_2X_CLK_SRC_SHIFT);\n\t\t\twhile (!(CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) & PLLM_LOCK))\n\t\t\t\t;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tCLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = dividers;\n\t\t\tCLOCK(CLK_RST_CONTROLLER_PLLM_MISC2) |= 0x10u; // PLLM_EN_LCKDET.\n\t\t\tCLOCK(CLK_RST_CONTROLLER_PLLM_BASE) |= PLLM_ENABLE;\n\t\t\tif ((clk_src_emc >> EMC_2X_CLK_SRC_SHIFT) == PLLM_UD)\n\t\t\t\tclk_src_emc = (clk_src_emc & 0x1FFFFFFF) | (PLLM_UD << EMC_2X_CLK_SRC_SHIFT);\n\t\t\twhile (!(CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) & PLLM_LOCK))\n\t\t\t\t;\n\t\t}\n\t}\n\treturn clk_src_emc;\n}\n\nstatic void _change_dll_src(emc_table_t *mtc_table_entry, u32 clk_src_emc)\n{\n\tu32 emc_2x_clk_src = clk_src_emc >> EMC_2X_CLK_SRC_SHIFT;\n\n\tu32 dll_setting = ((((mtc_table_entry->dll_clk_src & 0x1FFFFFFF)\n\t\t\t| (emc_2x_clk_src << EMC_2X_CLK_SRC_SHIFT)) & 0xFFFFFF00)\n\t\t| (clk_src_emc & 0xFF)) & 0xFFFFF3FF;\n\n\tif (emc_2x_clk_src == PLLMB_UD)\n\t\tdll_setting |= 0x400; // PLLM_VCOB.\n\telse if (emc_2x_clk_src != PLLM_UD)\n\t\tdll_setting |= 0x800; // EMC_DLL_SWITCH_OUT.\n\n\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = dll_setting;\n\n\t//OLD\n\tu32 clk_enb_emc_dll = ((mtc_table_entry->clk_out_enb_x_0_clk_enb_emc_dll & 1) << 14) | (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) & 0xFFFFBFFF);\n\tCLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) = clk_enb_emc_dll;\n\n\t//NEW\n\t// _usleep(2);\n\t// if (mtc_table_entry->clk_out_enb_x_0_clk_enb_emc_dll)\n\t// \tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) |= 0x4000;\n\t// else\n\t// \tCLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_CLR) |= 0x4000;\n\t// _usleep(2);\n}\n\nstatic u32 _digital_dll_prelock(emc_table_t *mtc_table_entry, u32 needs_tristate_training, u32 selected_clk_src_emc)\n{\n\ts32 dual_channel = (EMC(EMC_FBIO_CFG7) >> 1) & ((EMC(EMC_FBIO_CFG7) >> 2) & 1);\n\n\tEMC(EMC_CFG_DIG_DLL) = (EMC(EMC_CFG_DIG_DLL) & 0xFFFFF824) | 0x3C8;\n\n\t_timing_update(dual_channel);\n\n\twhile (EMC(EMC_CFG_DIG_DLL) & 1)\n\t\t;\n\tif (dual_channel)\n\t\twhile (EMC_CH1(EMC_CFG_DIG_DLL) & 1)\n\t\t\t;\n\n\tEMC(EMC_DLL_CFG_0) = mtc_table_entry->burst_regs.emc_dll_cfg_0_idx;\n\tEMC(EMC_DLL_CFG_1) = mtc_table_entry->burst_regs.emc_dll_cfg_1_idx;\n\n\t_change_dll_src(mtc_table_entry, selected_clk_src_emc);\n\n\tEMC(EMC_CFG_DIG_DLL) |= 1;\n\t\n\t_timing_update(dual_channel);\n\n\twhile (!(EMC(EMC_CFG_DIG_DLL) & 1))\n\t\t;\n\tif (dual_channel)\n\t\twhile (!(EMC_CH1(EMC_CFG_DIG_DLL) & 1))\n\t\t\t;\n\n\twhile ((((EMC(EMC_DIG_DLL_STATUS) >> 17) & 1) ^ 1) | (((EMC(EMC_DIG_DLL_STATUS) >> 15) & 1) ^ 1))\n\t\t;\n\n\tif (needs_tristate_training)\n\t{\n\t\tEMC(EMC_DBG) |= 2u;\n\t\tEMC(EMC_CFG_DIG_DLL) &= 0xFFFFFFFE; //Disable CFG_DLL_EN: [PMC] Enable digital DLL.\n\t\tEMC(EMC_DBG) &= 0xFFFFFFFD;\n\t\twhile (EMC(EMC_CFG_DIG_DLL) & 1)\n\t\t\t;\n\t\tif (dual_channel)\n\t\t\twhile (EMC_CH1(EMC_CFG_DIG_DLL) & 1)\n\t\t\t\t;\n\t}\n\n\treturn EMC(EMC_DIG_DLL_STATUS) & 0x7FF;\n}\n\nstatic void _digital_dll_disable()\n{\n\tbool dual_channel = (EMC(EMC_FBIO_CFG7) >> 1) & ((EMC(EMC_FBIO_CFG7) >> 2) & 1);\n\n\tEMC(EMC_CFG_DIG_DLL) &= 0xFFFFFFFE;\n\n\t_timing_update(dual_channel);\n\n\twhile (EMC(EMC_CFG_DIG_DLL) & 1)\n\t\t;\n\tif (dual_channel)\n\t{\n\t\twhile (EMC_CH1(EMC_CFG_DIG_DLL) & 1)\n\t\t\t;\n\t}\n}\n\nstatic void _digital_dll_enable(s32 channel1_enabled)\n{\n\tEMC(EMC_CFG_DIG_DLL) |= 1;\n\n\t_timing_update(channel1_enabled);\n\n\twhile (!(EMC(EMC_CFG_DIG_DLL) & 1))\n\t\t;\n\tif (channel1_enabled)\n\t{\n\t\twhile (!(EMC_CH1(EMC_CFG_DIG_DLL) & 1))\n\t\t\t;\n\t}\n}\n\nstatic void _digital_dll_enable_rs(s32 channel1_enabled)\n{\n\tEMC(EMC_CFG_DIG_DLL) = (EMC(EMC_CFG_DIG_DLL) & 0xFFFFFF24) | 0x89;\n\n\t_timing_update(channel1_enabled);\n\n\twhile (!(EMC(EMC_CFG_DIG_DLL) & 1))\n\t\t;\n\tif (channel1_enabled)\n\t{\n\t\twhile (!(EMC_CH1(EMC_CFG_DIG_DLL) & 1))\n\t\t\t;\n\t}\n}\n\nstatic u32 _dvfs_power_ramp_down(bool flip_backward, emc_table_t *src_emc_table_entry, emc_table_t *dst_emc_table_entry, float src_clock_period)\n{\n\tu32 pmacro_cmd_pad;\n\tu32 pmacro_rfu1;\n\tu32 pmacro_cfg5;\n\tu32 pmacro_common_tx;\n\tu32 pmacro_dq_pad;\n\n\tfloat src_clk_per_pc = (100.0f / src_clock_period) + 1.0f;\n\n\tif (flip_backward)\n\t{\n\t\tpmacro_cmd_pad = dst_emc_table_entry->burst_regs.emc_pmacro_cmd_pad_tx_ctrl_idx;\n\t\tpmacro_dq_pad = dst_emc_table_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl_idx;\n\t\tpmacro_rfu1 = dst_emc_table_entry->burst_regs.emc_pmacro_brick_ctrl_rfu1_idx;\n\t\tpmacro_cfg5 = dst_emc_table_entry->burst_regs.emc_fbio_cfg5_idx;\n\t\tpmacro_common_tx = dst_emc_table_entry->burst_regs.emc_pmacro_common_pad_tx_ctrl_idx;\n\t}\n\telse\n\t{\n\t\tpmacro_cmd_pad = src_emc_table_entry->burst_regs.emc_pmacro_cmd_pad_tx_ctrl_idx;\n\t\tpmacro_dq_pad = (dst_emc_table_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl_idx & 0x101) | src_emc_table_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl_idx;\n\t\tpmacro_rfu1 = src_emc_table_entry->burst_regs.emc_pmacro_brick_ctrl_rfu1_idx;\n\t\tpmacro_cfg5 = src_emc_table_entry->burst_regs.emc_fbio_cfg5_idx;\n\t\tpmacro_common_tx = src_emc_table_entry->burst_regs.emc_pmacro_common_pad_tx_ctrl_idx;\n\t}\n\tu32 pmacro_cmd_pad_drvforceon = pmacro_cmd_pad | 0x4000000;\n\n\tu32 ramp_down_wait = (u32)(float)(src_clock_period * 12.0f);\n\n\t_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_drvforceon, 0);\n\t_ccfifo_write(EMC_FBIO_CFG5, pmacro_cfg5 | 0x100, 12);\n\n\tif (src_clock_period >= 1.0f) // Dvfs high speed threshold.\n\t{\n\t\t_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xF800F800, (u32)(float)(src_clk_per_pc + 19.0f));\n\t\tramp_down_wait = (u32)(float)((float)ramp_down_wait + (100.0f + (src_clock_period * 20.0f)));\n\t}\n\telse\n\t{\n\t\tramp_down_wait += 100;\n\t\tif (src_clock_period >= 0.416666667) // Iobrick dcc threshold.\n\t\t\t_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFEEDFEED, (u32)src_clk_per_pc);\n\t\telse\n\t\t{\n\t\t\tpmacro_dq_pad = (pmacro_dq_pad & 0xFEFEFDFD) | 0x10200;\n\t\t\tpmacro_cmd_pad_drvforceon = (pmacro_cmd_pad & 0xFEFEFDFD) | 0x4010200;\n\t\t\t_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_drvforceon, (u32)src_clk_per_pc);\n\t\t\t_ccfifo_write(EMC_PMACRO_DATA_PAD_TX_CTRL, pmacro_dq_pad, 0);\n\t\t\t_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFEEDFEED, 0);\n\t\t}\n\t\tramp_down_wait += 200;\n\t\t_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFE40FE40, (u32)src_clk_per_pc);\n\t\tif (src_clock_period >= 0.416666667) // Iobrick dcc threshold.\n\t\t\t_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xF800F800, (u32)src_clk_per_pc);\n\t\telse\n\t\t{\n\t\t\t_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_drvforceon & 0xFEFEFDFD, (u32)src_clk_per_pc);\n\t\t\t_ccfifo_write(EMC_PMACRO_DATA_PAD_TX_CTRL, pmacro_dq_pad & 0xFEFEFDFD, 0);\n\t\t\t_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xF800F800, 0);\n\t\t}\n\t}\n\tif (src_clock_period >= 1.66666667) // Dvfs mid speed threshold.\n\t{\n\t\t_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_common_tx & 0xFFFFFFF0, (u32)src_clk_per_pc);\n\t}\n\telse\n\t{\n\t\tramp_down_wait += 400;\n\t\t_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_common_tx & 0xFFFFFFFA, (u32)src_clk_per_pc);\n\t\t_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_common_tx & 0xFFFFFFF0, (u32)src_clk_per_pc);\n\t\t_ccfifo_write(0, 0, (u32)src_clk_per_pc);\n\t}\n\n\treturn ramp_down_wait;\n}\n\nstatic u32 _dvfs_power_ramp_up(bool flip_backward, emc_table_t *src_emc_table_entry, emc_table_t *dst_emc_table_entry, u8 needs_training, float dst_clock_period)\n{\n\tu32 pmacro_cmd_pad;\n\tu32 pmacro_dq_pad;\n\tu32 pmacro_rfu1;\n\tu32 pmacro_cfg5;\n\tu32 pmacro_common_tx;\n\tu32 pmacro_cmd_pad_data;\n\tu32 ramp_up_wait = 0;\n\n\tfloat dst_clk_per_pc = (100.0f / dst_clock_period) + 1.0f;\n\tif (flip_backward)\n\t{\n\t\tpmacro_cmd_pad = src_emc_table_entry->burst_regs.emc_pmacro_cmd_pad_tx_ctrl_idx;\n\t\tpmacro_dq_pad = src_emc_table_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl_idx;\n\t\tpmacro_rfu1 = src_emc_table_entry->burst_regs.emc_pmacro_brick_ctrl_rfu1_idx;\n\t\tpmacro_cfg5 = src_emc_table_entry->burst_regs.emc_fbio_cfg5_idx;\n\t\tpmacro_common_tx = src_emc_table_entry->burst_regs.emc_pmacro_common_pad_tx_ctrl_idx;\n\t}\n\telse if (needs_training & 3)\n\t{\n\t\tpmacro_cmd_pad = dst_emc_table_entry->shadow_regs_ca_train.emc_pmacro_cmd_pad_tx_ctrl_idx;\n\t\tpmacro_dq_pad = dst_emc_table_entry->shadow_regs_ca_train.emc_pmacro_data_pad_tx_ctrl_idx;\n\t\tpmacro_rfu1 = dst_emc_table_entry->shadow_regs_ca_train.emc_pmacro_brick_ctrl_rfu1_idx;\n\t\tpmacro_cfg5 = dst_emc_table_entry->shadow_regs_ca_train.emc_fbio_cfg5_idx;\n\t\tpmacro_common_tx = dst_emc_table_entry->shadow_regs_ca_train.emc_pmacro_common_pad_tx_ctrl_idx;\n\t}\n\telse if (needs_training & 0xC)\n\t{\n\t\tpmacro_cmd_pad = dst_emc_table_entry->shadow_regs_quse_train.emc_pmacro_cmd_pad_tx_ctrl_idx;\n\t\tpmacro_dq_pad = dst_emc_table_entry->shadow_regs_quse_train.emc_pmacro_data_pad_tx_ctrl_idx;\n\t\tpmacro_rfu1 = dst_emc_table_entry->shadow_regs_quse_train.emc_pmacro_brick_ctrl_rfu1_idx;\n\t\tpmacro_cfg5 = dst_emc_table_entry->shadow_regs_quse_train.emc_fbio_cfg5_idx;\n\t\tpmacro_common_tx = dst_emc_table_entry->shadow_regs_quse_train.emc_pmacro_common_pad_tx_ctrl_idx;\n\t}\n\telse if (needs_training & 0xF0)\n\t{\n\t\tpmacro_cmd_pad = dst_emc_table_entry->shadow_regs_rdwr_train.emc_pmacro_cmd_pad_tx_ctrl_idx;\n\t\tpmacro_dq_pad = dst_emc_table_entry->shadow_regs_rdwr_train.emc_pmacro_data_pad_tx_ctrl_idx;\n\t\tpmacro_rfu1 = dst_emc_table_entry->shadow_regs_rdwr_train.emc_pmacro_brick_ctrl_rfu1_idx;\n\t\tpmacro_cfg5 = dst_emc_table_entry->shadow_regs_rdwr_train.emc_fbio_cfg5_idx;\n\t\tpmacro_common_tx = dst_emc_table_entry->shadow_regs_rdwr_train.emc_pmacro_common_pad_tx_ctrl_idx;\n\t}\n\telse\n\t{\n\t\tpmacro_cmd_pad = dst_emc_table_entry->burst_regs.emc_pmacro_cmd_pad_tx_ctrl_idx;\n\t\tpmacro_dq_pad = dst_emc_table_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl_idx;\n\t\tpmacro_rfu1 = dst_emc_table_entry->burst_regs.emc_pmacro_brick_ctrl_rfu1_idx;\n\t\tpmacro_cfg5 = dst_emc_table_entry->burst_regs.emc_fbio_cfg5_idx;\n\t\tpmacro_common_tx = dst_emc_table_entry->burst_regs.emc_pmacro_common_pad_tx_ctrl_idx;\n\t}\n\tpmacro_cmd_pad_data = (pmacro_cmd_pad & 0xFEFEFDFD) | 0x4000000;\n\n\tif (dst_clock_period >= 1.66666667) // Dvfs mid speed threshold.\n\t{\n\t\t_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_common_tx | 8, 0);\n\t\tif (dst_clock_period >= 1.0) // Dvfs high speed threshold.\n\t\t{\n\t\t\tif (dst_clock_period >= 1.66666667) // Dvfs mid speed threshold.\n\t\t\t{\n\t\t\t\t_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 | 0x600, 0);\n\t\t\t\t_ccfifo_write(EMC_FBIO_CFG5, pmacro_cfg5 & 0xFFFFFEFF, 12);\n\t\t\t\tramp_up_wait = (u32)((float)(dst_clock_period * 12.0f) + 0.0);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 | 0x6000600, (u32)dst_clk_per_pc);\n\t\t\t\t_ccfifo_write(EMC_FBIO_CFG5, pmacro_cfg5 & 0xFFFFFEFF, (u32)(float)(dst_clk_per_pc + 9.0f));\n\t\t\t\tramp_up_wait = (u32)(float)(100.0f + (float)(dst_clock_period * 10.0f));\n\t\t\t}\n\t\t\t_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_data & 0xFBFFFFFF, 5);\n\n\t\t\treturn ramp_up_wait;\n\t\t}\n\n\t\t_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFE40FE40, (u32)dst_clk_per_pc);\n\t\t_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFEEDFEED, (u32)dst_clk_per_pc);\n\t\t_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1, (u32)dst_clk_per_pc);\n\t\t_ccfifo_write(EMC_FBIO_CFG5, pmacro_cfg5 & 0xFFFFFEFF, (u32)(float)(dst_clk_per_pc + 9.0f));\n\t\tramp_up_wait = (u32)(float)((float)300 + (float)(100.0f + (float)(dst_clock_period * 10.0f)));\n\t\t_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_data & 0xFBFFFFFF, 5);\n\n\t\treturn ramp_up_wait;\n\t}\n\t_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_common_tx & 0xA, 0);\n\t_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_common_tx & 0xF, (u32)dst_clk_per_pc);\n\n\tif (dst_clock_period < 1.0) // Dvfs high speed threshold.\n\t{\n\t\tif (dst_clock_period >= 0.416666667) // Iobrick dcc threshold.\n\t\t\t_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFE40FE40, (u32)dst_clk_per_pc);\n\t\telse\n\t\t{\n\t\t\tpmacro_cmd_pad_data = (pmacro_cmd_pad & 0xFEFEFDFD) | 0x4010200;\n\t\t\tpmacro_dq_pad = (pmacro_dq_pad & 0xFEFEFDFD) | 0x10200;\n\t\t\t_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_data, (u32)dst_clk_per_pc);\n\t\t\t_ccfifo_write(EMC_PMACRO_DATA_PAD_TX_CTRL, pmacro_dq_pad, 0);\n\t\t\t_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFE40FE40, 0);\n\t\t}\n\n\t\t_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFEEDFEED, (u32)dst_clk_per_pc);\n\n\t\tif (dst_clock_period >= 0.416666667) // Iobrick dcc threshold.\n\t\t\t_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1, (u32)dst_clk_per_pc);\n\t\telse\n\t\t{\n\t\t\tpmacro_cmd_pad_data |= 0x1010202u;\n\t\t\tpmacro_dq_pad |= 0x1010202;\n\t\t\t_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_data, (u32)dst_clk_per_pc);\n\t\t\t_ccfifo_write(EMC_PMACRO_DATA_PAD_TX_CTRL, pmacro_dq_pad, 0);\n\t\t\t_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1, 0);\n\t\t}\n\n\t\t_ccfifo_write(EMC_FBIO_CFG5, pmacro_cfg5 & 0xFFFFFEFF, (u32)(float)(dst_clk_per_pc + 9.0f));\n\t\tramp_up_wait = (u32)(float)((float)400 + (float)(100.0f + (float)(dst_clock_period * 10.0f)));\n\t\t_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_data & 0xFBFFFFFF, 5);\n\n\t\treturn ramp_up_wait;\n\t}\n\n\t// 1.0 > dst_clock_period < 1.66666667.\n\t_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 | 0x6000600, (u32)dst_clk_per_pc);\n\t_ccfifo_write(EMC_FBIO_CFG5, pmacro_cfg5 & 0xFFFFFEFF, (u32)(float)(dst_clk_per_pc + 9.0f));\n\n\tramp_up_wait = (u32)(float)((float)100 + (float)(100.0f + (float)(dst_clock_period * 10.0f)));\n\t_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_data & 0xFBFFFFFF, 5);\n\n\treturn ramp_up_wait;\n}\n\nstatic u32 _minerva_update_clock_tree_delay(emc_table_t *src_emc_entry, emc_table_t *dst_emc_entry, s32 dram_dev_num, s32 channel1_enabled, enum tree_update_mode_t update_type)\n{\n\ts32 temp_ch0_0 = 0;\n\ts32 temp_ch0_1 = 0;\n\ts32 temp_ch1_0 = 0;\n\ts32 temp_ch1_1 = 0;\n\n\ts32 dst_rate_mhz;\n\n\tu32 cval = 0;\n\ts32 tdel0_0 = 0;\n\ts32 tdel0_1 = 0;\n\ts32 tdel1_0 = 0;\n\ts32 tdel1_1 = 0;\n\ts32 tmp_tdel0_0 = 0;\n\n\ttemp_ch0_0 = 0x10624DD3; // div 1000 denominator\n\ttemp_ch0_1 = dst_emc_entry->rate_khz;\n\tdst_rate_mhz = dst_emc_entry->rate_khz / 1000;\n\tu32 upd_type_bits = 1 << update_type;\n\n\tu32 tval = 1000 * (1000 * _actual_osc_clocks(src_emc_entry->run_clocks) / (src_emc_entry->rate_khz / 1000));\n\tif (update_type <= PERIODIC_TRAINING_UPDATE)\n\t{\n\t\ttemp_ch0_1 = 1 << update_type;\n\t\ttemp_ch0_0 = 0x5400;\n\t\tif (upd_type_bits & 0x5400)\n\t\t{\n\t\t\t_request_mmr_data(0x80130000, channel1_enabled); // Dev0 MRR 19.\n\t\t\ttemp_ch0_0 = (EMC(EMC_MRR) & 0xFF) << 8;\n\t\t\ttemp_ch0_1 = EMC(EMC_MRR) & 0xFF00;\n\t\t\tif (channel1_enabled)\n\t\t\t{\n\t\t\t\ttemp_ch1_0 = (EMC_CH1(EMC_MRR) & 0xFF) << 8;\n\t\t\t\ttemp_ch1_1 = EMC_CH1(EMC_MRR) & 0xFF00;\n\t\t\t}\n\n\t\t\t_request_mmr_data(0x80120000, channel1_enabled); // Dev0 MRR 18.\n\t\t\ttemp_ch0_0 |= EMC(EMC_MRR) & 0xFF;\n\t\t\ttemp_ch0_1 |= (EMC(EMC_MRR) & 0xFF00) >> 8;\n\t\t\tif (channel1_enabled)\n\t\t\t{\n\t\t\t\ttemp_ch1_0 |= EMC_CH1(EMC_MRR) & 0xFF;\n\t\t\t\ttemp_ch1_1 |= (EMC_CH1(EMC_MRR) & 0xFF00) >> 8;\n\t\t\t}\n\t\t}\n\t}\n\n\t//u32 delay = (u64)((u64)_actual_osc_clocks(src_emc_entry->run_clocks) * 1000000) / (u64)(src_emc_entry->rate_khz * 2);\n\tcval = tval / (2 * temp_ch0_0);\n\tswitch (update_type)\n\t{\n\tcase DVFS_PT1:\n\tcase TRAINING_PT1:\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0_idx += 100 * cval;\n\t\ttdel0_0 = 0;\n\t\tif (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))\n\t\t\tgoto calc_td0_0;\n\t\tbreak;\n\tcase DVFS_UPDATE:\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0_idx =\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0_idx / dst_emc_entry->ptfv_list.ptfv_dvfs_samples_idx;\n\t\tbreak;\n\tcase TRAINING_UPDATE:\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0_idx =\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0_idx / dst_emc_entry->ptfv_list.ptfv_write_samples_idx;\n\t\tbreak;\n\tcase PERIODIC_TRAINING_UPDATE:\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0_idx =\n\t\t\t(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight_idx * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0_idx)\n\t\t\t/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight_idx + 1);\n\t\tbreak;\n\tdefault:\n\t\ttdel0_0 = 0;\n\t\tif (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))\n\t\t\tgoto calc_td0_0;\n\t\tbreak;\n\t}\n\t\n\ttdel0_0 = dst_emc_entry->current_dram_clktree_c0d0u0 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0_idx / 100);\n\tif (tdel0_0 < 0)\n\t\ttdel0_0 = !tdel0_0;\n\tif (update_type == TRAINING_UPDATE || (dst_rate_mhz * tdel0_0 << 7) / 1000000 > dst_emc_entry->tree_margin)\n\t\tdst_emc_entry->current_dram_clktree_c0d0u0 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0_idx / 100;\n\ncalc_td0_0:\n\tcval = tval / (2 * temp_ch0_1);\n\tswitch (update_type)\n\t{\n\tcase DVFS_PT1:\n\tcase TRAINING_PT1:\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1_idx += 100 * cval;\n\t\tif (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))\n\t\t\tgoto calc_td1_0;\n\t\tbreak;\n\tcase DVFS_UPDATE:\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1_idx =\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1_idx / dst_emc_entry->ptfv_list.ptfv_dvfs_samples_idx;\n\t\tbreak;\n\tcase TRAINING_UPDATE:\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1_idx =\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1_idx / dst_emc_entry->ptfv_list.ptfv_write_samples_idx;\n\t\tbreak;\n\tcase PERIODIC_TRAINING_UPDATE:\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1_idx =\n\t\t\t(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight_idx * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1_idx)\n\t\t\t/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight_idx + 1);\n\t\tbreak;\n\tdefault:\n\t\tif (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))\n\t\t\tgoto calc_td1_0;\n\t\tbreak;\n\t}\n\n\ttdel0_1 = dst_emc_entry->current_dram_clktree_c0d0u1 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1_idx / 100);\n\tif (tdel0_1 < 0)\n\t\ttdel0_1 = !tdel0_1;\n\tif (tdel0_1 > tdel0_0)\n\t\ttdel0_0 = tdel0_1;\n\tif (update_type == TRAINING_UPDATE || (dst_rate_mhz * tdel0_1 << 7) / 1000000 > dst_emc_entry->tree_margin)\n\t\tdst_emc_entry->current_dram_clktree_c0d0u1 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1_idx / 100;\n\ncalc_td1_0:\n\tif (channel1_enabled == 1)\n\t{\n\t\tcval = tval / (2 * temp_ch1_0);\n\t\tswitch (update_type)\n\t\t{\n\t\tcase DVFS_PT1:\n\t\tcase TRAINING_PT1:\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0_idx += 100 * cval;\n\t\t\tif (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))\n\t\t\t\tgoto calc_td1_1;\n\t\t\tbreak;\n\t\tcase DVFS_UPDATE:\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0_idx =\n\t\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0_idx / dst_emc_entry->ptfv_list.ptfv_dvfs_samples_idx;\n\t\t\tbreak;\n\t\tcase TRAINING_UPDATE:\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0_idx =\n\t\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0_idx / dst_emc_entry->ptfv_list.ptfv_write_samples_idx;\n\t\t\tbreak;\n\t\tcase PERIODIC_TRAINING_UPDATE:\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0_idx =\n\t\t\t\t(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight_idx * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0_idx)\n\t\t\t\t/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight_idx + 1);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))\n\t\t\t\tgoto calc_td1_1;\n\t\t\tbreak;\n\t\t}\n\n\t\ttdel1_0 = dst_emc_entry->current_dram_clktree_c1d0u0 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0_idx / 100);\n\t\tif (tdel1_0 < 0)\n\t\t\ttdel1_0 = !tdel1_0;\n\t\tif (tdel1_0 > tdel0_0)\n\t\t\ttdel0_0 = tdel1_0;\n\t\tif (update_type == TRAINING_UPDATE || (dst_rate_mhz * tdel1_0 << 7) / 1000000 > dst_emc_entry->tree_margin)\n\t\t\tdst_emc_entry->current_dram_clktree_c1d0u0 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0_idx / 100;\n\ncalc_td1_1:\n\t\tcval = tval / (2 * temp_ch1_1);\n\t\tswitch (update_type)\n\t\t{\n\t\tcase DVFS_PT1:\n\t\tcase TRAINING_PT1:\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1_idx += 100 * cval;\n\t\t\tif (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))\n\t\t\t\tgoto calc_dev2;\n\t\t\tbreak;\n\t\tcase DVFS_UPDATE:\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1_idx =\n\t\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1_idx / dst_emc_entry->ptfv_list.ptfv_dvfs_samples_idx;\n\t\t\tbreak;\n\t\tcase TRAINING_UPDATE:\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1_idx =\n\t\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1_idx / dst_emc_entry->ptfv_list.ptfv_write_samples_idx;\n\t\t\tbreak;\n\t\tcase PERIODIC_TRAINING_UPDATE:\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1_idx =\n\t\t\t\t(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight_idx * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1_idx)\n\t\t\t\t/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight_idx + 1);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))\n\t\t\t\tgoto calc_dev2;\n\t\t\tbreak;\n\t\t}\n\n\t\ttdel1_1 = dst_emc_entry->current_dram_clktree_c1d0u1 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1_idx / 100);\n\t\tif (tdel1_1 < 0)\n\t\t\ttdel1_1 = !tdel1_1;\n\t\tif (tdel1_1 > tdel0_0)\n\t\t\ttdel0_0 = tdel1_1;\n\t\tif (update_type == TRAINING_UPDATE || (dst_rate_mhz * tdel1_1 << 7) / 1000000 > dst_emc_entry->tree_margin)\n\t\t\tdst_emc_entry->current_dram_clktree_c1d0u1 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1_idx / 100;\n\t}\n\ncalc_dev2:\n\tif (dram_dev_num != TWO_RANK)\n\t\tgoto out;\n\n\tif (update_type <= PERIODIC_TRAINING_UPDATE && upd_type_bits & 0x5400)\n\t{\n\t\t_request_mmr_data(0x40130000, channel1_enabled); // Dev1 MRR 19.\n\t\ttemp_ch0_0 = (EMC(EMC_MRR) & 0xFF) << 8;\n\t\ttemp_ch0_1 = EMC(EMC_MRR) & 0xFF00;\n\t\tif (channel1_enabled == 1)\n\t\t{\n\t\t\ttemp_ch1_0 = (EMC_CH1(EMC_MRR) & 0xFF) << 8;\n\t\t\ttemp_ch1_1 = EMC_CH1(EMC_MRR) & 0xFF00;\n\t\t}\n\n\t\t_request_mmr_data(0x40120000, channel1_enabled); // Dev1 MRR 18\n\t\ttemp_ch0_0 |= EMC(EMC_MRR) & 0xFF;\n\t\ttemp_ch0_1 |= ((EMC(EMC_MRR) & 0xFF00) >> 8);\n\t\tif (channel1_enabled == 1)\n\t\t{\n\t\t\ttemp_ch1_0 |= EMC_CH1(EMC_MRR) & 0xFF;\n\t\t\ttemp_ch1_1 |= (EMC_CH1(EMC_MRR) & 0xFF00) >> 8;\n\t\t}\n\t\t\n\t}\n\n\tcval = tval / (2 * temp_ch0_0);\n\tswitch (update_type )\n\t{\n\tcase DVFS_PT1:\n\tcase TRAINING_PT1:\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0_idx += 100 * cval;\n\t\tif (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))\n\t\t\tgoto calc_tmp_td0_1;\n\t\tbreak;\n\tcase DVFS_UPDATE:\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0_idx =\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0_idx / dst_emc_entry->ptfv_list.ptfv_dvfs_samples_idx;\n\t\tbreak;\n\tcase TRAINING_UPDATE:\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0_idx =\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0_idx / dst_emc_entry->ptfv_list.ptfv_write_samples_idx;\n\t\tbreak;\n\tcase PERIODIC_TRAINING_UPDATE:\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0_idx =\n\t\t\t(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight_idx * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0_idx)\n\t\t\t/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight_idx + 1);\n\t\tbreak;\n\tdefault:\n\t\tif (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))\n\t\t\tgoto calc_tmp_td0_1;\n\t\tbreak;\n\t}\n\n\ttmp_tdel0_0 = dst_emc_entry->current_dram_clktree_c0d1u0 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0_idx / 100);\n\tif (tmp_tdel0_0 < 0)\n\t\ttmp_tdel0_0 = !tmp_tdel0_0;\n\tif (tmp_tdel0_0 > tdel0_0)\n\t\ttdel0_0 = tmp_tdel0_0;\n\tif (update_type == TRAINING_UPDATE || (dst_rate_mhz * tmp_tdel0_0 << 7) / 1000000 > dst_emc_entry->tree_margin)\n\t\tdst_emc_entry->current_dram_clktree_c0d1u0 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0_idx / 100;\n\ncalc_tmp_td0_1:\n\tcval = tval / (2 * temp_ch0_1);\n\tswitch (update_type)\n\t{\n\tcase DVFS_PT1:\n\tcase TRAINING_PT1:\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1_idx += 100 * cval;\n\t\tif (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))\n\t\t\tgoto calc_tmp_td1_0;\n\t\tbreak;\n\tcase DVFS_UPDATE:\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1_idx =\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1_idx / dst_emc_entry->ptfv_list.ptfv_dvfs_samples_idx;\n\t\tbreak;\n\tcase TRAINING_UPDATE:\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1_idx =\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1_idx / dst_emc_entry->ptfv_list.ptfv_write_samples_idx;\n\t\tbreak;\n\tcase PERIODIC_TRAINING_UPDATE:\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1_idx =\n\t\t\t(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight_idx * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1_idx)\n\t\t\t/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight_idx + 1);\n\t\tbreak;\n\tdefault:\n\t\tif (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))\n\t\t\tgoto calc_tmp_td1_0;\n\t\tbreak;\n\t}\n\n\ttdel0_1 = dst_emc_entry->current_dram_clktree_c0d1u1 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1_idx / 100);\n\tif (tdel0_1 < 0)\n\t\ttdel0_1 = !tdel0_1;\n\tif (tdel0_1 > tdel0_0)\n\t\ttdel0_0 = tdel0_1;\n\tif (update_type == TRAINING_UPDATE || (dst_rate_mhz * tdel0_1 << 7) / 1000000 > dst_emc_entry->tree_margin)\n\t\tdst_emc_entry->current_dram_clktree_c0d1u1 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1_idx / 100;\n\ncalc_tmp_td1_0:\n\tif (channel1_enabled == 1)\n\t{\n\t\tcval = tval / (2 * temp_ch1_0);\n\t\tswitch (update_type)\n\t\t{\n\t\tcase DVFS_PT1:\n\t\tcase TRAINING_PT1:\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0_idx += 100 * cval;\n\t\t\tif (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))\n\t\t\t\tgoto calc_tmp_td1_1;\n\t\t\tbreak;\n\t\tcase DVFS_UPDATE:\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0_idx =\n\t\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0_idx / dst_emc_entry->ptfv_list.ptfv_dvfs_samples_idx;\n\t\t\tbreak;\n\t\tcase TRAINING_UPDATE:\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0_idx =\n\t\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0_idx / dst_emc_entry->ptfv_list.ptfv_write_samples_idx;\n\t\t\tbreak;\n\t\tcase PERIODIC_TRAINING_UPDATE:\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0_idx =\n\t\t\t\t(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight_idx * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0_idx)\n\t\t\t\t/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight_idx + 1);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))\n\t\t\t\tgoto calc_tmp_td1_1;\n\t\t\tbreak;\n\t\t}\n\n\t\ttdel1_0 = dst_emc_entry->current_dram_clktree_c1d1u0 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0_idx / 100);\n\t\tif (tdel1_0 < 0)\n\t\t\ttdel1_0 = !tdel1_0;\n\t\tif (tdel1_0 > tdel0_0)\n\t\t\ttdel0_0 = tdel1_0;\n\t\tif (update_type == TRAINING_UPDATE || (dst_rate_mhz * tdel1_0 << 7) / 1000000 > dst_emc_entry->tree_margin)\n\t\t\tdst_emc_entry->current_dram_clktree_c1d1u0 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0_idx / 100;\n\ncalc_tmp_td1_1:\n\t\tcval = tval / (2 * temp_ch1_1);\n\t\tswitch (update_type)\n\t\t{\n\t\tcase DVFS_PT1:\n\t\tcase TRAINING_PT1:\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1_idx += 100 * cval;\n\t\t\tif (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))\n\t\t\t\tgoto out;\n\t\t\tbreak;\n\t\tcase DVFS_UPDATE:\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1_idx =\n\t\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1_idx / dst_emc_entry->ptfv_list.ptfv_dvfs_samples_idx;\n\t\t\tbreak;\n\t\tcase TRAINING_UPDATE:\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1_idx =\n\t\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1_idx / dst_emc_entry->ptfv_list.ptfv_write_samples_idx;\n\t\t\tbreak;\n\t\tcase PERIODIC_TRAINING_UPDATE:\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1_idx =\n\t\t\t\t(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight_idx * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1_idx)\n\t\t\t\t/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight_idx + 1);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))\n\t\t\t\tgoto out;\n\t\t\tbreak;\n\t\t}\n\n\t\ttdel1_1 = dst_emc_entry->current_dram_clktree_c1d1u1 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1_idx / 100);\n\t\tif (tdel1_1 < 0)\n\t\t\ttdel1_1 = !tdel1_1;\n\t\tif (tdel1_1 > tdel0_0)\n\t\t\ttdel0_0 = tdel1_1;\n\t\tif (update_type == TRAINING_UPDATE || (dst_rate_mhz * tdel1_1 << 7) / 1000000 > dst_emc_entry->tree_margin)\n\t\t\tdst_emc_entry->current_dram_clktree_c1d1u1 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1_idx / 100;\n\t}\n\nout:\n\tif (update_type == TRAINING_UPDATE)\n\t{\n\t\tdst_emc_entry->trained_dram_clktree_c0d0u0 = dst_emc_entry->current_dram_clktree_c0d0u0;\n\t\tdst_emc_entry->trained_dram_clktree_c0d0u1 = dst_emc_entry->current_dram_clktree_c0d0u1;\n\t\tdst_emc_entry->trained_dram_clktree_c0d1u0 = dst_emc_entry->current_dram_clktree_c0d1u0;\n\t\tdst_emc_entry->trained_dram_clktree_c0d1u1 = dst_emc_entry->current_dram_clktree_c0d1u1;\n\t\tdst_emc_entry->trained_dram_clktree_c1d0u0 = dst_emc_entry->current_dram_clktree_c1d0u0;\n\t\tdst_emc_entry->trained_dram_clktree_c1d0u1 = dst_emc_entry->current_dram_clktree_c1d0u1;\n\t\tdst_emc_entry->trained_dram_clktree_c1d1u0 = dst_emc_entry->current_dram_clktree_c1d1u0;\n\t\tdst_emc_entry->trained_dram_clktree_c1d1u1 = dst_emc_entry->current_dram_clktree_c1d1u1;\n\t}\n\n\treturn (u32)tdel0_0;\n}\n\nstatic u32 _minerva_periodic_compensation_handler(emc_table_t *src_emc_entry, emc_table_t *dst_emc_entry, s32 dram_dev_num, s32 channel1_enabled, enum comp_seq_t seq_type)\n{\n\tif (!dst_emc_entry->periodic_training)\n\t\treturn seq_type;\n\n\tu32 adel = 0;\n\tu32 delay = 1000 * _actual_osc_clocks(src_emc_entry->run_clocks) / src_emc_entry->rate_khz + 2;\n\n\tif (seq_type == DVFS_SEQUENCE)\n\t{\n\t\tif (src_emc_entry->periodic_training && dst_emc_entry->ptfv_list.ptfv_config_ctrl_idx & 1)\n\t\t{\n\t\t\tu32 samples = dst_emc_entry->ptfv_list.ptfv_dvfs_samples_idx;\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0_idx = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0_idx * samples;\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1_idx = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1_idx * samples;\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0_idx = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0_idx * samples;\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1_idx = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1_idx * samples;\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0_idx = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0_idx * samples;\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1_idx = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1_idx * samples;\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0_idx = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0_idx * samples;\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1_idx = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1_idx * samples;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0_idx = 0;\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1_idx = 0;\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0_idx = 0;\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1_idx = 0;\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0_idx = 0;\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1_idx = 0;\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0_idx = 0;\n\t\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1_idx = 0;\n\n\t\t\tfor (s32 i = 0; i < dst_emc_entry->ptfv_list.ptfv_dvfs_samples_idx; i++)\n\t\t\t{\n\t\t\t\t_start_periodic_compensation();\n\t\t\t\t_usleep(delay);\n\t\t\t\t_minerva_update_clock_tree_delay(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, DVFS_PT1);\n\t\t\t}\n\t\t}\n\t\tadel = _minerva_update_clock_tree_delay(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, DVFS_UPDATE);\n\n\t\treturn adel;\n\t}\n\telse if (seq_type == WRITE_TRAINING_SEQUENCE)\n\t{\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0_idx = 0;\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1_idx = 0;\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0_idx = 0;\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1_idx = 0;\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0_idx = 0;\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1_idx = 0;\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0_idx = 0;\n\t\tdst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1_idx = 0;\n\n\t\tfor (s32 i = 0; i < dst_emc_entry->ptfv_list.ptfv_write_samples_idx; i++)\n\t\t{\n\t\t\t_start_periodic_compensation();\n\t\t\t_usleep(delay);\n\t\t\t_minerva_update_clock_tree_delay(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, TRAINING_PT1);\n\t\t}\n\t\tadel = _minerva_update_clock_tree_delay(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, TRAINING_UPDATE);\n\n\t\treturn adel;\n\t}\n\telse if (seq_type == PERIODIC_TRAINING_SEQUENCE)\n\t{\n\t\t_start_periodic_compensation();\n\t\t_usleep(delay);\n\t\tadel = _minerva_update_clock_tree_delay(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, PERIODIC_TRAINING_UPDATE);\n\n\t\treturn adel;\n\t}\n\n\treturn seq_type;\n}\n\n#define STORE_TRIM_VAL(chan, rank, reg, byte) \\\n\t\t((mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank##rank##_##reg##_idx >>\t\\\n\t \t\tEMC_PMACRO_OB_DDLL_LONG_DQ_BYTE##byte##_SHIFT) & 0x7FF) \\\n\t\t+ \\\n\t\t(((mtc_table_entry->trim_perch_regs.emc##chan##_data_brlshft_##rank##_idx >>\t\\\n\t\t\tEMC_DATA_BRLSHFT_##rank##_RANK##rank##_BYTE##byte##_DATA_BRLSHFT_SHIFT) & 0x7) << 6)\n\nstatic u32 _minerva_apply_periodic_compensation_trimmer(emc_table_t *mtc_table_entry, u32 trim_emc_reg_addr)\n{\n\tu32 trimmer = 0;\n\ts32 tree_delta[4] = {0};\n\ts32 tree_delta_taps[4] = {0};\n\ts32 new_trim[] = {\n\t\t// chan, rank, reg, byte.\n\t\tSTORE_TRIM_VAL(0, 0, 0, 0),\n\t\tSTORE_TRIM_VAL(0, 0, 0, 1),\n\t\tSTORE_TRIM_VAL(0, 0, 1, 2),\n\t\tSTORE_TRIM_VAL(0, 0, 1, 3),\n\n\t\tSTORE_TRIM_VAL(1, 0, 2, 4),\n\t\tSTORE_TRIM_VAL(1, 0, 2, 5),\n\t\tSTORE_TRIM_VAL(1, 0, 3, 6),\n\t\tSTORE_TRIM_VAL(1, 0, 3, 7),\n\n\t\tSTORE_TRIM_VAL(0, 1, 0, 0),\n\t\tSTORE_TRIM_VAL(0, 1, 0, 1),\n\t\tSTORE_TRIM_VAL(0, 1, 1, 2),\n\t\tSTORE_TRIM_VAL(0, 1, 1, 3),\n\n\t\tSTORE_TRIM_VAL(1, 1, 2, 4),\n\t\tSTORE_TRIM_VAL(1, 1, 2, 5),\n\t\tSTORE_TRIM_VAL(1, 1, 3, 6),\n\t\tSTORE_TRIM_VAL(1, 1, 3, 7)\n\t};\n\n\tu32 dst_rate_mhz = mtc_table_entry->rate_khz / 1000;\n\n\tswitch (trim_emc_reg_addr) \n\t{\n\tcase EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0:\n\tcase EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1:\n\tcase EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2:\n\tcase EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3:\n\tcase EMC_DATA_BRLSHFT_0:\n\t\ttree_delta[0] = (mtc_table_entry->current_dram_clktree_c0d0u0 - mtc_table_entry->trained_dram_clktree_c0d0u0) << 7;\n\t\ttree_delta[1] = (mtc_table_entry->current_dram_clktree_c0d0u1 - mtc_table_entry->trained_dram_clktree_c0d0u1) << 7;\n\t\ttree_delta[2] = (mtc_table_entry->current_dram_clktree_c1d0u0 - mtc_table_entry->trained_dram_clktree_c1d0u0) << 7;\n\t\ttree_delta[3] = (mtc_table_entry->current_dram_clktree_c1d0u1 - mtc_table_entry->trained_dram_clktree_c1d0u1) << 7;\n\t\ttree_delta_taps[0] = (tree_delta[0] * (s32)dst_rate_mhz) / 1000000;\n\t\ttree_delta_taps[1] = (tree_delta[1] * (s32)dst_rate_mhz) / 1000000;\n\t\ttree_delta_taps[2] = (tree_delta[2] * (s32)dst_rate_mhz) / 1000000;\n\t\ttree_delta_taps[3] = (tree_delta[3] * (s32)dst_rate_mhz) / 1000000;\n\t\tfor (s32 i = 0; i < 4; i++)\n\t\t{\n\t\t\tif ((tree_delta_taps[i] > mtc_table_entry->tree_margin) || (tree_delta_taps[i] < (-1 * mtc_table_entry->tree_margin)))\n\t\t\t{\n\t\t\t\tnew_trim[i * 2] += tree_delta_taps[i];\n\t\t\t\tnew_trim[i * 2 + 1] += tree_delta_taps[i];\n\t\t\t}\n\t\t}\n\t\tif (trim_emc_reg_addr == EMC_DATA_BRLSHFT_0)\n\t\t{\n\t\t\tfor (s32 i = 0; i < 8; i++)\n\t\t\t\tnew_trim[i] /= 64;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor (s32 i = 0; i < 8; i++)\n\t\t\t\tnew_trim[i] %= 64;\n\t\t}\n\t\tbreak;\n\tcase EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0:\n\tcase EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1:\n\tcase EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2:\n\tcase EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3:\n\tcase EMC_DATA_BRLSHFT_1:\n\t\ttree_delta[0] = (mtc_table_entry->current_dram_clktree_c0d1u0 - mtc_table_entry->trained_dram_clktree_c0d1u0) << 7;\n\t\ttree_delta[1] = (mtc_table_entry->current_dram_clktree_c0d1u1 - mtc_table_entry->trained_dram_clktree_c0d1u1) << 7;\n\t\ttree_delta[2] = (mtc_table_entry->current_dram_clktree_c1d1u0 - mtc_table_entry->trained_dram_clktree_c1d1u0) << 7;\n\t\ttree_delta[3] = (mtc_table_entry->current_dram_clktree_c1d1u1 - mtc_table_entry->trained_dram_clktree_c1d1u1) << 7;\n\t\ttree_delta_taps[0] = (tree_delta[0] * (s32)dst_rate_mhz) / 1000000;\n\t\ttree_delta_taps[1] = (tree_delta[1] * (s32)dst_rate_mhz) / 1000000;\n\t\ttree_delta_taps[2] = (tree_delta[2] * (s32)dst_rate_mhz) / 1000000;\n\t\ttree_delta_taps[3] = (tree_delta[3] * (s32)dst_rate_mhz) / 1000000;\n\t\tfor (s32 i = 0; i < 4; i++)\n\t\t{\n\t\t\tif ((tree_delta_taps[i] > mtc_table_entry->tree_margin) || (tree_delta_taps[i] < (-1 * mtc_table_entry->tree_margin))) {\n\t\t\t\tnew_trim[8 + i * 2] += tree_delta_taps[i];\n\t\t\t\tnew_trim[8 + i * 2 + 1] += tree_delta_taps[i];\n\t\t\t}\n\t\t}\n\t\tif (trim_emc_reg_addr == EMC_DATA_BRLSHFT_1)\n\t\t{\n\t\t\tfor (s32 i = 0; i < 8; i++)\n\t\t\t\tnew_trim[i + 8] /= 64;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor (s32 i = 0; i < 8; i++)\n\t\t\t\tnew_trim[i + 8] %= 64;\n\t\t}\n\t\tbreak;\n\t}\n\n\tswitch (trim_emc_reg_addr)\n\t{\n\tcase EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0:\n\t\ttrimmer = (new_trim[0] & 0x7FF) | ((new_trim[1] & 0x7FF) << 16);\n\t\tbreak;\n\tcase EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1:\n\t\ttrimmer = (new_trim[2] & 0x7FF) | ((new_trim[3] & 0x7FF) << 16);\n\t\tbreak;\n\tcase EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2:\n\t\ttrimmer = (new_trim[4] & 0x7FF) | ((new_trim[5] & 0x7FF) << 16);\n\t\tbreak;\n\tcase EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3:\n\t\ttrimmer = (new_trim[6] & 0x7FF) | ((new_trim[7] & 0x7FF) << 16);\n\t\tbreak;\n\tcase EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0:\n\t\ttrimmer = (new_trim[8] & 0x7FF) | ((new_trim[9] & 0x7FF) << 16);\n\t\tbreak;\n\tcase EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1:\n\t\ttrimmer = (new_trim[10] & 0x7FF) | ((new_trim[11] & 0x7FF) << 16);\n\t\tbreak;\n\tcase EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2:\n\t\ttrimmer = (new_trim[12] & 0x7FF) | ((new_trim[13] & 0x7FF) << 16);\n\t\tbreak;\n\tcase EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3:\n\t\ttrimmer = (new_trim[14] & 0x7FF) | ((new_trim[15] & 0x7FF) << 16);\n\t\tbreak;\n\tcase EMC_DATA_BRLSHFT_0:\n\t\ttrimmer = (new_trim[0] & 7)\n\t\t\t\t| ((new_trim[1] & 7) << 3)\n\t\t\t\t| ((new_trim[2] & 7) << 6)\n\t\t\t\t| ((new_trim[3] & 7) << 9)\n\t\t\t\t| ((new_trim[4] & 7) << 12)\n\t\t\t\t| ((new_trim[5] & 7) << 15)\n\t\t\t\t| ((new_trim[6] & 7) << 18)\n\t\t\t\t| ((new_trim[7] & 7) << 21);\n\t\tbreak;\n\tcase EMC_DATA_BRLSHFT_1:\n\t\ttrimmer = (new_trim[8] & 7)\n\t\t\t\t| ((new_trim[9] & 7) << 3)\n\t\t\t\t| ((new_trim[10] & 7) << 6)\n\t\t\t\t| ((new_trim[11] & 7) << 9)\n\t\t\t\t| ((new_trim[12] & 7) << 12)\n\t\t\t\t| ((new_trim[13] & 7) << 15)\n\t\t\t\t| ((new_trim[14] & 7) << 18)\n\t\t\t\t| ((new_trim[15] & 7) << 21);\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn trimmer;\n}\n\nstatic bool _check_freq_changed(u32 dst_entry_rate_KHz, u32 dst_entry_clk_src_emc, u32 src_entry_rate_KHz, u32 src_entry_clk_src_emc)\n{\n\tfloat dst_div_clock;\n\tfloat src_div_clock;\n\tfloat src_end_div_clk_ratio;\n\n\tu32 src_entry_emc_2X_clk_src = src_entry_clk_src_emc >> EMC_2X_CLK_SRC_SHIFT;\n\tu32 dst_entry_emc_2X_clk_src = dst_entry_clk_src_emc >> EMC_2X_CLK_SRC_SHIFT;\n\tu32 src_entry_emc_2X_clk_src_div = src_entry_clk_src_emc & 0xFF;\n\tu32 dst_entry_emc_2X_clk_src_div = dst_entry_clk_src_emc & 0xFF;\n\tu32 pll_post_divider = 0;\n\tswitch (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) >> EMC_2X_CLK_SRC_SHIFT)\n\t{\n\t\tcase PLLM_OUT0:\n\t\tcase PLLM_UD:\n\t\t\tpll_post_divider = (CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) >> 20) & 0x1F;\n\t\t\tbreak;\n\t\tcase PLLMB_UD:\n\t\tcase PLLMB_OUT0:\n\t\t\tpll_post_divider = (CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) >> 20) & 0x1F;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\tif (pll_post_divider > 5)\n\t{\n\t\twhile (true)\n\t\t\t;\n\t}\n\n\tif (src_entry_emc_2X_clk_src <= PLLMB_UD)\n\t\tsrc_entry_emc_2X_clk_src_div = 0;\n\tif (dst_entry_emc_2X_clk_src <= PLLMB_UD)\n\t\tdst_entry_emc_2X_clk_src_div = 0;\n\n\tif (dst_entry_emc_2X_clk_src != src_entry_emc_2X_clk_src && (dst_entry_emc_2X_clk_src & 0xFFFFFFFB || src_entry_emc_2X_clk_src & 0xFFFFFFFB))\n\t\treturn true;\n\n\tdst_div_clock = (double)dst_entry_rate_KHz\n\t\t* ((double)((dst_entry_emc_2X_clk_src_div >> 1) + 1)\n\t\t+ (double)(dst_entry_emc_2X_clk_src_div & 1) * 0.5)\n\t\t* (double)(pll_post_divider + 1);\n\tsrc_div_clock = (double)src_entry_rate_KHz\n\t\t* ((double)((src_entry_emc_2X_clk_src_div >> 1) + 1)\n\t\t+ (double)(src_entry_emc_2X_clk_src_div & 1) * 0.5)\n\t\t* (double)(pll_post_divider + 1);\n\n\tsrc_end_div_clk_ratio = src_div_clock / dst_div_clock;\n\n\tif (src_end_div_clk_ratio > 1.01f || src_end_div_clk_ratio < 0.99f)\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\nstatic void _save_train_results(emc_table_t *mtc_table_entry, u32 needs_training, s32 dram_dev_num, bool channel1_enabled)\n{\n\tbool needs_ca_training = needs_training & 1;\n\tbool needs_ca_vref_training = (needs_training >> 1) & 1;\n\tbool needs_quse_training = (needs_training >> 2) & 1;\n\tbool needs_quse_vref_training = (needs_training >> 3) & 1;\n\tbool needs_wr_training = (needs_training >> 4) & 1;\n\tbool needs_wr_vref_training = (needs_training >> 5) & 1;\n\tbool needs_rd_training = (needs_training >> 6) & 1;\n\tbool needs_rd_vref_training = (needs_training >> 7) & 1;\n\tbool needs_training_in_self_refresh = (needs_training >> 9) & 1;\n\n\tif (needs_ca_training)\n\t{\n\t\tmtc_table_entry->trim_perch_regs.emc_cmd_brlshft_0_idx = EMC_CH0(EMC_CMD_BRLSHFT_0);\n\t\tmtc_table_entry->trim_perch_regs.emc_cmd_brlshft_1_idx = channel1_enabled ? EMC_CH1(EMC_CMD_BRLSHFT_1) : 0;\n\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_4_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4);\n\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_5_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5) : 0;\n\n\t\tif (needs_training_in_self_refresh)\n\t\t{\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd0_0_idx = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_0);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd0_1_idx = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_1);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd0_2_idx = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_2);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd1_0_idx = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_0);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd1_1_idx = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_1);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd1_2_idx = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_2);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd2_0_idx = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_0);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd2_1_idx = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_1);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd2_2_idx = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_2);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd3_0_idx = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_0);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd3_1_idx = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_1);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd3_2_idx = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_2);\n\t\t}\n\t}\n\n\tif (needs_ca_vref_training)\n\t{\n\t\tmtc_table_entry->burst_reg_per_ch.emc0_mrw10_idx = (EMC_CH0(EMC_TRAINING_OPT_CA_VREF) & 0xFFFF) | 0x880C0000;\n\t\tmtc_table_entry->burst_reg_per_ch.emc1_mrw10_idx = (channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_CA_VREF) & 0xFFFF : 0) | 0x880C0000;\n\n\t\tu32 mrw11_dev_selectn = 0;\n\t\tif (dram_dev_num == TWO_RANK)\n\t\t\tmrw11_dev_selectn = 0x480C0000;\n\t\telse\n\t\t\tmrw11_dev_selectn = 0xC80C0000;\n\n\t\tmtc_table_entry->burst_reg_per_ch.emc0_mrw11_idx = \n\t\t\t((EMC_CH0(EMC_TRAINING_OPT_CA_VREF) >> 16) & 0xFF)\n\t\t\t| (EMC_CH0(EMC_TRAINING_OPT_CA_VREF) >> 24 << 8)\n\t\t\t| (mrw11_dev_selectn & 0xFFFFFF00);\n\n\t\tmtc_table_entry->burst_reg_per_ch.emc1_mrw11_idx =\n\t\t\t(((channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_CA_VREF) : 0) >> 16) & 0xFF)\n\t\t\t| ((channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_CA_VREF) : 0) >> 24 << 8)\n\t\t\t| (mrw11_dev_selectn & 0xFFFFFF00);\n\t}\n\n\tif (needs_quse_training || needs_rd_training)\n\t{\n\t\tmtc_table_entry->trim_perch_regs.emc_quse_brlshft_0_idx = EMC_CH0(EMC_QUSE_BRLSHFT_0);\n\t\tmtc_table_entry->trim_perch_regs.emc_quse_brlshft_1_idx = channel1_enabled ? EMC_CH1(EMC_QUSE_BRLSHFT_1) : 0;\n\n\t\tmtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank0_0_idx = EMC_CH0(EMC_PMACRO_QUSE_DDLL_RANK0_0);\n\t\tmtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank0_1_idx = EMC_CH0(EMC_PMACRO_QUSE_DDLL_RANK0_1);\n\t\tmtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank0_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_QUSE_DDLL_RANK0_2) : 0;\n\t\tmtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank0_3_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_QUSE_DDLL_RANK0_3) : 0;\n\n\t\tif (dram_dev_num == TWO_RANK)\n\t\t{\n\t\t\tmtc_table_entry->trim_perch_regs.emc_quse_brlshft_2_idx = EMC_CH0(EMC_QUSE_BRLSHFT_2);\n\t\t\tmtc_table_entry->trim_perch_regs.emc_quse_brlshft_3_idx = channel1_enabled ? EMC_CH1(EMC_QUSE_BRLSHFT_3) : 0;\n\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank1_0_idx = EMC_CH0(EMC_PMACRO_QUSE_DDLL_RANK1_0);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank1_1_idx = EMC_CH0(EMC_PMACRO_QUSE_DDLL_RANK1_1);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank1_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_QUSE_DDLL_RANK1_2) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank1_3_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_QUSE_DDLL_RANK1_3) : 0;\n\t\t}\n\t}\n\n\tif (needs_quse_vref_training)\n\t{\n\t\tif (dram_dev_num == TWO_RANK)\n\t\t{\n\t\t\tu32 emc0_opt_dqs_array[4] = {0};\n\t\t\tu32 emc1_opt_dqs_array[4] = {0};\n\t\t\tu32 emc1_training_opt_dqs_ib_vref_rank0_val = channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_DQS_IB_VREF_RANK0) : 0;\n\t\t\tu32 emc1_training_opt_dqs_ib_vref_rank1_val = channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_DQS_IB_VREF_RANK1) : 0;\n\n\t\t\tfor (u32 i = 0; i < 4; i++)\n\t\t\t{\n\t\t\t\temc0_opt_dqs_array[i] = (EMC_CH0(EMC_TRAINING_OPT_DQS_IB_VREF_RANK0) >> (8 * i)) & 0xFF;\n\t\t\t\temc1_opt_dqs_array[i] = (emc1_training_opt_dqs_ib_vref_rank0_val >> (8 * i)) & 0xFF;\n\t\t\t}\n\n\t\t\tu32 ib_vref_dqs_0 = 0;\n\t\t\tu32 ib_vref_dqs_1 = 0;\n\t\t\tfor (u32 i = 0; i < 4; i++)\n\t\t\t{\n\t\t\t\tib_vref_dqs_0 |= (emc0_opt_dqs_array[i] + ((EMC_CH0(EMC_TRAINING_OPT_DQS_IB_VREF_RANK1) >> (8 * i)) & 0xFF)) >> 1 << (8 * i);\n\t\t\t\tib_vref_dqs_1 |= (emc1_opt_dqs_array[i] + ((emc1_training_opt_dqs_ib_vref_rank1_val >> (8 * i)) & 0xFF)) >> 1 << (8 * i);\n\t\t\t}\n\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_vref_dqs_0_idx = ib_vref_dqs_0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_vref_dqs_1_idx = ib_vref_dqs_1;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_vref_dqs_0_idx = EMC(EMC_PMACRO_IB_VREF_DQS_0);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_vref_dqs_1_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_VREF_DQS_1) : 0;\n\t\t}\n\t}\n\n\tif (needs_rd_training)\n\t{\n\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank0_0_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0);\n\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank0_1_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1);\n\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank0_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2) : 0;\n\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank0_3_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3) : 0;\n\n\t\tif (dram_dev_num == TWO_RANK)\n\t\t{\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank1_0_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank1_1_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank1_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank1_3_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) : 0;\n\t\t}\n\n\t\tif (needs_training_in_self_refresh)\n\t\t{\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte0_0_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_0);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte0_1_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_1);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte0_2_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_2);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte1_0_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_0);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte1_1_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_1);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte1_2_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_2);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte2_0_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_0);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte2_1_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_1);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte2_2_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_2);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte3_0_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_0);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte3_1_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_1);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte3_2_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_2);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte4_0_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_0) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte4_1_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_1) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte4_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_2) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte5_0_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_0) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte5_1_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_1) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte5_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_2) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte6_0_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_0) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte6_1_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_1) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte6_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_2) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte7_0_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_0) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte7_1_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_1) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte7_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_2) : 0;\n\n\t\t\tif (dram_dev_num == TWO_RANK)\n\t\t\t{\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte0_0_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_0);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte0_1_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_1);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte0_2_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_2);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte1_0_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_0);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte1_1_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_1);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte1_2_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_2);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte2_0_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_0);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte2_1_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_1);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte2_2_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_2);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte3_0_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_0);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte3_1_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_1);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte3_2_idx = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_2);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte4_0_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_0) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte4_1_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_1) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte4_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_2) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte5_0_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_0) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte5_1_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_1) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte5_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_2) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte6_0_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_0) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte6_1_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_1) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte6_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_2) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte7_0_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_0) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte7_1_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_1) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte7_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_2) : 0;\n\t\t\t}\n\t\t}\n\n\t\tif (needs_rd_vref_training)\n\t\t{\n\t\t\tchar ib_vref_dq_byte0_icr = (EMC(EMC_PMACRO_IB_VREF_DQ_0) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[0] & 0x7F);\n\t\t\tif (mtc_table_entry->save_restore_mod_regs[0] & 0x80000000) // < 0 check.\n\t\t\t\tib_vref_dq_byte0_icr = (EMC(EMC_PMACRO_IB_VREF_DQ_0) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[0] & 0x7F);\n\n\t\t\tchar ib_vref_dq_byte1_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 8) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[1] & 0x7F);\n\t\t\tif (mtc_table_entry->save_restore_mod_regs[1] & 0x80000000)\n\t\t\t\tib_vref_dq_byte1_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 8) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[1] & 0x7F);\n\n\t\t\tchar ib_vref_dq_byte2_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 16) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[2] & 0x7F);\n\t\t\tif (mtc_table_entry->save_restore_mod_regs[2] & 0x80000000)\n\t\t\t\tib_vref_dq_byte2_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 16) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[2] & 0x7F);\n\n\t\t\tchar ib_vref_dq_byte3_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 24) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[3] & 0x7F);\n\t\t\tif (mtc_table_entry->save_restore_mod_regs[3] & 0x80000000)\n\t\t\t\tib_vref_dq_byte3_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 24) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[3] & 0x7F);\n\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_vref_dq_0_idx = \n\t\t\t\t ((ib_vref_dq_byte0_icr & 0x7F)\n\t\t\t\t| (ib_vref_dq_byte1_icr & 0x7F) << 8)\n\t\t\t\t| ((ib_vref_dq_byte2_icr & 0x7F) << 16)\n\t\t\t\t| ((ib_vref_dq_byte3_icr & 0x7F) << 24);\n\t\t\t\n\t\t\tchar ib_vref_dq_byte4_icr = (EMC(EMC_PMACRO_IB_VREF_DQ_1) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[4] & 0x7F);\n\t\t\tif (mtc_table_entry->save_restore_mod_regs[4] & 0x80000000)\n\t\t\t\tib_vref_dq_byte4_icr = (EMC(EMC_PMACRO_IB_VREF_DQ_1) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[4] & 0x7F);\n\n\t\t\tchar ib_vref_dq_byte5_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 8) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[5] & 0x7F);\n\t\t\tif (mtc_table_entry->save_restore_mod_regs[5] & 0x80000000)\n\t\t\t\tib_vref_dq_byte5_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 8) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[5] & 0x7F);\n\n\t\t\tchar ib_vref_dq_byte6_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 16) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[6] & 0x7F);\n\t\t\tif (mtc_table_entry->save_restore_mod_regs[6] & 0x80000000)\n\t\t\t\tib_vref_dq_byte6_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 16) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[6] & 0x7F);\n\n\t\t\tchar ib_vref_dq_byte7_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 24) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[7] & 0x7F);\n\t\t\tif (mtc_table_entry->save_restore_mod_regs[7] & 0x80000000)\n\t\t\t\tib_vref_dq_byte7_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 24) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[7] & 0x7F);\n\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ib_vref_dq_1_idx =\n\t\t\t\t ((ib_vref_dq_byte4_icr & 0x7F)\n\t\t\t\t| (ib_vref_dq_byte5_icr & 0x7F) << 8)\n\t\t\t\t| ((ib_vref_dq_byte6_icr & 0x7F) << 16)\n\t\t\t\t| ((ib_vref_dq_byte7_icr & 0x7F) << 24);\n\t\t}\n\t}\n\n\tif (needs_wr_training)\n\t{\n\t\tmtc_table_entry->trim_perch_regs.emc0_data_brlshft_0_idx = EMC_CH0(EMC_DATA_BRLSHFT_0);\n\t\tmtc_table_entry->trim_perch_regs.emc1_data_brlshft_0_idx = channel1_enabled ? EMC_CH1(EMC_DATA_BRLSHFT_0) : 0;\n\n\t\tif (dram_dev_num == TWO_RANK)\n\t\t{\n\t\t\tmtc_table_entry->trim_perch_regs.emc0_data_brlshft_1_idx = EMC_CH0(EMC_DATA_BRLSHFT_1);\n\t\t\tmtc_table_entry->trim_perch_regs.emc1_data_brlshft_1_idx = channel1_enabled ? EMC_CH1(EMC_DATA_BRLSHFT_1) : 0;\n\t\t}\n\n\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_0_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0);\n\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_1_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1);\n\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2) : 0;\n\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_3_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3) : 0;\n\n\t\tif (dram_dev_num == TWO_RANK)\n\t\t{\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank1_0_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank1_1_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank1_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank1_3_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3) : 0;\n\t\t}\n\n\t\tif (needs_training_in_self_refresh)\n\t\t{\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte0_0_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_0);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte0_1_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_1);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte0_2_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_2);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte1_0_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_0);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte1_1_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_1);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte1_2_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_2);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte2_0_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_0);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte2_1_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_1);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte2_2_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_2);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte3_0_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_0);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte3_1_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_1);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte3_2_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_2);\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte4_0_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_0) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte4_1_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_1) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte4_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_2) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte5_0_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_0) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte5_1_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_1) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte5_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_2) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte6_0_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_0) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte6_1_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_1) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte6_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_2) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte7_0_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_0) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte7_1_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_1) : 0;\n\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte7_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_2) : 0;\n\n\t\t\tif (dram_dev_num == TWO_RANK)\n\t\t\t{\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte0_0_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_0);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte0_1_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_1);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte0_2_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_2);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte1_0_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_0);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte1_1_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_1);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte1_2_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_2);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte2_0_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_0);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte2_1_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_1);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte2_2_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_2);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte3_0_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_0);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte3_1_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_1);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte3_2_idx = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_2);\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte4_0_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_0) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte4_1_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_1) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte4_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_2) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte5_0_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_0) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte5_1_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_1) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte5_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_2) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte6_0_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_0) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte6_1_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_1) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte6_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_2) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte7_0_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_0) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte7_1_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_1) : 0;\n\t\t\t\tmtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte7_2_idx = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_2) : 0;\n\t\t\t}\n\t\t}\n\n\t\tif (needs_wr_vref_training) // mode 12/13 (MRW).\n\t\t{\n\t\t\tu32 emc1_ranks_sub_partitions = 0;\n\t\t\temc1_ranks_sub_partitions = channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_DQ_OB_VREF) : 0;\n\n\t\t\tu8 emc0_ib_vref_dq_byte8_modded_plus = mtc_table_entry->save_restore_mod_regs[8] + EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF);\n\t\t\tif (mtc_table_entry->save_restore_mod_regs[8] & 0x80000000) // < 0 check.\n\t\t\t\temc0_ib_vref_dq_byte8_modded_plus = EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) - mtc_table_entry->save_restore_mod_regs[8];\n\n\t\t\tu8 emc0_mrw12_op_sp1 = ((EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) & 0xFFFF) >> 8) + mtc_table_entry->save_restore_mod_regs[9];\n\t\t\tif (mtc_table_entry->save_restore_mod_regs[9] & 0x80000000)\n\t\t\t\temc0_mrw12_op_sp1 = ((EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) & 0xFFFF) >> 8) - mtc_table_entry->save_restore_mod_regs[9];\n\n\t\t\tu8 emc0_mrw13_op_sp0 = ((EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) >> 16) & 0xFF) + mtc_table_entry->save_restore_mod_regs[8];\n\t\t\tif (mtc_table_entry->save_restore_mod_regs[8] & 0x80000000)\n\t\t\t\temc0_mrw13_op_sp0 = ((EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) >> 16) & 0xFF) - mtc_table_entry->save_restore_mod_regs[8];\n\n\t\t\tu8 emc0_ib_vref_dq_byte9_modded_a_plus = mtc_table_entry->save_restore_mod_regs[9] + (EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) >> 24);\n\t\t\tif (mtc_table_entry->save_restore_mod_regs[9] & 0x80000000)\n\t\t\t\temc0_ib_vref_dq_byte9_modded_a_plus = (EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) >> 24) - (u8)mtc_table_entry->save_restore_mod_regs[9];\n\n\t\t\tu8 emc0_ib_vref_dq_byte10_modded_plus = emc1_ranks_sub_partitions + mtc_table_entry->save_restore_mod_regs[10];\n\t\t\tif (mtc_table_entry->save_restore_mod_regs[10] & 0x80000000)\n\t\t\t\temc0_ib_vref_dq_byte10_modded_plus = emc1_ranks_sub_partitions - mtc_table_entry->save_restore_mod_regs[10];\n\n\t\t\tu8 emc0_ib_vref_dq_byte11_modded_plus = ((emc1_ranks_sub_partitions & 0xFFFF) >> 8) + mtc_table_entry->save_restore_mod_regs[11];\n\t\t\tif (mtc_table_entry->save_restore_mod_regs[11] & 0x80000000)\n\t\t\t\temc0_ib_vref_dq_byte11_modded_plus = ((emc1_ranks_sub_partitions & 0xFFFF) >> 8) - mtc_table_entry->save_restore_mod_regs[11];\n\n\t\t\tu8 emc1_mrw13_op_sp0 = ((emc1_ranks_sub_partitions >> 16) & 0xFF) + mtc_table_entry->save_restore_mod_regs[10];\n\t\t\tif (mtc_table_entry->save_restore_mod_regs[10] & 0x80000000)\n\t\t\t\temc1_mrw13_op_sp0 = ((emc1_ranks_sub_partitions >> 16) & 0xFF) - mtc_table_entry->save_restore_mod_regs[10];\n\n\t\t\tu8 emc1_mrw13_op_sp1 = (emc1_ranks_sub_partitions >> 24) + mtc_table_entry->save_restore_mod_regs[11];\n\t\t\tif (mtc_table_entry->save_restore_mod_regs[11] & 0x80000000)\n\t\t\t\temc1_mrw13_op_sp1 = (emc1_ranks_sub_partitions >> 24) - mtc_table_entry->save_restore_mod_regs[11];\n\n\t\t\tu32 mr13_dev_ext_cnt_sp_addr = 0xC80E0000;\n\t\t\tif (dram_dev_num == TWO_RANK)\n\t\t\t\tmr13_dev_ext_cnt_sp_addr = 0x480E0000;\n\n\t\t\tmtc_table_entry->burst_reg_per_ch.emc1_mrw12_idx = (u8)emc0_ib_vref_dq_byte10_modded_plus | 0x880E0000 | (emc0_ib_vref_dq_byte11_modded_plus << 8);\n\t\t\tmtc_table_entry->burst_reg_per_ch.emc0_mrw12_idx = emc0_ib_vref_dq_byte8_modded_plus | 0x880E0000 | (emc0_mrw12_op_sp1 << 8);\n\t\t\tmtc_table_entry->burst_reg_per_ch.emc0_mrw13_idx = emc0_ib_vref_dq_byte9_modded_a_plus << 8 | emc0_mrw13_op_sp0 | mr13_dev_ext_cnt_sp_addr;\n\t\t\tmtc_table_entry->burst_reg_per_ch.emc1_mrw13_idx = (emc1_mrw13_op_sp1 << 8) | emc1_mrw13_op_sp0 | mr13_dev_ext_cnt_sp_addr;\n\t\t\t\n\t\t}\n\t}\n}\n\ns32 _minerva_set_clock(emc_table_t *src_emc_entry, emc_table_t *dst_emc_entry, u32 needs_training, u32 selected_clk_src_emc)\n{\n\tu32 emc_dbg_o;\n\tu32 emc_pin_o;\n\tu32 emc_cfg_pipe_clk_o;\n\tu32 emc_sel_dpd_ctrl;\n\tu32 emc_cfg;\n\tu32 emc_dbg_val;\n\tu32 emc_zq_cal = 0;\n\tu32 ramp_up_wait;\n\tu32 ramp_down_wait;\n\tu32 bg_regulator_mode_change;\n\tu32 mr13_flip_fspop = 0;\n\tu32 mr13_flip_fspwr = 0; //float\n\tu32 mr13_catr_enable; //float\n\tbool opt_zcal_en_cc;\n\n\t/* needs_training LOBYTE table var */\n\t/*\n\t | bit | Description                |\n\t |-----|----------------------------|\n\t |  0  | Needs CA        training   |\n\t |  1  | Needs CA_VREF   training   |\n\t |  2  | Needs QUSE      training   |\n\t |  3  | Needs QUSE_VREF training   |\n\t |  4  | Needs WR        training   |\n\t |  5  | Needs WR_VREF   training   |\n\t |  6  | Needs RD        training   |\n\t |  7  | Needs RD_VREF   training   |\n\t */\n\t\n\tbool opt_dll_mode = false;\n\tbool is_lpddr3_dram = false;\n\tbool compensate_trimmer_applicable = false;\n\tbool needs_ca_or_cavref_training = (needs_training & 3) != 0;\n\tbool needs_tristate_training = (needs_training & 0xF7) != 0;\n\tbool needs_ca_training = needs_training & 1;\n\tbool needs_ca_vref_training = (needs_training >> 1) & 1;\n\tbool needs_quse_training = (needs_training >> 2) & 1;\n\tbool needs_quse_vref_training = (needs_training >> 3) & 1;\n\tbool needs_wr_training = (needs_training >> 4) & 1;\n\tbool needs_wr_vref_training = (needs_training >> 5) & 1;\n\tbool needs_rd_training = (needs_training >> 6) & 1;\n\tbool needs_rd_vref_training = (needs_training >> 7) & 1;\n\tbool needs_swap_rank_training = (needs_training >> 8) & 1;\n\n\tbool zcal_resistor_shared = (src_emc_entry->burst_regs.emc_zcal_wait_cnt_idx >> 31) & 1;\n\tbool enable_bg_regulator = (dst_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0_idx & 1) ^ 1;\n\tbool channel1_enabled = (src_emc_entry->burst_regs.emc_fbio_cfg7_idx >> 2) & 1;\n\ts32  dram_type = EMC(EMC_FBIO_CFG5) & 3;\n\ts32  dram_dev_num = (MC(MC_EMEM_ADR_CFG) & 1) + 1;\n\t\n\tfloat src_clock_period = 1000000.0 / (double)src_emc_entry->rate_khz;\n\tfloat dst_clock_period = 1000000.0 / (double)dst_emc_entry->rate_khz;\n\n\tfsp_for_src_freq = !fsp_for_src_freq;\n\t\n\tif (dst_emc_entry->burst_regs.emc_zcal_interval_idx && !src_emc_entry->burst_regs.emc_zcal_interval_idx)\n\t\topt_zcal_en_cc = true;\n\telse\n\t\topt_zcal_en_cc = dram_type == DRAM_TYPE_LPDDR4;\n\n\tswitch(dram_type)\n\t{\n\tcase DRAM_TYPE_DDR2:\n\tcase DRAM_TYPE_LPDDR4:\n\t\tbreak;\n\tcase DRAM_TYPE_DDR3:\n\t\topt_dll_mode = (dst_emc_entry->emc_emrs & 1) ^ 1;\n\t\tbreak;\n\t\n\tcase DRAM_TYPE_LPDDR2:\n\t\tif ((dst_emc_entry->burst_regs.emc_fbio_cfg5_idx >> 25) & 1) //LPDDR3_DRAM bit\n\t\t\tis_lpddr3_dram = true;\n\t\tbreak;\n\t}\n\n\tu32 tFC_lpddr4 = dst_emc_entry->dram_timings.t_fc_lpddr4;\n\tfloat tZQCAL_lpddr4 = 1000.0f;\n\tif (src_clock_period <= 2.0)\n\t\ttZQCAL_lpddr4 = (float)(1000 - tFC_lpddr4);\n\ts32 tZQCAL_lpddr4_fc_adj = (s32)(float)(tZQCAL_lpddr4 / dst_clock_period);\n\n\t// Step 1 - Pre DVFS SW sequence.\n\tEPRINTF(\"Step 1\");\n\temc_dbg_o = EMC(EMC_DBG);\n\temc_pin_o = EMC(EMC_PIN);\n\temc_cfg = dst_emc_entry->burst_regs.emc_cfg_idx & 0xFFFFFFF;\n\temc_sel_dpd_ctrl = dst_emc_entry->emc_sel_dpd_ctrl & 0xFFFFFEC3;\n\temc_cfg_pipe_clk_o = EMC(EMC_CFG_PIPE_CLK);\n\t_digital_dll_disable();\n\n\t// Step 1.2 - Disable AUTOCAL temporarily.\n\tEPRINTF(\"Step 1.2\");\n\tEMC(EMC_AUTO_CAL_CONFIG) = (dst_emc_entry->emc_auto_cal_config & 0x7FFFF9FF) | 0x600;\n\n\t// Step 1.3 - Disable other power features.\n\tEPRINTF(\"Step 1.3\");\n\tEMC(EMC_DBG) = emc_dbg_o | 2;\n\tEMC(EMC_CFG) = emc_cfg;\n\tEMC(EMC_SEL_DPD_CTRL) = emc_sel_dpd_ctrl;\n\tEMC(EMC_DBG) = emc_dbg_o;\n\t\n\tif (!needs_tristate_training && dst_emc_entry->periodic_training)\n\t{\n\t\tif (dram_dev_num == TWO_RANK)\n\t\t{\n\t\t\t_wait_emc_status(EMC_EMC_STATUS, IN_POWERDOWN_MASK, false, EMC_CH0);\n\t\t\tif (channel1_enabled)\n\t\t\t\t_wait_emc_status(EMC_EMC_STATUS, IN_POWERDOWN_MASK, false, channel1_enabled);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t_wait_emc_status(EMC_EMC_STATUS, 0x10, false, EMC_CH0);\n\t\t\tif (channel1_enabled)\n\t\t\t\t_wait_emc_status(EMC_EMC_STATUS, 0x10, false, channel1_enabled);\n\t\t}\n\n\t\t_wait_emc_status(EMC_EMC_STATUS, IN_SELF_REFRESH_MASK, false, EMC_CH0);\n\t\tif (channel1_enabled)\n\t\t\t_wait_emc_status(EMC_EMC_STATUS, IN_SELF_REFRESH_MASK, false, channel1_enabled);\n\n\t\t// Reset clock tree delays.\n\t\tdst_emc_entry->current_dram_clktree_c0d0u0 = dst_emc_entry->trained_dram_clktree_c0d0u0;\n\t\tdst_emc_entry->current_dram_clktree_c0d0u1 = dst_emc_entry->trained_dram_clktree_c0d0u1;\n\t\tdst_emc_entry->current_dram_clktree_c0d1u0 = dst_emc_entry->trained_dram_clktree_c0d1u0;\n\t\tdst_emc_entry->current_dram_clktree_c0d1u1 = dst_emc_entry->trained_dram_clktree_c0d1u1;\n\t\tdst_emc_entry->current_dram_clktree_c1d0u0 = dst_emc_entry->trained_dram_clktree_c1d0u0;\n\t\tdst_emc_entry->current_dram_clktree_c1d0u1 = dst_emc_entry->trained_dram_clktree_c1d0u1;\n\t\tdst_emc_entry->current_dram_clktree_c1d1u0 = dst_emc_entry->trained_dram_clktree_c1d1u0;\n\t\tdst_emc_entry->current_dram_clktree_c1d1u1 = dst_emc_entry->trained_dram_clktree_c1d1u1;\n\n\t\tu32 adel = _minerva_periodic_compensation_handler(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, DVFS_SEQUENCE);\n\n\t\tif (((dst_emc_entry->rate_khz / 1000) << 7) * adel / 1000000 > dst_emc_entry->tree_margin)\n\t\t\tcompensate_trimmer_applicable = true;\n\t}\n\n\tEMC(EMC_INTSTATUS) = CLKCHANGE_COMPLETE_INT;\n\tEMC(EMC_DBG) = emc_dbg_o | 2;\n\tEMC(EMC_CFG) = emc_cfg;\n\tEMC(EMC_SEL_DPD_CTRL) = emc_sel_dpd_ctrl;\n\tEMC(EMC_CFG_PIPE_CLK) = emc_cfg_pipe_clk_o | 1; // CLK_ALWAYS_ON.\n\tEMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = dst_emc_entry->emc_fdpd_ctrl_cmd_no_ramp & 0xFFFFFFFE;\n\n\tbg_regulator_mode_change = src_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0_idx ^ dst_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0_idx;\n\tbg_regulator_mode_change = (bg_regulator_mode_change | (bg_regulator_mode_change >> 2)) & 1;\n\n\tif (bg_regulator_mode_change)\n\t{\n\t\tEMC(EMC_DBG) = emc_dbg_o | 2;\n\t\tif (enable_bg_regulator)\n\t\t\tEMC(EMC_PMACRO_BG_BIAS_CTRL_0) = src_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0_idx & 0xFFFFFFFE;\n\t\telse\n\t\t\tEMC(EMC_PMACRO_BG_BIAS_CTRL_0) = src_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0_idx & 0xFFFFFFFB;\n\t}\n\n\t// Check if we need to turn on VREF generator.\n\tif ((!(src_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl_idx & 0x100)\n\t\t&& (dst_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl_idx & 0x100))\n\t\t|| (!(src_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl_idx & 1) \n\t\t&& (dst_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl_idx & 1)))\n\t{\n\t\tEMC(EMC_PMACRO_DATA_PAD_TX_CTRL) =\n\t\t\t(((dst_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl_idx & 1) | (src_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl_idx & 0xFFFFFFFE)) & 0xFFFFFEFF)\n\t\t\t| (((dst_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl_idx >> 8) & 0x1) << 8);\n\t\t_usleep(1);\n\t}\n\telse if (bg_regulator_mode_change)\n\t\t_usleep(1);\n\n\tEMC(EMC_DBG) = emc_dbg_o;\n\n\t// Step 2 - Prelock the DLL.\n\tEPRINTF(\"Step 2\");\n\tif (dst_emc_entry->burst_regs.emc_cfg_dig_dll_idx & 1)\n\t\t_digital_dll_prelock(dst_emc_entry, needs_tristate_training, selected_clk_src_emc); //Prelock enabled for target frequency.\n\telse\n\t{\n\t\t_change_dll_src(dst_emc_entry, selected_clk_src_emc);\n\t\t_digital_dll_disable(); // Disabling DLL for target frequency.\n\t}\n\n\t// Step 3 - Prepare autocal for the clock change.\n\tEPRINTF(\"Step 3\");\n\tEMC(EMC_AUTO_CAL_CONFIG) = (dst_emc_entry->emc_auto_cal_config & 0x7FFFF9FF) | 0x600;\n\tEMC(EMC_DBG) = emc_dbg_o | 2;\n\tEMC(EMC_AUTO_CAL_CONFIG2) = dst_emc_entry->emc_auto_cal_config2;\n\tEMC(EMC_AUTO_CAL_CONFIG3) = dst_emc_entry->emc_auto_cal_config3;\n\tEMC(EMC_AUTO_CAL_CONFIG4) = dst_emc_entry->emc_auto_cal_config4;\n\tEMC(EMC_AUTO_CAL_CONFIG5) = dst_emc_entry->emc_auto_cal_config5;\n\tEMC(EMC_AUTO_CAL_CONFIG6) = dst_emc_entry->emc_auto_cal_config6;\n\tEMC(EMC_AUTO_CAL_CONFIG7) = dst_emc_entry->emc_auto_cal_config7;\n\tEMC(EMC_AUTO_CAL_CONFIG8) = dst_emc_entry->emc_auto_cal_config8;\n\tEMC(EMC_DBG) = emc_dbg_o;\n\tEMC(EMC_AUTO_CAL_CONFIG) = (dst_emc_entry->emc_auto_cal_config & 0x7FFFF9FE) | 0x601;\n\n\t// Step 4 - Update EMC_CFG.\n\tEPRINTF(\"Step 4\");\n\tif (src_clock_period <= 50.0f || dram_type != 1)\n\t\tEMC(EMC_CFG_2) = dst_emc_entry->emc_cfg_2;\n\telse\n\t\t_ccfifo_write(EMC_SELF_REF, 1, 0);\n\n\t// Step 5 - Prepare reference variables for ZQCAL regs.\n\tEPRINTF(\"Step 5\");\n\t// u32 zq_wait_long = 0;\n\t// u32 zq_wait_short = 0;\n\n\t// if (dram_type == DRAM_TYPE_LPDDR4)\n\t// \tzq_wait_long = _fceil(1000.0f / dst_clock_period);\n\t// else if (is_lpddr3_dram || dram_type == DRAM_TYPE_LPDDR2)\n\t// \tzq_wait_long = _fceil(360.0f / dst_clock_period);\n\t// else if (!dram_type)\n\t// \tzq_wait_long = _fceil(320.0f / dst_clock_period);\n\n\t// if (is_lpddr3_dram || dram_type == DRAM_TYPE_LPDDR2)\n\t// \tzq_wait_short = _fceil(90.0f / dst_clock_period);\n\t// else if (!dram_type)\n\t// \tzq_wait_short = _fceil(80.0f / dst_clock_period);\n\n\t// Step 7 - Bug 200024907 - Patch RP R2P.\n\tEPRINTF(\"Step 7\");\n\tif (needs_ca_or_cavref_training && dram_dev_num == TWO_RANK)\n\t\tEMC(EMC_PIN) = 0x107;\n\n\tif (dram_type == DRAM_TYPE_LPDDR4)\n\t{\n\t\tu32 R2P_war = 0;\n\t\tu32 TRPab_war = 0;\n\t\tu32 RP_war = 0;\n\t\tu32 W2P_war = 0;\n\n\t\ts32 nRTP = 8;  // <= 1066MHz.\n\t\tif (src_clock_period < 3.7593985           // 1000 / 266MHz.\n\t\t\t\t&& src_clock_period < 1.87617261   // 1000 / 533MHz.\n\t\t\t\t&& src_clock_period < 1.25         // 1000 / 800MHz.\n\t\t\t\t&& src_clock_period < 0.938086304) // 1000 / 1066MHz.\n\t\t\tnRTP = 10; // 1067MHz < x <= 1333MHz.\n\t\tif (src_clock_period < 0.750187547)        // 1000 / 1333MHz.\n\t\t\tnRTP = 12; // 1333MHz < x <= 1333MHz.\n\t\tif (src_clock_period < 0.625)              // 1000 / 1600MHz.\n\t\t\tnRTP = 14; // 1600MHz < x <= 1866MHz.\n\t\tif (src_clock_period < 0.535905681)        // 1000 / 1866MHz.\n\t\t\tnRTP = 16; // > 1866MHz\n\t\t\n\t\tfloat tRPST = (float)((src_emc_entry->emc_mrw >> 7) & 1) + 0.5f;\n\n\t\ts32 deltaTWATM = _fceil(7.5f / src_clock_period);\n\t\tif (deltaTWATM < 8)\n\t\t\tdeltaTWATM = 8;\n\n\t\tu32 tRTM = (u32)_fceil((float)((((float)src_emc_entry->dram_timings.rl + _fceil(3.6f / src_clock_period) + (float)deltaTWATM) + tRPST) + (float)nRTP));\n\n\t\tif (tRTM <= src_emc_entry->burst_regs.emc_rp_idx + src_emc_entry->burst_regs.emc_r2p_idx)\n\t\t{\n\t\t\tTRPab_war = src_emc_entry->burst_regs.emc_trpab_idx;\n\t\t\tR2P_war = src_emc_entry->burst_regs.emc_r2p_idx;\n\t\t\tRP_war = src_emc_entry->burst_regs.emc_rp_idx;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tR2P_war = tRTM - src_emc_entry->burst_regs.emc_rp_idx;\n\t\t\tTRPab_war = src_emc_entry->burst_regs.emc_trpab_idx;\n\t\t\tRP_war = src_emc_entry->burst_regs.emc_rp_idx;\n\t\t\tif (R2P_war > 63)\n\t\t\t{\n\t\t\t\tRP_war = tRTM - 63;\n\t\t\t\tR2P_war = 63;\n\t\t\t\tif (src_emc_entry->burst_regs.emc_trpab_idx < tRTM - 63)\n\t\t\t\t\tTRPab_war = tRTM - 63;\n\t\t\t\telse\n\t\t\t\t\tTRPab_war = src_emc_entry->burst_regs.emc_trpab_idx;\n\t\t\t}\n\t\t}\n\n\t\tif (RP_war >= deltaTWATM)\n\t\t\tW2P_war = src_emc_entry->burst_regs.emc_w2p_idx;\n\t\telse\n\t\t{\n\t\t\tu32 W2P_war_temp = deltaTWATM + src_emc_entry->burst_regs.emc_w2p_idx;\n\t\t\tW2P_war = W2P_war_temp - RP_war;\n\t\t\tif (W2P_war > 63)\n\t\t\t{\n\t\t\t\tRP_war = W2P_war_temp - 63;\n\t\t\t\tW2P_war = 63;\n\t\t\t\tif (TRPab_war < RP_war)\n\t\t\t\t\tTRPab_war = RP_war;\n\t\t\t}\n\t\t}\n\n\t\tif ( src_emc_entry->burst_regs.emc_w2p_idx != W2P_war\n\t\t\t|| src_emc_entry->burst_regs.emc_rp_idx != RP_war\n\t\t\t|| src_emc_entry->burst_regs.emc_r2p_idx != R2P_war\n\t\t\t|| src_emc_entry->burst_regs.emc_trpab_idx != TRPab_war)\n\t\t{\n\t\t\tEMC(EMC_DBG) = emc_dbg_o | 2;\n\t\t\tEMC(EMC_RP) = RP_war;\n\t\t\tEMC(EMC_R2P) = R2P_war;\n\t\t\tEMC(EMC_W2P) = W2P_war;\n\t\t\tEMC(EMC_TRPAB) = TRPab_war;\n\t\t\tEMC(EMC_DBG) = emc_dbg_o;\n\t\t\t_usleep(1);\n\t\t}\n\t}\n\n\t// Step 7.2 - Program FSP reference registers and send MRWs to new FSPWR.\n\tEPRINTF(\"Step 7.2\");\n\tmr13_catr_enable = 0;\n\tif (fsp_for_src_freq)\n\t{\n\t\tmr13_flip_fspop = dst_emc_entry->emc_mrw3 | 0xC0;\n\t\tmr13_flip_fspwr = (dst_emc_entry->emc_mrw3 & 0xFFFFFF3F) | 0x40;\n\t}\n\telse\n\t{\n\t\tmr13_flip_fspop = dst_emc_entry->emc_mrw3 & 0xFFFFFF3F;\n\t\tmr13_flip_fspwr = mr13_flip_fspop | 0x80;\n\t}\n\n\tif (needs_ca_or_cavref_training && dram_dev_num == TWO_RANK)\n\t{\n\t\tif (needs_swap_rank_training)\n\t\t{\n\t\t\tmr13_flip_fspop = (mr13_flip_fspop & 0x3FFFFFFF) | 0x80000000;\n\t\t\tmr13_catr_enable = (mr13_flip_fspwr & 0x3FFFFFFF)| 0x40000001;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tmr13_flip_fspop = (mr13_flip_fspop & 0x3FFFFFFF) | 0x40000000;\n\t\t\tmr13_catr_enable = (mr13_flip_fspwr & 0x3FFFFFFF) | 0x80000001;\n\t\t}\n\t}\n\telse if (dram_dev_num == TWO_RANK)\n\t{\n\t\tif (needs_swap_rank_training)\n\t\t\tmr13_catr_enable = (mr13_flip_fspwr & 0x3FFFFFFF) | 0x40000001;\n\t\telse\n\t\t\tmr13_catr_enable = (mr13_flip_fspwr & 0x3FFFFFFF) | 0x80000001;\n\t}\n\telse\n\t\tmr13_catr_enable = mr13_flip_fspwr | 1;\n\n\tif (dram_type == DRAM_TYPE_LPDDR4)\n\t{\n\t\tEMC(EMC_MRW3) = mr13_flip_fspwr;\n\t\tEMC(EMC_MRW) = dst_emc_entry->emc_mrw;\n\t\tEMC(EMC_MRW2) = dst_emc_entry->emc_mrw2;\n\t}\n\n\t// Step 8 - Program the shadow registers.\n\tEPRINTF(\"Step 8\");\n\t// Writing burst_regs.\n\tu32 reg_addr = 0;\n\tu32 reg_val = 0;\n\tu32 reg_check = false;\n\tburst_regs_table_t *dst_burst_regs = (burst_regs_table_t *)&dst_emc_entry->burst_regs;\n\n\tfor (u32 i = 0; dst_emc_entry->num_burst > i; i++)\n\t{\n\t\treg_check = false;\n\t\treg_addr = burst_regs_emc_addr_table[i];\n\t\tif (needs_tristate_training)\n\t\t{\n\t\t\tif (needs_ca_or_cavref_training)\n\t\t\t\treg_val = dst_burst_regs->shadow_regs_ca_train[i];\n\t\t\telse if (needs_training & 0xC)\n\t\t\t\treg_val = dst_burst_regs->shadow_regs_quse_train[i];\n\t\t\telse if (needs_training & 0xF0)\n\t\t\t\treg_val = dst_burst_regs->shadow_regs_rdwr_train[i];\n\t\t\telse\n\t\t\t\tcontinue;\n\t\t}\n\t\telse\n\t\t\treg_val = dst_burst_regs->burst_regs[i];\n\n\t\tif ((reg_addr & 0xFFF7) != EMC_MRW6\n\t\t\t&& (reg_addr - EMC_MRW7) & 0xFFFF7\n\t\t\t//&& (reg_addr & 0xEFF7) != 0x34B4 // EMC_MRW10.\n\t\t\t&& ((reg_addr & 0xEFFF) - 0x34B8) & 0xFFF7 // EMC_MRW11.\n\t\t\t&& reg_addr != EMC_TRAINING_CTRL\n\t\t\t&& reg_addr != EMC_MRW14\n\t\t\t&& reg_addr != EMC_MRW15)\n\t\t{\n\t\t\treg_check = true;\n\t\t}\n\n\t\tif (reg_check && reg_addr == EMC_CFG)\n\t\t{\n\t\t\tif (dram_type == DRAM_TYPE_LPDDR4)\n\t\t\t\treg_val &= 0xFFFFFFF;\n\t\t\telse\n\t\t\t\treg_val &= 0xCFFFFFFF;\n\t\t\tEMC(reg_addr) = reg_val;\n\t\t\tcontinue;\n\t\t}\n\t\tif (!reg_check && dram_type != DRAM_TYPE_LPDDR4)\n\t\t\tcontinue;\n\n\t\tif (reg_addr != EMC_CFG)// EMC_CFG\n\t\t{\n\t\t\tif (reg_addr != EMC_ZCAL_INTERVAL || !opt_zcal_en_cc)\n\t\t\t{\n\t\t\t\tswitch ( reg_addr )\n\t\t\t\t{\n\t\t\t\t\tcase EMC_PMACRO_AUTOCAL_CFG_COMMON:\n\t\t\t\t\t\treg_val |= 0x10000;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EMC_PMACRO_DATA_PAD_TX_CTRL:\n\t\t\t\t\t\treg_val &= 0xFEFEFDFD;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EMC_PMACRO_CMD_PAD_TX_CTRL:\n\t\t\t\t\t\treg_val = (reg_val & 0xFAFEFDFD) | 0x4000000;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EMC_PMACRO_BRICK_CTRL_RFU1:\n\t\t\t\t\t\treg_val &= 0xF800F800;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EMC_PMACRO_COMMON_PAD_TX_CTRL:\n\t\t\t\t\t\treg_val &= 0xFFFFFFF0;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EMC_TRAINING_CTRL:\n\t\t\t\t\t\treg_val |= needs_swap_rank_training << 14;// bit15 is TR_IN_SELF_REFRESH\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\treg_val = 0;\n\t\t}\n\t\telse\n\t\t\treg_val &= 0xFFFFFFF;\n\n\t\tEMC(reg_addr) = reg_val;\n\t}\n\n\tif (needs_tristate_training)\n\t\tEMC(EMC_MRW) = (src_emc_entry->run_clocks & 0xFF) | 0x170000;\n\telse\n\t\tEMC(EMC_MRW) = (dst_emc_entry->run_clocks & 0xFF) | 0x170000;\n\n\t// Writing burst_regs_per_ch.\n\tfor (u32 i = 0; dst_emc_entry->num_burst_per_ch > i; i++)\n\t{\n\t\treg_addr = burst_reg_per_ch_emc01_addr_table[i];\n\t\tif (reg_addr\n\t\t\t&& (((((reg_addr & 0xFFF) - 0x4B8) & 0xFFFFFFF7) //EMC0_MRW11\n\t\t\t\t\t&& (reg_addr & 0xFFF) != 0x4B4 //EMC0_MRW10 - ALways true, because of constant table.\n\t\t\t\t\t&& (reg_addr & 0xFFFFFFF7) != EMC_MRW6\n\t\t\t\t\t&& reg_addr != EMC_MRW15\n\t\t\t\t\t&& reg_addr != EMC_MRW14\n\t\t\t\t\t&& ((reg_addr - EMC_MRW7) & 0xFFFFFFF7))\n\t\t\t\t|| dram_type == DRAM_TYPE_LPDDR4)\n\t\t\t&& (channel1_enabled || ((reg_addr - 0x4000) > 0xFFF)))\n\t\t{\n\t\t\tEMC(reg_addr) = dst_burst_regs->burst_reg_per_ch[i];\n\t\t}\n\t}\n\n\t// Writing vref_regs.\n\ttrim_regs_table_t *trim_regs_table = (trim_regs_table_t *)&dst_emc_entry->trim_regs;\n\tfor (u32 i = 0; dst_emc_entry->vref_num > i; i++)\n\t{\n\t\treg_addr = vref_perch_regs_emc01_addr_table[i];\n\t\tif (reg_addr && (channel1_enabled || (reg_addr - 0x4000) > 0xFFF))\n\t\t\tEMC(reg_addr) = trim_regs_table->vref_perch_regs[i];\n\t}\n\n\t// Writing training mod regs.\n\tif (needs_tristate_training)\n\t{\n\t\tfor (u32 i = 0; dst_emc_entry->training_mod_num > i; i++)\n\t\t{\n\t\t\treg_addr = training_mod_regs_emc01_addr_table[i];\n\t\t\tif (reg_addr && (channel1_enabled || (reg_addr - 0x4000) > 0xFFF))\n\t\t\t\tEMC(reg_addr) = dst_emc_entry->training_mod_regs[i];\n\t\t}\n\t}\n\n\t// Writing trim_regs\n\tfor (u32 i = 0; dst_emc_entry->num_trim > i; i++)\n\t{\n\t\treg_addr = trim_regs_emc_addr_table[i];\n\t\tif (reg_addr)\n\t\t{\n\t\t\tif (((reg_addr & 0xFFFFFFF3) == EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0\n\t\t\t\t || (reg_addr & 0xFFFFFFF3) == EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0\n\t\t\t\t || (reg_addr & 0xFFFFFFFB) == EMC_DATA_BRLSHFT_0)\n\t\t\t\t&& compensate_trimmer_applicable)\n\t\t\t{\n\t\t\t\tEMC(reg_addr) = _minerva_apply_periodic_compensation_trimmer(dst_emc_entry, reg_addr);\n\t\t\t}\n\t\t\telse\n\t\t\t\tEMC(reg_addr) = trim_regs_table->trim_regs[i];\n\t\t}\n\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t // Writing trim_regs_per_ch\n\treg_val = 0;\n\tfor (u32 i = 0; dst_emc_entry->num_trim_per_ch > i; i++)\n\t{\n\t\treg_addr = trim_perch_regs_emc01_addr_table[i];\n\t\tif (reg_addr && (channel1_enabled || reg_addr - 0x4000 > 0xFFF))\n\t\t{\n\t\t\tif (((reg_addr & 0xFFFFFFF3) == EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0\n\t\t\t\t || (reg_addr & 0xFFFFFFF3) == EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0\n\t\t\t\t || (reg_addr & 0xFFFFFFFB) == EMC_DATA_BRLSHFT_0)\n\t\t\t\t&& compensate_trimmer_applicable )\n\t\t\t{\n\t\t\t\treg_val = _minerva_apply_periodic_compensation_trimmer(dst_emc_entry, reg_addr & 0xFFF);\n\t\t\t}\n\t\t\telse if (((reg_addr & 0xFFFFFFFB) == 0x3660\n\t\t\t\t || (reg_addr & 0xFFFFFFDF) == 0x3648\n\t\t\t\t || (reg_addr & 0xFFFFFFF7) == 0x3644\n\t\t\t\t || reg_addr == 0x366C\n\t\t\t\t || reg_addr == EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0\n\t\t\t\t || (reg_addr & 0xFFFFFFFB) == 0x3588)\n\t\t\t\t&& compensate_trimmer_applicable )\n\t\t\t{\n\t\t\t\treg_val = _minerva_apply_periodic_compensation_trimmer(dst_emc_entry, reg_addr & 0xFFF);\n\t\t\t}\n\t\t\telse if (((reg_addr & 0xFFFFFFF3) == 0x4660\n\t\t\t\t || (reg_addr & 0xFFFFFFF3) == 0x4640\n\t\t\t\t || (reg_addr & 0xFFFFFFFB) == 0x4588)\n\t\t\t\t&& compensate_trimmer_applicable)\n\t\t\t{\n\t\t\t\treg_val = _minerva_apply_periodic_compensation_trimmer(dst_emc_entry, reg_addr & 0xFFF);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treg_val = trim_regs_table->trim_perch_regs[i];\n\t\t\t}\n\t\t\tEMC(reg_addr) = reg_val;\n\t\t}\n\t}\n\n\tif (needs_tristate_training)\n\t{\n\t\t// Check delta wrt previous values (save value if margin exceeds what is set in table).\n\t\tif (needs_wr_training && dst_emc_entry->periodic_training)\n\t\t\t_minerva_periodic_compensation_handler(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, WRITE_TRAINING_SEQUENCE);\n\t}\n\telse\n\t{\n\t\t// Writing burst_mc_regs.\n\t\tfor (u32 i = 0; dst_emc_entry->num_mc_regs > i; i++)\n\t\t\tMC(burst_mc_regs_addr_table[i]) = dst_emc_entry->burst_mc_regs[i];\n\t}\n\n\t// Writing la_scale_regs.\n\t//if ((dst_emc_entry->rate_khz < src_emc_entry->rate_khz) && dst_emc_entry->num_up_down) //NEW TODO\n\tif ((dst_emc_entry->rate_khz < src_emc_entry->rate_khz) > needs_tristate_training)\n\t{\n\t\tfor (u32 i = 0; dst_emc_entry->num_up_down > i; i++)\n\t\t\tMC(la_scale_regs_mc_addr_table[i]) = dst_emc_entry->la_scale_regs[i];\n\t}\n\n\t// Step 9 - LPDDR4.\n\tEPRINTF(\"Step 9\");\n\tif (dram_type == DRAM_TYPE_LPDDR4)\n\t{\n\t\tEMC(EMC_ZCAL_INTERVAL) = src_emc_entry->burst_regs.emc_zcal_interval_idx & 0xFF000000;\n\t\tEMC(EMC_ZCAL_WAIT_CNT) = dst_emc_entry->burst_regs.emc_zcal_wait_cnt_idx & 0xFFFFF800;\n\t\tEMC(EMC_DBG) = emc_dbg_o | 0x40000002;\n\t\tEMC(EMC_ZCAL_INTERVAL) = src_emc_entry->burst_regs.emc_zcal_interval_idx & 0xFF000000;\n\t\tEMC(EMC_DBG) = emc_dbg_o;\n\t\tif (needs_tristate_training)\n\t\t{\n\t\t\tEMC(EMC_DBG) = emc_dbg_o | 2;\n\t\t\tEMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = dst_emc_entry->burst_regs.emc_pmacro_autocal_cfg_common_idx | 0x10000;\n\t\t\tif (needs_ca_or_cavref_training)\n\t\t\t\tEMC(EMC_FBIO_CFG5) = src_emc_entry->burst_regs.emc_fbio_cfg5_idx | 0x8000000;\n\t\t\tEMC(EMC_DBG) = emc_dbg_o;\n\t\t\tif (channel1_enabled)\n\t\t\t\t_ccfifo_write(EMC_CFG_SYNC, 0, 0);\n\t\t\t_ccfifo_write(EMC_DBG, (emc_dbg_o & 0xF3FFFFFF) | 0x4000000, 0);\n\t\t}\n\t}\n\n\t// Step 10 - Self refresh\n\tEPRINTF(\"Step 10\");\n\tu32 emc_self_ref_val = 1;\n\tif (!opt_dll_mode && dram_type == DRAM_TYPE_DDR3)\n\t\t_ccfifo_write(EMC_EMRS, dst_emc_entry->emc_emrs, 0); \n\telse if (dram_type == DRAM_TYPE_LPDDR4)\n\t\temc_self_ref_val = 0x101;\n\t\t\t\t\t\t \n\t_ccfifo_write(EMC_SELF_REF, emc_self_ref_val, 0);\n\n\tif (needs_ca_or_cavref_training < ((src_clock_period <= 2.0f) && dram_type == DRAM_TYPE_LPDDR4))\n\t{\n\t\t_ccfifo_write(EMC_MRW3, mr13_flip_fspwr ^ 0x40, 0); \n\t\t_ccfifo_write(EMC_MRW6, (src_emc_entry->burst_regs.emc_mrw6_idx & 0xC0C0) | (dst_emc_entry->burst_regs.emc_mrw6_idx & 0xFFFF3F3F), 0); \n\t\t_ccfifo_write(EMC_MRW14, (src_emc_entry->burst_regs.emc_mrw14_idx & 0x3838) | (dst_emc_entry->burst_regs.emc_mrw14_idx & 0xFFFF0707), 0); \n\t\tif (dram_dev_num == TWO_RANK)\n\t\t{\n\t\t\t_ccfifo_write(EMC_MRW7, (src_emc_entry->burst_regs.emc_mrw7_idx & 0xC0C0) | (dst_emc_entry->burst_regs.emc_mrw7_idx & 0xFFFF3F3F), 0); \n\t\t\t_ccfifo_write(EMC_MRW15, (src_emc_entry->burst_regs.emc_mrw15_idx & 0x3838) | (dst_emc_entry->burst_regs.emc_mrw15_idx & 0xFFFF0707), 0); \n\t\t}\n\t\tif (opt_zcal_en_cc)\n\t\t{\n\t\t\tif (dram_dev_num == ONE_RANK || zcal_resistor_shared)\n\t\t\t\temc_zq_cal = 0x80000001;\n\t\t\telse\n\t\t\t\temc_zq_cal = 1;\n\t\t\t_ccfifo_write(EMC_ZQ_CAL, emc_zq_cal, 0);\n\t\t}\n\t}\n\t\n\temc_dbg_val = emc_dbg_o;\n\tfloat tRP_src_timing = (float)((float)src_emc_entry->dram_timings.t_rp / src_clock_period);\n\tfloat tRFC_src_timing = (float)((float)src_emc_entry->dram_timings.t_rfc / src_clock_period);\n\tbool in_self_refresh = false;\n\tu32 ref_delay = 0;\n\n\tif (dram_type == DRAM_TYPE_LPDDR4)\n\t{\n\t\tif (needs_tristate_training)\n\t\t{\n\t\t\temc_dbg_val = (emc_dbg_o & 0xF3FFFFFF) | 0x44000000;\n\t\t\t_ccfifo_write(EMC_DBG, emc_dbg_val, 0);\n\t\t}\n\t\tif (needs_ca_or_cavref_training)\n\t\t{\n\t\t\t_ccfifo_write(EMC_PMACRO_DATA_RX_TERM_MODE, src_emc_entry->burst_regs.emc_pmacro_data_rx_term_mode_idx & 0xFFFFFCCC, 0);\n\t\t\tif (dram_dev_num == TWO_RANK && needs_swap_rank_training)\n\t\t\t{\n\t\t\t\t_ccfifo_write(EMC_MRW3, mr13_flip_fspop | 8, (u32)tRP_src_timing);\n\t\t\t\t_ccfifo_write(EMC_MRW3, mr13_catr_enable | 8, 0);\n\t\t\t}\n\t\t\telse\n\t\t\t\t_ccfifo_write(EMC_MRW3, mr13_catr_enable | 8, (u32)tRP_src_timing);\n\n\t\t\t_ccfifo_write(EMC_TR_CTRL_0, 0x15A, 0);\n\t\t\tref_delay = (u32)(1000.0 / src_clock_period);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t_ccfifo_write(EMC_MRW3, mr13_flip_fspop | 8, (u32)tRP_src_timing);\n\t\t\tref_delay = (u32)(float)((float)tFC_lpddr4 / src_clock_period);\n\t\t}\n\t\t_ccfifo_write(EMC_INTSTATUS, 0, ref_delay);\n\t\t_ccfifo_write(EMC_PIN, emc_pin_o & 0xFFFFFFF8, 30);\n\t}\n\telse\n\t{\n\t\tin_self_refresh = true;\n\t\t_ccfifo_write(EMC_SELF_REF, 0x1, 0);\n\t}\n\n\t// Step 11 - Ramp down.\n\tEPRINTF(\"Step 11\");\n\tref_delay = 0;\n\tif (dram_type != DRAM_TYPE_LPDDR4)\n\t\tref_delay = (u32)(float)(tRP_src_timing + tRFC_src_timing + 20.0f);\n\t_ccfifo_write(EMC_CFG_SYNC, 0, ref_delay);\n\t_ccfifo_write(EMC_DBG, emc_dbg_val | 0x40000002, 0); // WRITE_MUX_ACTIVE | WRITE_ACTIVE_ONLY\n\tramp_down_wait = _dvfs_power_ramp_down(false, src_emc_entry, dst_emc_entry, src_clock_period);\n\n\t// Step 12 - Trigger clock change.\n\tEPRINTF(\"Step 12\");\n\t_ccfifo_write(EMC_STALL_THEN_EXE_AFTER_CLKCHANGE, 1, 0);\n\tif (!needs_tristate_training)\n\t\t_ccfifo_write(EMC_DBG, (emc_dbg_val & 0xBFFFFFFF) | 2, 0);\n\n\t// Step 13 - Ramp up.\n\tEPRINTF(\"Step 13\");\n\tramp_up_wait = _dvfs_power_ramp_up(false, src_emc_entry, dst_emc_entry, needs_training & 0xFF, dst_clock_period);\n\t_ccfifo_write(EMC_DBG, emc_dbg_val, 0);\n\n\t// Step 14 - Bringup CKE pins.\n\tEPRINTF(\"Step 14\");\n\tif (dram_type == DRAM_TYPE_LPDDR4)\n\t{\n\t\tu32 emc_pin_val_final = 0;\n\t\tif (needs_ca_or_cavref_training)\n\t\t{\n\t\t\temc_pin_val_final = emc_pin_o & 0xFFFFFFF8;\n\t\t\tif (dram_dev_num == TWO_RANK)\n\t\t\t{\n\t\t\t\tif (needs_swap_rank_training)\n\t\t\t\t\temc_pin_val_final |= 5;\n\t\t\t\telse\n\t\t\t\t\temc_pin_val_final |= 6;\n\t\t\t}\n\t\t}\n\t\telse if (dram_dev_num == TWO_RANK)\n\t\t\temc_pin_val_final = emc_pin_o | 7;\n\t\telse\n\t\t\temc_pin_val_final = (emc_pin_o & 0xFFFFFFF8) | 1;\n\n\t\t_ccfifo_write(EMC_PIN, emc_pin_val_final, 0);\n\t}\n\n\t// Step 15 - Zqlatch.\n\tEPRINTF(\"Step 15\");\n\tif (dram_type == DRAM_TYPE_LPDDR4 && !needs_ca_or_cavref_training && opt_zcal_en_cc)\n\t{\n\t\ts32 zq_latch_dvfs_wait_time = 0;\n\t\ts32 T_PDEX_timing_final = 0;\n\t\ts32 T_PDEX_timing = _fceil((float)dst_emc_entry->dram_timings.t_pdex / dst_clock_period);\n\n\t\tif (src_clock_period > 2.0)\n\t\t\tzq_latch_dvfs_wait_time = (s32)(tZQCAL_lpddr4_fc_adj - T_PDEX_timing);\n\t\telse\n\t\t\tzq_latch_dvfs_wait_time =\n\t\t\t\t(s32)(tZQCAL_lpddr4_fc_adj - (s32)((float)(ramp_up_wait + ramp_down_wait) / dst_clock_period));\n\n\t\tif (dram_dev_num == ONE_RANK)\n\t\t{\n\t\t\tif (T_PDEX_timing < 0)\n\t\t\t\t\tT_PDEX_timing = 0;\n\n\t\t\tif (src_clock_period > 2.0)\n\t\t\t\t_ccfifo_write(EMC_ZQ_CAL, 0x80000001, T_PDEX_timing);\n\n\t\t\tif (!needs_tristate_training)\n\t\t\t{\n\t\t\t\t_ccfifo_write(EMC_MRW3, (mr13_flip_fspop & 0xF3FFFFF7) | 0xC000000, T_PDEX_timing);\n\t\t\t\t_ccfifo_write(EMC_SELF_REF, 0x100, 0);\n\t\t\t\t_ccfifo_write(EMC_REF, 0, 0);\n\t\t\t}\n\t\t\temc_zq_cal = 0x80000002;\n\t\t\tif (zq_latch_dvfs_wait_time < 0)\n\t\t\t\tzq_latch_dvfs_wait_time = 0;\n\t\t}\n\t\telse if (zcal_resistor_shared)\n\t\t{\n\t\t\tif (src_clock_period > 2.0)\n\t\t\t{\n\t\t\t\tT_PDEX_timing_final = T_PDEX_timing;\n\t\t\t\tif (T_PDEX_timing < 0)\n\t\t\t\t\tT_PDEX_timing_final = 0;\n\t\t\t\t_ccfifo_write(EMC_ZQ_CAL, 0x80000001, T_PDEX_timing_final);\n\t\t\t}\n\t\t\tT_PDEX_timing_final = zq_latch_dvfs_wait_time + T_PDEX_timing;\n\t\t\tif ((zq_latch_dvfs_wait_time + T_PDEX_timing) < 0)\n\t\t\t\tT_PDEX_timing_final = 0;\n\t\t\t_ccfifo_write(EMC_ZQ_CAL, 0x80000002, T_PDEX_timing_final);\n\t\t\t_ccfifo_write(EMC_ZQ_CAL, 0x40000001, 0);\n\t\t\tif (!needs_tristate_training)\n\t\t\t{\n\t\t\t\t_ccfifo_write(EMC_MRW3, (mr13_flip_fspop & 0xF3FFFFF7) | 0xC000000, 0);\n\t\t\t\t_ccfifo_write(EMC_SELF_REF, 0x100, 0);\n\t\t\t\t_ccfifo_write(EMC_REF, 0, 0);\n\t\t\t}\n\t\t\temc_zq_cal = 0x40000002;\n\t\t\tzq_latch_dvfs_wait_time = (s32)(float)(1000.0f / dst_clock_period);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (T_PDEX_timing < 0)\n\t\t\t\tT_PDEX_timing = 0;\n\n\t\t\tif (src_clock_period > 2.0)\n\t\t\t\t_ccfifo_write(EMC_ZQ_CAL, 1, T_PDEX_timing);\n\t\t\tif (!needs_tristate_training)\n\t\t\t{\n\t\t\t\t_ccfifo_write(EMC_MRW3, (mr13_flip_fspop & 0xF3FFFFF7) | 0xC000000, T_PDEX_timing);\n\t\t\t\t_ccfifo_write(EMC_SELF_REF, 0x100, 0);\n\t\t\t\t_ccfifo_write(EMC_REF, 0, 0);\n\t\t\t}\n\t\t\temc_zq_cal = 2;\n\n\t\t\tif (zq_latch_dvfs_wait_time < 0)\n\t\t\t\tzq_latch_dvfs_wait_time = 0;\n\t\t}\n\t\t_ccfifo_write(EMC_ZQ_CAL, emc_zq_cal, (u32)zq_latch_dvfs_wait_time);\n\t}\n\t\n\t_ccfifo_write(EMC_INTSTATUS, 0, 10); // WAR: delay for zqlatch.\n\n\t// Step 16 - LPDDR4 Conditional training kickoff.\n\tEPRINTF(\"Step 16\");\n\tif (needs_tristate_training && dram_type == DRAM_TYPE_LPDDR4)\n\t{\n\t\t_ccfifo_write(EMC_INTSTATUS, 0, (u32)(1020.0f / dst_clock_period));\n\n\t\tu32 training_command = 0;\n\n\t\tif (needs_ca_training)\n\t\t\ttraining_command |= (1 << 1);  // CA: Initiates CA Training.\n\t\tif (needs_ca_vref_training)\n\t\t\ttraining_command |= (1 << 5);  // CA_VREF: Initiates CA_VREF Training.\n\t\tif (needs_quse_training)\n\t\t\ttraining_command |= (1 << 4);  // QUSE: Initiates QUSE Training.\n\t\tif (needs_quse_vref_training)\n\t\t\ttraining_command |= (1 << 8);  // QUSE_VREF: Initiates DQS_VREF Training.\n\t\tif (needs_wr_training)\n\t\t\ttraining_command |= (1 << 3);  // WR: Initiates WR Training.\n\t\tif (needs_wr_vref_training)\n\t\t\ttraining_command |= (1 << 6);  // WR_VREF: Initiates OB (wrire) DRAM_VREF Training.\n\t\tif (needs_rd_training)\n\t\t\ttraining_command |= (1 << 2);  // RD: Initiates RD Training.\n\t\tif (needs_rd_vref_training)\n\t\t\ttraining_command |= (1 << 7);  // RD_VREF: Initiates IB_DQ_VREF Training.\n\t\ttraining_command     |= (1 << 31); // GO: Start the Training.\n\n\t\t_ccfifo_write(EMC_TRAINING_CMD, training_command, 0);\n\n\t\tif (bg_regulator_mode_change)\n\t\t{\n\t\t\tif (enable_bg_regulator)\n\t\t\t\t_ccfifo_write(EMC_PMACRO_BG_BIAS_CTRL_0,\n\t\t\t\t\tsrc_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0_idx & 0xFFFFFFFE, 0);\n\t\t\telse\n\t\t\t\t_ccfifo_write(EMC_PMACRO_BG_BIAS_CTRL_0,\n\t\t\t\t\tsrc_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0_idx & 0xFFFFFFFB, 0);\n\t\t}\n\n\t\t_ccfifo_write(EMC_SWITCH_BACK_CTRL, 1, 0);\n\n\t\tif (!needs_ca_or_cavref_training || needs_swap_rank_training)\n\t\t{\n\t\t\t_ccfifo_write(EMC_MRW3, mr13_flip_fspop ^ 0xC0, 0);\n\t\t\t_ccfifo_write(EMC_INTSTATUS, 0, (u32)(1000.0f / dst_clock_period));\n\t\t}\n\n\t\t_ccfifo_write(EMC_PIN, emc_pin_o & 0xFFFFFFF8, 0);\n\t\t_ccfifo_write(EMC_CFG_SYNC, 0, 0);\n\t\t_ccfifo_write(EMC_DBG, emc_dbg_val | 0x40000002, 0);\n\n\t\t_dvfs_power_ramp_down(true, src_emc_entry, dst_emc_entry, dst_clock_period);\n\n\t\t_ccfifo_write(EMC_STALL_THEN_EXE_AFTER_CLKCHANGE, 1, 0);\n\t\t_ccfifo_write(EMC_DBG, (emc_dbg_val & 0xBFFFFFFF) | 2, 0);\n\n\t\t_dvfs_power_ramp_up(true, src_emc_entry, dst_emc_entry, needs_training, src_clock_period);\n\n\t\t_ccfifo_write(EMC_DBG, emc_dbg_val, 0);\n\n\t\tif (dram_dev_num == TWO_RANK)\n\t\t\t_ccfifo_write(EMC_PIN, emc_pin_o | 7, 0);\n\t\telse\n\t\t\t_ccfifo_write(EMC_PIN, (emc_pin_o & 0xFFFFFFF8) | 1, 0);\n\n\t\tif (needs_ca_or_cavref_training)\n\t\t{\n\t\t\t_ccfifo_write(EMC_TR_CTRL_0, 0x4A, (u32)(float)(200.0f / src_clock_period));\n\t\t\t_ccfifo_write(EMC_TR_CTRL_0, 0x40, (u32)(float)(1000.0f / src_clock_period));\n\t\t\t_ccfifo_write(EMC_MRW3, mr13_catr_enable & 0xFFFFFFFE, 0);\n\t\t\t_ccfifo_write(EMC_INTSTATUS, 0, (u32)(float)(1000.0f / src_clock_period));\n\t\t\t_ccfifo_write(EMC_PMACRO_DATA_RX_TERM_MODE, src_emc_entry->burst_regs.emc_pmacro_data_rx_term_mode_idx, 0);\n\t\t}\n\t\t_ccfifo_write(EMC_DBG, emc_dbg_o, 0);\n\n\t\tif (opt_zcal_en_cc)\n\t\t{\n\t\t\t_ccfifo_write(EMC_ZQ_CAL, 0x80000001, 0);\n\t\t\t_ccfifo_write(EMC_ZQ_CAL, 0x80000002, (u32)(float)(1000.0f / src_clock_period));\n\n\t\t\tif (zcal_resistor_shared && dram_dev_num == TWO_RANK)\n\t\t\t{\n\t\t\t\tif (!needs_ca_or_cavref_training || needs_swap_rank_training)\n\t\t\t\t{\n\t\t\t\t\t_ccfifo_write(EMC_ZQ_CAL, 0x40000001, 0);\n\t\t\t\t\t_ccfifo_write(EMC_ZQ_CAL, 0x40000002, (u32)(float)(1000.0f / src_clock_period));\n\t\t\t\t\tif (!needs_ca_or_cavref_training)\n\t\t\t\t\t\t_ccfifo_write(EMC_MRW3, ((mr13_flip_fspop ^ 0xC0) & 0xF3FFFFF7) | 0xC000000, 0);\n\t\t\t\t}\n\n\t\t\t\t_ccfifo_write(EMC_SELF_REF, 0x100, 0);\n\n\t\t\t\tgoto step_19_2;\n\t\t\t}\n\t\t\telse if (dram_dev_num == TWO_RANK)\n\t\t\t{\n\t\t\t\tif (needs_ca_or_cavref_training && !needs_swap_rank_training)\n\t\t\t\t{\n\t\t\t\t\t_ccfifo_write(EMC_SELF_REF, 0x100, 0);\n\n\t\t\t\t\tgoto step_19_2;\n\t\t\t\t}\n\n\t\t\t\t_ccfifo_write(EMC_ZQ_CAL, 0x40000001, 0);\n\t\t\t\t_ccfifo_write(EMC_ZQ_CAL, 0x40000002, (u32)(float)(1000.0f / src_clock_period));\n\t\t\t}\n\t\t}\n\n\t\tif (!needs_ca_or_cavref_training)\n\t\t\t_ccfifo_write(EMC_MRW3, ((mr13_flip_fspop ^ 0xC0) & 0xF3FFFFF7) | 0xC000000, 0);\n\n\t\t_ccfifo_write(EMC_SELF_REF, 0x100, 0);\n\t}\n\n\tif (dram_type != DRAM_TYPE_LPDDR4)\n\t{\n\t\t// Step 17 - MANSR exit self refresh.\n\t\tEPRINTF(\"Step 17\");\n\t\t_ccfifo_write(EMC_SELF_REF, 0, 0);\n\n\t\tif (dram_type != DRAM_TYPE_LPDDR2)\n\t\t{\n\t\t\tif (dram_type == DRAM_TYPE_DDR3)\n\t\t\t{\n\t\t\t\tif (opt_dll_mode)\n\t\t\t\t\t_ccfifo_write(EMC_EMRS, dst_emc_entry->emc_emrs & 0xFBFFFFFF, 0);\n\n\t\t\t\t_ccfifo_write(EMC_EMRS2, dst_emc_entry->emc_emrs2 & 0xFBFFFFFF, 0);\n\t\t\t\t_ccfifo_write(EMC_MRS, dst_emc_entry->emc_mrs | 0x4000000, 0);\n\n\t\t\t\tif (opt_zcal_en_cc)\n\t\t\t\t{\n\t\t\t\t\t_ccfifo_write(EMC_ZQ_CAL, 0x80000001, 0);\n\t\t\t\t\tif (dram_dev_num == TWO_RANK)\n\t\t\t\t\t\t_ccfifo_write(EMC_ZQ_CAL, 0x40000001, 0);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (dram_type == DRAM_TYPE_LPDDR2 && opt_zcal_en_cc)\n\t\t\t{\n\t\t\t\t_ccfifo_write(EMC_MRW, 0x880A0056, 0);\n\t\t\t\tif (dram_dev_num == TWO_RANK)\n\t\t\t\t\t_ccfifo_write(EMC_MRW, 0x480A0056, 0);\n\t\t\t}\n\n\t\t\tgoto step_19_2;\n\t\t}\n\n\t\t// Step 18 - Send MRWs to LPDDR3/DDR3.\n\t\tEPRINTF(\"Step 18\");\n\t\t_ccfifo_write(EMC_MRW2, dst_emc_entry->emc_mrw2, 0);\n\t\t_ccfifo_write(EMC_MRW, dst_emc_entry->emc_mrw, 0);\n\t\tif (is_lpddr3_dram)\n\t\t\t_ccfifo_write(EMC_MRW4, dst_emc_entry->emc_mrw4, 0);\n\n\t\t// Step 19 - ZQCAL for LPDDR3/DDR3.\n\t\tEPRINTF(\"Step 19\");\n\t\tif (opt_zcal_en_cc)\n\t\t{\n\t\t\tu32 zcal_wait_time_clocks = _fceil(90.0f / dst_clock_period);\n\t\t\t_ccfifo_write(EMC_MRS_WAIT_CNT2, ((zcal_wait_time_clocks & 0xB) << 16) | (zcal_wait_time_clocks & 0x3FF), 0); //WTFF\n\t\t\t_ccfifo_write(EMC_MRW, 0x880A0056, 0);\n\t\t\tif (dram_dev_num == TWO_RANK)\n\t\t\t\t_ccfifo_write(EMC_MRW, 0x480A0056, 0);\n\t\t}\n\t}\n\nstep_19_2:\n\t// Step 19.2.\n\tEPRINTF(\"Step 19.2\");\n\tif (bg_regulator_mode_change)\n\t{\n\t\t_ccfifo_write(EMC_DBG, emc_dbg_o | 2, 0);\n\n\t\tu32 bg_regulator_switch_complete_wait_clks = 0;\n\t\tif (needs_tristate_training)\n\t\t{\n\t\t\tbg_regulator_switch_complete_wait_clks = (u32)(float)(1250.0f / src_clock_period);\n\t\t\t_ccfifo_write(EMC_PMACRO_BG_BIAS_CTRL_0,\n\t\t\t\tsrc_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0_idx, bg_regulator_switch_complete_wait_clks);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (ramp_up_wait <= 1250)\n\t\t\t\tbg_regulator_switch_complete_wait_clks = (u32)(float)((float)((s32)1250 - ramp_up_wait) / dst_clock_period);\n\t\t\t_ccfifo_write(EMC_PMACRO_BG_BIAS_CTRL_0,\n\t\t\t\tdst_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0_idx, bg_regulator_switch_complete_wait_clks);\n\t\t}\n\n\t\t_ccfifo_write(EMC_DBG, emc_dbg_o, 0);\n\t}\n\n\t// Step 20 - Issue ref and optional QRST.\n\tEPRINTF(\"Step 20\");\n\tif (needs_tristate_training || dram_type != DRAM_TYPE_LPDDR4)\n\t\t_ccfifo_write(EMC_REF, 0, 0);\n\n\t// Step 21 - Restore ZCAL and ZCAL interval.\n\tEPRINTF(\"Step 21\");\n\t_ccfifo_write(EMC_DBG, emc_dbg_o | 2, 0);\n\n\tif (opt_zcal_en_cc)\n\t{\n\t\tif (needs_tristate_training)\n\t\t\t_ccfifo_write(EMC_ZCAL_INTERVAL, src_emc_entry->burst_regs.emc_zcal_interval_idx, 0);\n\t\telse if (dram_type != DRAM_TYPE_LPDDR4)\n\t\t\t_ccfifo_write(EMC_ZCAL_INTERVAL, dst_emc_entry->burst_regs.emc_zcal_interval_idx, 0);\n\t}\n\n\t_ccfifo_write(EMC_CFG, dst_emc_entry->burst_regs.emc_cfg_idx & 0xEFFFFFFF, 0);\n\n\t// Step 22 - Restore EMC_CFG_PIPE_CLK.\n\tEPRINTF(\"Step 22\");\n\tif (needs_tristate_training && dram_type == DRAM_TYPE_LPDDR4)\n\t\t_ccfifo_write(EMC_SEL_DPD_CTRL, src_emc_entry->emc_sel_dpd_ctrl, 0);\n\t_ccfifo_write(EMC_DBG, emc_dbg_o, 0);\n\t_ccfifo_write(EMC_CFG_PIPE_CLK, emc_cfg_pipe_clk_o, 0);\n\tif (bg_regulator_mode_change)\n\t{\n\t\tif (enable_bg_regulator)\n\t\t\tEMC(EMC_PMACRO_BG_BIAS_CTRL_0) = dst_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0_idx & 0xFFFFFFFB;\n\t\telse\n\t\t\tEMC(EMC_PMACRO_BG_BIAS_CTRL_0) = dst_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0_idx & 0xFFFFFFFE;\n\t}\n\n\t// Step 23 - Clock Change.\n\tEPRINTF(\"Step 23\");\n\tif (needs_tristate_training)\n\t{\n\t\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_SAFE) = (u32)CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC);\n\t\t_change_dll_src(src_emc_entry, (u32)CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC));\n\t}\n\tEMC(EMC_CFG_DIG_DLL) = (EMC(EMC_CFG_DIG_DLL) & 0xFFFFFF24) | 0x88;\n\t\n\tCLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = selected_clk_src_emc;\n\tif (_wait_emc_status(EMC_INTSTATUS, CLKCHANGE_COMPLETE_INT, true, 0))\n\t\treturn 4; // Clkchange handshake timeout error.\n\n\t// Step 24 - Save training results.\n\tEPRINTF(\"Step 24\");\n\tif (needs_tristate_training)\n\t{\n\t\temc_dbg_val = EMC(EMC_DBG);\n\t\tEMC(EMC_DBG) |= 1;\n\n\t\t_save_train_results(dst_emc_entry, needs_training, dram_dev_num, channel1_enabled);\n\n\t\tEMC(EMC_DBG) = emc_dbg_val;\n\t}\n\n\t// Step 25 - Program MC updown regs.\n\tEPRINTF(\"Step 25\");\n\t//if (dst_emc_entry->rate_khz > src_emc_entry->rate_khz) //NEW TODO\n\tif ((dst_emc_entry->rate_khz > src_emc_entry->rate_khz) > needs_tristate_training)\n\t{\n\t\tfor (u32 i = 0; dst_emc_entry->num_up_down > i; i++)\n\t\t\tMC(la_scale_regs_mc_addr_table[i]) = dst_emc_entry->la_scale_regs[i];\n\n\t\tbool dual_channel = (EMC(EMC_FBIO_CFG7) >> 1) & ((EMC(EMC_FBIO_CFG7) >> 2) & 1);\n\t\tif (_timing_update(dual_channel))\n\t\t\treturn 4;\n\t}\n\n\t// Step 26 - Restore ZCAL regs.\n\tEPRINTF(\"Step 26\");\n\tif (!in_self_refresh)\n\t{\n\t\tEMC(EMC_DBG) = emc_dbg_o | 2;\n\t\tEMC(EMC_ZCAL_WAIT_CNT) = dst_emc_entry->burst_regs.emc_zcal_wait_cnt_idx;\n\t\tEMC(EMC_ZCAL_INTERVAL) = dst_emc_entry->burst_regs.emc_zcal_interval_idx;\n\t\tEMC(EMC_DBG) = emc_dbg_o;\n\t}\n\n\t// Step 27 - Restore EMC_CFG, FDPD regs.\n\tEPRINTF(\"Step 27\");\n\tEMC(EMC_DBG) = emc_dbg_o | 2;\n\tEMC(EMC_CFG) = dst_emc_entry->burst_regs.emc_cfg_idx;\n\tEMC(EMC_DBG) = emc_dbg_o;\n\tEMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = dst_emc_entry->emc_fdpd_ctrl_cmd_no_ramp;\n\tEMC(EMC_SEL_DPD_CTRL) = dst_emc_entry->emc_sel_dpd_ctrl;\n\n\t// Step 28 - Training recover.\n\tEPRINTF(\"Step 28\");\n\tif (needs_tristate_training && dram_type == DRAM_TYPE_LPDDR4)\n\t{\n\t\tEMC(EMC_DBG) = emc_dbg_o | 2;\n\t\tEMC(EMC_CFG) = dst_emc_entry->burst_regs.emc_cfg_idx;\n\t\tEMC(EMC_SEL_DPD_CTRL) = dst_emc_entry->emc_sel_dpd_ctrl;\n\t\tEMC(EMC_ZCAL_WAIT_CNT) = src_emc_entry->burst_regs.emc_zcal_wait_cnt_idx;\n\t\tEMC(EMC_ZCAL_INTERVAL) = src_emc_entry->burst_regs.emc_zcal_interval_idx;\n\t\tEMC(EMC_AUTO_CAL_CONFIG2) = src_emc_entry->emc_auto_cal_config2;\n\t\tEMC(EMC_AUTO_CAL_CONFIG3) = src_emc_entry->emc_auto_cal_config3;\n\t\tEMC(EMC_AUTO_CAL_CONFIG4) = src_emc_entry->emc_auto_cal_config4;\n\t\tEMC(EMC_AUTO_CAL_CONFIG5) = src_emc_entry->emc_auto_cal_config5;\n\t\tEMC(EMC_AUTO_CAL_CONFIG6) = src_emc_entry->emc_auto_cal_config6;\n\t\tEMC(EMC_AUTO_CAL_CONFIG7) = src_emc_entry->emc_auto_cal_config7;\n\t\tEMC(EMC_AUTO_CAL_CONFIG8) = src_emc_entry->emc_auto_cal_config8;\n\t\tEMC(EMC_DBG) = emc_dbg_o;\n\t\tEMC(EMC_TR_DVFS) = dst_emc_entry->burst_regs.emc_tr_dvfs_idx & 0xFFFFFFFE;\n\t}\n\n\tEMC(EMC_DBG) = emc_dbg_o | 2;\n\tEMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = dst_emc_entry->burst_regs.emc_pmacro_autocal_cfg_common_idx;\n\tEMC(EMC_DBG) = emc_dbg_o;\n\n\t// Step 29 - Power fix WAR.\n\tEPRINTF(\"Step 29\");\n\tEMC(EMC_PMACRO_CFG_PM_GLOBAL_0) = 0xFF0000;\n\tEMC(EMC_PMACRO_TRAINING_CTRL_0) = CH0_TRAINING_E_WRPTR;\n\tEMC(EMC_PMACRO_TRAINING_CTRL_1) = CH0_TRAINING_E_WRPTR;\n\tEMC(EMC_PMACRO_CFG_PM_GLOBAL_0) = 0;\n\n\t// Step 30 - Re-enable autocal and Restore FSP to account for switch back (training).\n\tEPRINTF(\"Step 30\");\n\tif (needs_tristate_training)\n\t{\n\t\tEMC(EMC_AUTO_CAL_CONFIG) = src_emc_entry->emc_auto_cal_config;\n\t\tfsp_for_src_freq = !fsp_for_src_freq;\n\t}\n\telse\n\t{\n\t\tif (dst_emc_entry->burst_regs.emc_cfg_dig_dll_idx & 1)\n\t\t\t_digital_dll_enable_rs(channel1_enabled);\n\t\tEMC(EMC_AUTO_CAL_CONFIG) = dst_emc_entry->emc_auto_cal_config;\n\t}\n\n\treturn 0;\n}\n\nstatic void _minerva_train_patterns(emc_table_t *src_emc_entry, emc_table_t *dst_emc_entry, bool switch_rate, u32 selected_clk_src_emc)\n{\n\tu32 needs_training_idx = 0;\n\tu32 emc_cfg_dig_dll_val = 0;\n\tu32 needs_training_emc_table[8] = {0};\n\n\tu32 needs_training = dst_emc_entry->needs_training;\n\tu32 dram_type = dst_emc_entry->burst_regs.emc_fbio_cfg5_idx & 3;\n\tbool dual_channel = (EMC(EMC_FBIO_CFG7) >> 1) & ((EMC(EMC_FBIO_CFG7) >> 2) & 1);\n\n\t // Must start as true.\n\tif (train_ram_patterns)\n\t{\n\t\tu32 train_table_off = dst_emc_entry->training_pattern * 256;\n\t\tfor (u32 i = 0; i < 256; i++)\n\t\t{\n\t\t\tEMC(EMC_TRAINING_PATRAM_DQ) = ram_pattern_dq_table[train_table_off + i];\n\t\t\tEMC(EMC_TRAINING_PATRAM_DMI) = ram_pattern_dmi_table[train_table_off + i] & 0xF;\n\t\t\tEMC(EMC_TRAINING_PATRAM_CTRL) = 0x80000000 + i;\n\t\t}\n\t\ttrain_ram_patterns = false;\n\t}\n\n\tif (needs_training && !dst_emc_entry->trained)\n\t{\n\t\tneeds_training_idx = needs_training & 3;\n\n\t\tif (needs_training & 3)\n\t\t{\n\t\t\tneeds_training_idx = 1;\n\t\t\tneeds_training_emc_table[0] = needs_training & 0x203;\n\t\t\tif (MC(MC_EMEM_ADR_CFG) & 1) // if mapping W8 (1KB page).\n\t\t\t{\n\t\t\t\tneeds_training_idx = 2;\n\t\t\t\tneeds_training_emc_table[1] = needs_training & 0x303;\n\t\t\t}\n\t\t}\n\n\t\tif (MC(MC_EMEM_ADR_CFG) & 1 && needs_training & 0xC)\n\t\t{\n\t\t\tneeds_training_emc_table[needs_training_idx] = needs_training & 0x20C;\n\t\t\tneeds_training_emc_table[needs_training_idx + 1] = needs_training & 0x204;\n\t\t\tneeds_training_idx += 2;\n\t\t}\n\t\telse if (needs_training & 0xC)\n\t\t\tneeds_training_emc_table[needs_training_idx++] = needs_training & 0x20C;\n\n\t\tif (needs_training & 0xF0)\n\t\t\tneeds_training_emc_table[needs_training_idx++] = needs_training & 0x2F0;\n\n\t\tfor (u32 i = 0; needs_training_idx > i; i++) // Runs more than once for needs_training & 0xF\n\t\t{\n\t\t\t_minerva_set_clock(src_emc_entry, dst_emc_entry, needs_training_emc_table[i], selected_clk_src_emc);\n\n\t\t\tEMC(EMC_DBG) = (EMC(EMC_DBG) & 0xF3FFFFFF) | 0x8000000;\n\t\t\tEMC(EMC_CFG_UPDATE) = (EMC(EMC_CFG_UPDATE) & 0xFFFFFFF9) | 4;\n\t\t\t_timing_update(dual_channel);\n\n\t\t\tEMC(EMC_CFG_UPDATE) &= 0xFFFFFFF9;\n\t\t\tEMC(EMC_DBG) &= 0xF3FFFFFF;\n\t\t\tEMC(EMC_CFG_DIG_DLL) = (EMC(EMC_CFG_DIG_DLL) & 0xFFFFFF3E) | 0x80;\n\t\t\t_timing_update(dual_channel);\n\n\t\t\temc_cfg_dig_dll_val = EMC(EMC_CFG_DIG_DLL) & 0xFFFFFFFE;\n\t\t\tif (dst_emc_entry->burst_regs.emc_cfg_dig_dll_idx == 1)\n\t\t\t\temc_cfg_dig_dll_val = EMC(EMC_CFG_DIG_DLL) | 1;\n\t\t\tEMC(EMC_CFG_DIG_DLL) = (emc_cfg_dig_dll_val & 0xFFFFFF3F) | 0x80;\n\t\t\t_timing_update(dual_channel);\n\n\t\t\twhile (!(EMC(EMC_DIG_DLL_STATUS) & 0x8000))\n\t\t\t\t;\n\n\t\t\t// Bug 200024907.\n\t\t\tif (dram_type == DRAM_TYPE_LPDDR4)\n\t\t\t{\n\t\t\t\tEMC(EMC_RP) = src_emc_entry->burst_regs.emc_rp_idx;\n\t\t\t\tEMC(EMC_R2P) = src_emc_entry->burst_regs.emc_r2p_idx;\n\t\t\t\tEMC(EMC_W2P) = src_emc_entry->burst_regs.emc_w2p_idx;\n\t\t\t\tEMC(EMC_TRPAB) = src_emc_entry->burst_regs.emc_trpab_idx;\n\t\t\t}\n\t\t\t_timing_update(dual_channel);\n\n\t\t}\n\t\tdst_emc_entry->trained = 1;\n\t\tEPRINTF(\"Trained\");\n\t}\n\n\tif (switch_rate)\n\t\t_minerva_set_clock(src_emc_entry, dst_emc_entry, 0, selected_clk_src_emc);\n}\n\nvoid _minerva_do_over_temp_compensation(mtc_config_t *mtc_cfg)\n{\n\ts32 dram_type = EMC(EMC_FBIO_CFG5) & 3;\n\n\t// Only LPDDR chips are supported.\n\tif (dram_type != DRAM_TYPE_LPDDR2 && dram_type != DRAM_TYPE_LPDDR4)\n\t\treturn;\n\n\ts32 dram_temp = _get_dram_temperature();\n\n\tif (mtc_cfg->prev_temp == dram_temp || dram_temp < 0)\n\t\treturn;\n\n\tu32 refr = mtc_cfg->current_emc_table->burst_regs.emc_refresh_idx;\n\tu32 pre_refr = mtc_cfg->current_emc_table->burst_regs.emc_pre_refresh_req_cnt_idx;\n\tu32 dyn_self_ref = mtc_cfg->current_emc_table->burst_regs.emc_dyn_self_ref_control_idx;\n\n\tswitch (dram_temp)\n\t{\n\t// Normal temp (<= 85 oC).\n\tcase 0:\n\tcase 1:\n\tcase 2:\n\tcase 3:\n\t\tif (mtc_cfg->prev_temp < 4)\n\t\t{\n\t\t\tmtc_cfg->prev_temp = dram_temp;\n\t\t\treturn;\n\t\t}\n\t\tbreak;\n\t// Over temp (> 85 oC).\n\tcase 4: // \n\t\trefr = (refr & 0xFFFF0000) | ((refr & 0xFFFF) >> REFRESH_X2);\n\t\tpre_refr = (pre_refr & 0xFFFF0000) | ((pre_refr & 0xFFFF) >> REFRESH_X2);\n\t\tdyn_self_ref = (dyn_self_ref & 0xFFFF0000) | ((dyn_self_ref & 0xFFFF) >> REFRESH_X2);\n\t\tbreak;\n\tcase 5:\n\tcase 6: // Temp 6 normally needs a derating emc table.\n\t\trefr = (refr & 0xFFFF0000) | ((refr & 0xFFFF) >> REFRESH_X4);\n\t\tpre_refr = (pre_refr & 0xFFFF0000) | ((pre_refr & 0xFFFF) >> REFRESH_X4);\n\t\tdyn_self_ref = (dyn_self_ref & 0xFFFF0000) | ((dyn_self_ref & 0xFFFF) >> REFRESH_X4);\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\tmtc_cfg->prev_temp = dram_temp;\n\n\tEMC(EMC_REFRESH) = refr;\n\tEMC(EMC_PRE_REFRESH_REQ_CNT) = pre_refr;\n\tEMC(EMC_DYN_SELF_REF_CONTROL) = dyn_self_ref;\n}\n\nu32 _minerva_do_periodic_compensation(emc_table_t *mtc_table_entry)\n{\n\tif (mtc_table_entry && mtc_table_entry->periodic_training)\n\t{\n\t\tu32 val = 0;\n\t\ts32  dram_dev_num = (MC(MC_EMEM_ADR_CFG) & 1) + 1;\n\t\tbool channel1_enabled = (mtc_table_entry->burst_regs.emc_fbio_cfg7_idx >> 2) & 1;\n\n\t\t//u32 emc_dbg_o = EMC(EMC_DBG);\n\t\tu32 emc_cfg_o = EMC(EMC_CFG);\n\t\tu32 emc_cfg = emc_cfg_o & 0xFFFFFFF;\n\n\t\t// Step 1 - Disable other power features.\n\t\tEMC(EMC_CFG) = emc_cfg;\n\n\t\t_digital_dll_disable();\n\n\t\tif (dram_dev_num == TWO_RANK)\n\t\t{\n\t\t\t_wait_emc_status(EMC_EMC_STATUS, IN_POWERDOWN_MASK, 0, EMC_CH0);\n\t\t\tif (channel1_enabled)\n\t\t\t\t_wait_emc_status(EMC_EMC_STATUS, IN_POWERDOWN_MASK, 0, channel1_enabled);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t_wait_emc_status(EMC_EMC_STATUS, 0x10, 0, 0);\n\t\t\tif (channel1_enabled)\n\t\t\t\t_wait_emc_status(EMC_EMC_STATUS, 0x10, 0, channel1_enabled);\n\t\t}\n\n\t\t_wait_emc_status(EMC_EMC_STATUS, IN_SELF_REFRESH_MASK, 0, EMC_CH0);\n\t\tif (channel1_enabled)\n\t\t\t_wait_emc_status(EMC_EMC_STATUS, IN_SELF_REFRESH_MASK, 0, channel1_enabled);\n\n\t\t//_wait_emc_status(EMC_EMC_STATUS, REQ_FIFO_EMPTY, 0, EMC_CH0); //v1.6\n\t\t//if (channel1_enabled)\n\t\t//\t_wait_emc_status(EMC_EMC_STATUS, REQ_FIFO_EMPTY, 0, channel1_enabled); //v1.6\n\n\t\tu32 emc_cfg_update = EMC(EMC_CFG_UPDATE);\n\t\tEMC(EMC_CFG_UPDATE) = (emc_cfg_update & 0xFFFFF9FF) | 0x400;\n\n\t\t// Step 2 - Osc kick off - this assumes training and dvfs have set correct MR23.\n\t\t_start_periodic_compensation();\n\n\t\t// Step 3 - Let dram capture its clock tree delays.\n\t\t_usleep(1000 * _actual_osc_clocks(mtc_table_entry->run_clocks) / mtc_table_entry->rate_khz + 1);\n\n\t\t// Step 4 - Check delta wrt previous values (save value if margin exceeds what is set in table).\n\t\tu32 adel = _minerva_update_clock_tree_delay(mtc_table_entry, mtc_table_entry, dram_dev_num, channel1_enabled, PERIODIC_TRAINING_UPDATE);\n\n\t\t// Step 5 - Apply compensation w.r.t. trained values (if clock tree has drifted more than the set margin).\n\t\tif (adel && ((mtc_table_entry->rate_khz / 1000) << 7) * adel / 1000000 > mtc_table_entry->tree_margin)\n\t\t{\n\t\t\tfor (u32 i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tval = _minerva_apply_periodic_compensation_trimmer(mtc_table_entry, periodic_training_addr[i]);\n\t\t\t\tEMC(periodic_training_addr[i]) = val;\n\t\t\t}\n\t\t}\n\n\t\tEMC(EMC_CFG) = emc_cfg_o;\n\n\t\t// Step 6 - Timing update to apply the new trimmers.\n\t\t_timing_update(channel1_enabled);\n\n\t\t// Step 6.1 - Restore the UPDATE_DLL_IN_UPDATE field.\n\t\tEMC(EMC_CFG_UPDATE) = emc_cfg_update;\n\n\t\t// Step 6.2 - Restore the DLL.\n\t\t_digital_dll_enable(channel1_enabled);\n\t}\n\n\treturn 0;\n}\n\ns32 _minerva_set_rate(mtc_config_t *mtc_cfg)\n{\n\ts32 src_emc_entry_idx = 0;\n\ts32 dst_emc_entry_idx = 999;\n\ts32 table_entry_rate;\n\tu32 selected_clk_src_emc;\n\tu32 selected_emc_2x_clk_src;\n\tbool freq_changed = false;\n\temc_table_t *src_emc_entry;\n\temc_table_t *dst_emc_entry;\n\n\tfor (s32 i = 0; i < mtc_cfg->table_entries; i++)\n\t{\n\t\ttable_entry_rate = mtc_cfg->mtc_table[i].rate_khz;\n\t\tif (mtc_cfg->rate_from == table_entry_rate)\n\t\t\tsrc_emc_entry_idx = i;\n\t\tif (mtc_cfg->rate_to == table_entry_rate)\n\t\t\tdst_emc_entry_idx = i;\n\t}\n\tsrc_emc_entry = (emc_table_t *)&mtc_cfg->mtc_table[src_emc_entry_idx];\n\tdst_emc_entry = (emc_table_t *)&mtc_cfg->mtc_table[dst_emc_entry_idx];\n\ts32 src_rate_khz = src_emc_entry->rate_khz;\n\ts32 dst_rate_khz = dst_emc_entry->rate_khz;\n\tu32 src_clk_src_emc = src_emc_entry->clk_src_emc;\n\tu32 dst_clk_src_emc = dst_emc_entry->clk_src_emc;\n\tif (mtc_cfg->table_entries > 900)\n\t\treturn 4;\n\n\tfreq_changed = _check_freq_changed(dst_rate_khz, dst_clk_src_emc, src_rate_khz, src_clk_src_emc);\n\tEPRINTFARGS(\"Requested freq change from %d to %d.\", src_rate_khz, dst_rate_khz);\n\n\tif (freq_changed)\n\t{\n\t\tselected_emc_2x_clk_src = src_clk_src_emc >> EMC_2X_CLK_SRC_SHIFT;\n\t\tif (selected_emc_2x_clk_src & 3)\n\t\t{\n\t\t\tif (selected_emc_2x_clk_src - PLLMB_UD <= 1)\n\t\t\t\temc_2X_clk_src_is_pllmb = 0;\n\t\t}\n\t\telse\n\t\t{\n\t\t\temc_2X_clk_src_is_pllmb = !emc_2X_clk_src_is_pllmb;\n\t\t}\n\t\tselected_clk_src_emc = _pllm_clk_base_cfg(dst_rate_khz, dst_clk_src_emc, emc_2X_clk_src_is_pllmb);\n\t}\n\telse\n\t{\n\t\tselected_clk_src_emc = dst_clk_src_emc;\n\t\tselected_emc_2x_clk_src = selected_clk_src_emc >> EMC_2X_CLK_SRC_SHIFT;\n\t\tif (selected_emc_2x_clk_src != PLLMB_OUT0 && selected_emc_2x_clk_src)\n\t\t{\n\t\t\tif (selected_emc_2x_clk_src - PLLM_UD <= PLLC_OUT0 && emc_2X_clk_src_is_pllmb)\n\t\t\t\tselected_clk_src_emc = (selected_clk_src_emc & 0x1FFFFFFF) | (PLLMB_UD << EMC_2X_CLK_SRC_SHIFT);\n\t\t}\n\t\telse if (emc_2X_clk_src_is_pllmb)\n\t\t{\n\t\t\tselected_clk_src_emc = (selected_clk_src_emc & 0x1FFFFFFF) | (PLLMB_OUT0 << EMC_2X_CLK_SRC_SHIFT);\n\t\t}\n\t}\n\n\tswitch (mtc_cfg->train_mode)\n\t{\n\tcase OP_SWITCH:\n\t\t_minerva_set_clock(src_emc_entry, dst_emc_entry, 0, selected_clk_src_emc);\n\t\tmtc_cfg->current_emc_table = dst_emc_entry;\n\t\tmtc_cfg->rate_from = dst_emc_entry->rate_khz;\n\t\tif (dst_emc_entry->periodic_training)\n\t\t\t_minerva_do_periodic_compensation(dst_emc_entry);\n\t\treturn 0;\n\tcase OP_TRAIN:\n\t\t_minerva_train_patterns(src_emc_entry, dst_emc_entry, false, selected_clk_src_emc);\n\t\tif (freq_changed)\n\t\t\temc_2X_clk_src_is_pllmb = !emc_2X_clk_src_is_pllmb;\n\t\treturn 0;\n\tcase OP_TRAIN_SWITCH:\n\t\t_minerva_train_patterns(src_emc_entry, dst_emc_entry, true, selected_clk_src_emc);\n\t\tmtc_cfg->current_emc_table = dst_emc_entry;\n\t\tmtc_cfg->rate_from = dst_emc_entry->rate_khz;\n\t\tif (dst_emc_entry->periodic_training)\n\t\t\t_minerva_do_periodic_compensation(dst_emc_entry);\n\t\treturn 0;\n\tdefault:\n\t\treturn 4;\n\t}\n}\n\nstatic void _minerva_get_table(mtc_config_t *mtc_cfg)\n{\n\tswitch (mtc_cfg->sdram_id)\n\t{\n\tcase 1:\n\t\tmemcpy((void *)MTC_TABLE, nx_abca2_2_10NoCfgVersion_V9_8_7_V1_6, EMC_TABLE_SIZE_R7);\n\t\tbreak;\n\tcase 0:\n\tcase 2:\n\tcase 3:\n\tcase 4:\n\tdefault:\n\t\tmemcpy((void *)MTC_TABLE, nx_abca2_0_3_10NoCfgVersion_V9_8_7_V1_6, EMC_TABLE_SIZE_R7);\n\t\tbreak;\n\t}\n\n\tmtc_cfg->mtc_table = (emc_table_t *)MTC_TABLE;\n\n\tmtc_cfg->table_entries = 10;\n\tmtc_cfg->rate_to = 0;\n\tmtc_cfg->rate_from = 0;\n\tmtc_cfg->train_mode = 0;\n\tmtc_cfg->prev_temp = 0;\n\tmtc_cfg->current_emc_table = NULL;\n\n\t// Important!\n\tmtc_cfg->emc_2X_clk_src_is_pllmb = false;\n\tmtc_cfg->fsp_for_src_freq = false;\n\tmtc_cfg->train_ram_patterns = true;\n}\n\nvoid _minerva_init(mtc_config_t *mtc_cfg, void* bp)\n{\n\tEPRINTF(\"-- Minerva Training Cell --\");\n\t\n\ttrain_ram_patterns = mtc_cfg->train_ram_patterns;\n\tfsp_for_src_freq = mtc_cfg->fsp_for_src_freq;\n\temc_2X_clk_src_is_pllmb = mtc_cfg->emc_2X_clk_src_is_pllmb;\n\n\tif (!mtc_cfg->mtc_table)\n\t{\n\t\t_minerva_get_table(mtc_cfg);\n\t\treturn;\n\t}\n\t\n\t// If this is set, it need to be managed. Changing freq from OC to a lower\n\t// must have the rate_from set to 2131200 and not 1600000\n\t// bool overclock = true;\n\t\n\t// if (overclock && mtc_cfg->rate_to == 1600000)\n\t// {\n\t// \t\tmtc_cfg->rate_to = 2131200;\n\t// \t\tmtc_cfg->mtc_table[9].rate_khz = 2131200;\n\t// }\n\n\tswitch (mtc_cfg->train_mode)\n\t{\n\tcase OP_SWITCH:\n\t\tEPRINTF(\"Switching..\");\n\t\t_minerva_set_rate(mtc_cfg);\n\t\tbreak;\n\tcase OP_TRAIN:\n\t\tEPRINTF(\"Training..\");\n\t\t_minerva_set_rate(mtc_cfg);\n\t\tbreak;\n\tcase OP_TRAIN_SWITCH:\n\t\tEPRINTF(\"Training and switching..\");\n\t\t_minerva_set_rate(mtc_cfg);\n\t\tbreak;\n\tcase OP_PERIODIC_TRAIN:\n\t\tEPRINTF(\"Periodic training..\");\n\t\t_minerva_do_periodic_compensation(mtc_cfg->current_emc_table);\n\t\tbreak;\n\tcase OP_TEMP_COMP:\n\t\tEPRINTF(\"Over temperature compensation..\");\n\t\t_minerva_do_over_temp_compensation(mtc_cfg);\n\t\tbreak;\n\t}\n\n\tmtc_cfg->train_ram_patterns = train_ram_patterns;\n\tmtc_cfg->fsp_for_src_freq = fsp_for_src_freq;\n\tmtc_cfg->emc_2X_clk_src_is_pllmb = emc_2X_clk_src_is_pllmb;\n}\n"
  },
  {
    "path": "modules/minerva/types.h",
    "content": "/*\n* Copyright (c) 2018 naehrwert\n*\n* This program is free software; you can redistribute it and/or modify it\n* under the terms and conditions of the GNU General Public License,\n* version 2, as published by the Free Software Foundation.\n*\n* This program is distributed in the hope it will be useful, but WITHOUT\n* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n* more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#ifndef _TYPES_H_\n#define _TYPES_H_\n\n#define NULL ((void *)0)\n\n#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))\n#define MAX(a, b) ((a) > (b) ? (a) : (b))\n#define MIN(a, b) ((a) < (b) ? (a) : (b))\n\n#define OFFSET_OF(t, m) ((u32)&((t *)NULL)->m)\n#define CONTAINER_OF(mp, t, mn) ((t *)((u32)mp - OFFSET_OF(t, mn)))\n\ntypedef char s8;\ntypedef short s16;\ntypedef short SHORT;\ntypedef int s32;\ntypedef int INT;\ntypedef long LONG;\ntypedef long long int s64;\ntypedef unsigned char u8;\ntypedef unsigned char BYTE;\ntypedef unsigned short u16;\ntypedef unsigned short WORD;\ntypedef unsigned short WCHAR;\ntypedef unsigned int u32;\ntypedef unsigned int UINT;\ntypedef unsigned long DWORD;\ntypedef unsigned long long QWORD;\ntypedef unsigned long long int u64;\ntypedef volatile unsigned char vu8;\ntypedef volatile unsigned short vu16;\ntypedef volatile unsigned int vu32;\n\ntypedef int bool;\n#define true  1\n#define false 0\n\n#endif\n"
  },
  {
    "path": "scripts/argon.py",
    "content": "from pathlib import Path\n\nimport click\nfrom PIL import Image\nfrom PIL import ImageDraw\nfrom wand.image import Image as WI\n\n\nDST_PATH = 'sd-files/argon'\n\ndef add_corners(im, rad):\n    circle = Image.new('L', (rad * 2, rad * 2), 0)\n    draw = ImageDraw.Draw(circle)\n    draw.ellipse((0, 0, rad * 2, rad * 2), fill=255)\n    alpha = Image.new('L', im.size, 255)\n    w, h = im.size\n    alpha.paste(circle.crop((0, 0, rad, rad)), (0, 0))\n    alpha.paste(circle.crop((0, rad, rad, rad * 2)), (0, h - rad))\n    alpha.paste(circle.crop((rad, 0, rad * 2, rad)), (w - rad, 0))\n    alpha.paste(circle.crop((rad, rad, rad * 2, rad * 2)), (w - rad, h - rad))\n    im.putalpha(alpha)\n    return im\n\n\ndef to_bmp(img, size):\n    img.resize(*size)\n    img.alpha_channel = True\n    return img.convert('BMP')\n\n\n@click.group()\ndef main():\n    pass\n\n\n@main.command()\n@click.argument('img-path', type=click.Path(exists=True, dir_okay=False))\n@click.option('--round/--no-round', default=False, help=\"Round image corners?\")\ndef img_to_logo(img_path, round):\n    img_path = Path(img_path)\n    img_name = img_path.stem\n    fname = Path('{}.bmp'.format(img_name))\n    out_path = str(logos_dst_path.joinpath(fname))\n\n    # Preprocess image using pillow\n    im = Image.open(img_path)\n    im = im.resize((280, 280))\n    im = im.convert('RGBA')\n\n    if round:\n        im = add_corners(im, 30)\n\n    # Save image as a temp file\n    im.save('./.tmp.png')\n\n    # Reload image and convert it to 32 bmp bit format\n    with WI(filename='./.tmp.png') as img:\n        with img.convert('BMP') as i:\n            i.save(filename=out_path)\n\n    # Remove the tmp file\n    Path('./.tmp.png').unlink()\n\n    print('Convertion done. Check your new logo here: {}'.format(out_path))\n    \n\n@main.command()\n@click.argument('img-path', type=click.Path(exists=True, dir_okay=False))\ndef generate_background(img_path):\n    out_path = str(dst_path.joinpath('background.bmp'))\n    with WI(filename=img_path) as img:\n        im = to_bmp(img, (1280, 720))\n        i.save(filename=out_path)\n\n    print('Convertion done. Check your new background here: {}'.format(out_path))\n\n\n@main.command()\n@click.argument('img-path', type=click.Path(exists=True, dir_okay=False))\ndef generate_splash(img_path):\n    out_path = str(dst_path.joinpath('splash.bmp'))\n    with WI(filename=img_path) as img:\n        im = to_bmp(img, (1280, 720))\n        im.rotate(270)\n        im.save(filename=out_path)\n\n    print('Convertion done. Check your new splash here: {}'.format(out_path))\n \nif __name__ == '__main__':\n    dst_path = Path(DST_PATH)\n    logos_dst_path = dst_path.joinpath('logos')\n    logos_dst_path.mkdir(exist_ok=True, parents=True)\n\n    main()"
  },
  {
    "path": "scripts/requirements.txt",
    "content": "Click==7.0\nPillow==9.0.1\nWand==0.5.6\n"
  }
]