docs_rombanking_mbcs.html (22858B)
1<!-- HTML header for doxygen 1.8.14--> 2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 3<html xmlns="http://www.w3.org/1999/xhtml"> 4<head> 5<meta http-equiv="cache-control" content="max-age=86400"/> 6<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> 7<meta http-equiv="X-UA-Compatible" content="IE=9"/> 8<meta name="generator" content="Doxygen 1.8.20"/> 9<meta name="viewport" content="width=device-width, initial-scale=1"/> 10<title>GBDK 2020 Docs: ROM/RAM Banking and MBCs</title> 11<link href="tabs.css" rel="stylesheet" type="text/css"/> 12<script type="text/javascript" src="jquery.js"></script> 13<script type="text/javascript" src="dynsections.js"></script> 14<link href="navtree.css" rel="stylesheet" type="text/css"/> 15<script type="text/javascript" src="resize.js"></script> 16<script type="text/javascript" src="navtreedata.js"></script> 17<script type="text/javascript" src="navtree.js"></script> 18<link href="search/search.css" rel="stylesheet" type="text/css"/> 19<script type="text/javascript" src="search/searchdata.js"></script> 20<script type="text/javascript" src="search/search.js"></script> 21<link href="doxygen.css" rel="stylesheet" type="text/css" /> 22<link href="doxygen_extra.css" rel="stylesheet" type="text/css"/> 23</head> 24<body> 25<div id="top"><!-- do not remove this div, it is closed by doxygen! --> 26<div id="titlearea"> 27<table cellspacing="0" cellpadding="0"> 28 <tbody> 29 <tr style="height: 56px;"> 30 <td id="projectalign" style="padding-left: 0.5em;"> 31 <div id="projectname">GBDK 2020 Docs 32  <span id="projectnumber">4.0.6</span> 33 </div> 34 <div id="projectbrief">API Documentation for GBDK 2020</div> 35 </td> 36 </tr> 37 </tbody> 38</table> 39</div> 40<!-- end header part --> 41<!-- Generated by Doxygen 1.8.20 --> 42<script type="text/javascript"> 43/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */ 44var searchBox = new SearchBox("searchBox", "search",false,'Search'); 45/* @license-end */ 46</script> 47<script type="text/javascript" src="menudata.js"></script> 48<script type="text/javascript" src="menu.js"></script> 49<script type="text/javascript"> 50/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */ 51$(function() { 52 initMenu('',true,false,'search.php','Search'); 53 $(document).ready(function() { init_search(); }); 54}); 55/* @license-end */</script> 56<div id="main-nav"></div> 57</div><!-- top --> 58<div id="side-nav" class="ui-resizable side-nav-resizable"> 59 <div id="nav-tree"> 60 <div id="nav-tree-contents"> 61 <div id="nav-sync" class="sync"></div> 62 </div> 63 </div> 64 <div id="splitbar" style="-moz-user-select:none;" 65 class="ui-resizable-handle"> 66 </div> 67</div> 68<script type="text/javascript"> 69/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */ 70$(document).ready(function(){initNavTree('docs_rombanking_mbcs.html',''); initResizable(); }); 71/* @license-end */ 72</script> 73<div id="doc-content"> 74<!-- window showing the filter options --> 75<div id="MSearchSelectWindow" 76 onmouseover="return searchBox.OnSearchSelectShow()" 77 onmouseout="return searchBox.OnSearchSelectHide()" 78 onkeydown="return searchBox.OnSearchSelectKey(event)"> 79</div> 80 81<!-- iframe showing the search results (closed by default) --> 82<div id="MSearchResultsWindow"> 83<iframe src="javascript:void(0)" frameborder="0" 84 name="MSearchResults" id="MSearchResults"> 85</iframe> 86</div> 87 88<div class="PageDoc"><div class="header"> 89 <div class="headertitle"> 90<div class="title">ROM/RAM Banking and MBCs </div> </div> 91</div><!--header--> 92<div class="contents"> 93<div class="textblock"><h1><a class="anchor" id="autotoc_md73"></a> 94ROM/RAM Banking and MBCs (Memory Bank Controllers)</h1> 95<p>The standard Game Boy cartridge with no MBC has a fixed 32K bytes of ROM. In order to make cartridges with larger ROM sizes (to store more code and graphics) MBCs can be used. They allow switching between multiple ROM banks that use the same memory region. Only one of the banks can be selected as active at a given time, while all the other banks are inactive (and so, inaccessible).</p> 96<h2><a class="anchor" id="autotoc_md74"></a> 97Non-banked cartridges</h2> 98<p>Cartridges with no MBC controller are non-banked, they have 32K bytes of fixed ROM space and no switchable banks. For these cartridges the ROM space between <code>0000h and 7FFFh</code> can be treated as a single large bank of 32K bytes, or as two contiguous banks of 16K bytes in Bank 0 at <code>0000h - 3FFFh</code> and Bank 1 at <code>4000h to 7FFFh</code>.</p> 99<h2><a class="anchor" id="autotoc_md75"></a> 100MBC Banked cartridges (Memory Bank Controllers)</h2> 101<p><a class="anchor" id="MBC"></a><a class="anchor" id="MBCS"></a>Cartridges with MBCs allow the the Game Boy to work with ROMS up to 8MB in size and with RAM up to 128kB. Each bank is 16K Bytes.</p><ul> 102<li>Bank 0 of the ROM is located in the region at <code>0000h - 3FFFh</code>. It is <em>usually</em> fixed (non-banked) and cannot be switched out for another bank.</li> 103<li>The higher region at <code>4000h to 7FFFh</code> is used for switching between different ROM banks.</li> 104</ul> 105<p>See the <a class="el" href="docs_links_and_tools.html#Pandocs">Pandocs</a> for more details about the individual MBCs and their capabilities.</p> 106<h1><a class="anchor" id="autotoc_md76"></a> 107Working with Banks</h1> 108<p>To assign code and constant data (such as graphics) to a ROM bank and use it:</p><ul> 109<li>Place the code for your ROM bank in one or several source files.</li> 110<li>Specify the ROM bank to use, either in the source file or at compile/link time.</li> 111<li>Specify the number of banks and MBC type during link time.</li> 112<li>When the program is running and wants to use data or call a function that is in a given bank, manually or automatically set the desired bank to active.</li> 113</ul> 114<h2><a class="anchor" id="autotoc_md77"></a> 115Setting the ROM bank for a Source file</h2> 116<p>The ROM and RAM bank for a source file can be set in a couple different ways. Multiple different banks cannot be assigned inside the same source file (unless the <code>__addressmod</code> method is used), but multiple source files can share the same bank.</p> 117<p>If no ROM and RAM bank are speciied for a file then the default _CODE, _BSS and _DATA segments are used.</p> 118<p>Ways to set the ROM bank for a Source file</p><ul> 119<li><code>#pragma bank <N></code> at the start of a source file. Example (ROM bank 2): <code>#pragma bank 2</code></li> 120<li>The lcc switch for ROM bank <code>-Wf-bo<N></code>. Example (ROM bank 2): <code>-Wf-bo2</code></li> 121<li>Using <a class="el" href="docs_rombanking_mbcs.html#rom_autobanking">rom_autobanking</a></li> 122</ul> 123<p>Note: You can use the <code>NONBANKED</code> keyword to define a function as non-banked if it resides in a source file which has been assigned a bank.</p> 124<h2><a class="anchor" id="autotoc_md78"></a> 125Setting the RAM bank for a Source file</h2> 126<ul> 127<li>Using the lcc switch for RAM bank <code>-Wf-ba<N></code>. Example (ROM bank 3): <code>-Wf-bo3</code></li> 128</ul> 129<p><a class="anchor" id="setting_mbc_and_rom_ram_banks"></a></p> 130<h2><a class="anchor" id="autotoc_md79"></a> 131Setting the MBC and number of ROM & RAM banks available</h2> 132<p>At the link stage this is done with <a class="el" href="docs_toolchain.html#lcc">lcc</a> using pass-through switches for <a class="el" href="docs_toolchain.html#makebin">makebin</a>.</p><ul> 133<li><code>-Wl-yo<N></code> where <code><N></code> is the number of ROM banks. 2, 4, 8, 16, 32, 64, 128, 256, 512<ul> 134<li><code>-Wl-yoA</code> may be used for automatic bank size.</li> 135</ul> 136</li> 137<li><code>-Wl-ya<N></code> where <code><N></code> is the number of RAM banks. 2, 4, 8, 16, 32</li> 138<li><code>-Wl-yt<N></code> where <code><N></code> is the type of MBC cartridge (see below).<ul> 139<li>Example: <code>Wl-yt0x1A</code></li> 140</ul> 141</li> 142</ul> 143<p>The MBC settings below are available when using the makebin MBC switch.</p> 144<p>Additional details available at <a href="https://gbdev.io/pandocs/The_Cartridge_Header.html#0147---cartridge-type" title="Pandocs">Pandocs</a></p> 145<div class="fragment"><div class="line"># From Makebin source:</div> 146<div class="line">#</div> 147<div class="line">#-Wl-yt<NN> where <NN> is one of the numbers below</div> 148<div class="line">#</div> 149<div class="line"># 0147: Cartridge type:</div> 150<div class="line"># 0-ROM ONLY 12-ROM+MBC3+RAM</div> 151<div class="line"># 1-ROM+MBC1 13-ROM+MBC3+RAM+BATT</div> 152<div class="line"># 2-ROM+MBC1+RAM 19-ROM+MBC5</div> 153<div class="line"># 3-ROM+MBC1+RAM+BATT 1A-ROM+MBC5+RAM</div> 154<div class="line"># 5-ROM+MBC2 1B-ROM+MBC5+RAM+BATT</div> 155<div class="line"># 6-ROM+MBC2+BATTERY 1C-ROM+MBC5+RUMBLE</div> 156<div class="line"># 8-ROM+RAM 1D-ROM+MBC5+RUMBLE+SRAM</div> 157<div class="line"># 9-ROM+RAM+BATTERY 1E-ROM+MBC5+RUMBLE+SRAM+BATT</div> 158<div class="line"># B-ROM+MMM01 1F-Pocket Camera</div> 159<div class="line"># C-ROM+MMM01+SRAM FD-Bandai TAMA5</div> 160<div class="line"># D-ROM+MMM01+SRAM+BATT FE - Hudson HuC-3</div> 161<div class="line"># F-ROM+MBC3+TIMER+BATT FF - Hudson HuC-1</div> 162<div class="line"># 10-ROM+MBC3+TIMER+RAM+BATT</div> 163<div class="line"># 11-ROM+MBC3</div> 164</div><!-- fragment --><h2><a class="anchor" id="autotoc_md80"></a> 165Getting Bank Numbers</h2> 166<p>The bank number for a banked function, variable or source file can be stored and retrieved using the following macros:</p><ul> 167<li><a class="el" href="gb_8h.html#a086293f2afb4c7945460a4496b20aea3">BANKREF()</a>: Create a reference for retrieving the bank number of a variable or function</li> 168<li><a class="el" href="gb_8h.html#a42705001e2b9897f5167b67fb36c69dd">BANK()</a>: Retrieve a bank number using a reference created with <a class="el" href="gb_8h.html#a086293f2afb4c7945460a4496b20aea3">BANKREF()</a></li> 169<li><a class="el" href="gb_8h.html#a261bba55a07b802baf99346feadd9852">BANKREF_EXTERN()</a> - Make a <a class="el" href="gb_8h.html#a086293f2afb4c7945460a4496b20aea3">BANKREF()</a> reference residing in another source file accessible in the current file for use with <a class="el" href="gb_8h.html#a42705001e2b9897f5167b67fb36c69dd">BANK()</a>.</li> 170</ul> 171<h2><a class="anchor" id="autotoc_md81"></a> 172Banking and Functions</h2> 173<p><a class="anchor" id="banked_keywords"></a></p> 174<h3><a class="anchor" id="autotoc_md82"></a> 175BANKED/NONBANKED keywords</h3> 176<ul> 177<li><code>BANKED</code>:<ul> 178<li>The function will use banked sdcc calls</li> 179<li>Placed in the bank selected by it's source file (or compiler switches)</li> 180</ul> 181</li> 182<li><code>NONBANKED</code>:<ul> 183<li>Placed in the non-banked lower 16K region (bank 0), regardless of the bank selected by it's source file.</li> 184</ul> 185</li> 186<li><code><not-specified></code>:<ul> 187<li>The function does not use sdcc banked calls (<code>near</code> instead of <code>far</code>)</li> 188<li>Placed in the bank selected by it's source file (or compiler switches)</li> 189</ul> 190</li> 191</ul> 192<p><a class="anchor" id="banked_calls"></a></p> 193<h3><a class="anchor" id="autotoc_md83"></a> 194Banked Function Calls</h3> 195<p>Banked functions can be called as follows.</p><ul> 196<li>When defined with the <code>BANKED</code> keyword. Example: <code>void my_function() BANKED { do stuff }</code> in a source file which has had it's bank set (see above).</li> 197<li>Using <a class="el" href="docs_rombanking_mbcs.html#far_pointers">far_pointers</a></li> 198<li>When defined with an area set up using the <code>__addressmod</code> keyword (See the <code>banks_new</code> example project and the SDCC manual for details)</li> 199<li>Using <a class="el" href="gb_8h.html#a1e22a3b60368bb5f3705d625ac2d09cc">SWITCH_ROM()</a> (and related functions for other MBCs) to manually switch in the required bank and then call the function.</li> 200</ul> 201<p>Non-banked functions (either in fixed Bank 0, or in an non-banked ROM with no MBC)</p><ul> 202<li>May call functions in any bank: <b>YES</b></li> 203<li>May use data in any bank: <b>YES</b></li> 204</ul> 205<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000004">Todo:</a></b></dt><dd>Fill in this info for Banked Functions Banked functions (located in a switchable ROM bank)<ul> 206<li>May call functions in any bank: ?</li> 207<li>May use data in any bank: <b>NO</b> (may only use data from currently active banks)</li> 208</ul> 209</dd></dl> 210<p>Limitations:</p><ul> 211<li>SDCC banked calls and far_pointers in GBDK only save one byte for the ROM bank. So, for example, they are limtied to <b>bank 31</b> max for MBC1 and <b>bank 255</b> max for MBC5. This is due to the bank switching for those MBCs requiring a second, additional write to select the upper bits for more banks (banks 32+ in MBC1 and banks 256+ in MBC5).</li> 212</ul> 213<h2><a class="anchor" id="autotoc_md84"></a> 214Const Data (Variables in ROM)</h2> 215<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000005">Todo:</a></b></dt><dd>Const Data (Variables in ROM)</dd></dl> 216<h2><a class="anchor" id="autotoc_md85"></a> 217Variables in RAM</h2> 218<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000006">Todo:</a></b></dt><dd>Variables in RAM</dd></dl> 219<h2><a class="anchor" id="autotoc_md86"></a> 220Far Pointers</h2> 221<p><a class="anchor" id="far_pointers"></a>Far pointers include a segment (bank) selector so they are able to point to addresses (functions or data) outside of the current bank (unlike normal pointers which are not bank-aware). A set of macros is provided by GBDK 2020 for working with far pointers.</p> 222<p><b>Warning:</b> Do not call the far pointer function macros from inside interrupt routines (ISRs). The far pointer function macros use a global variable that would not get restored properly if a function called that way was interrupted by another one called the same way. However, they may be called recursively.</p> 223<p>See <a class="el" href="far__ptr_8h.html#a7f4ab1893ea392f8bf042a3b97de4730">FAR_CALL</a>, <a class="el" href="far__ptr_8h.html#a0c227677a96f9bf7e84a90922f2f8708">TO_FAR_PTR</a> and the <code>banks_farptr</code> example project.</p> 224<h2><a class="anchor" id="autotoc_md87"></a> 225Bank switching</h2> 226<p>You can manually switch banks using the <a class="el" href="gb_8h.html#a1e22a3b60368bb5f3705d625ac2d09cc">SWITCH_ROM()</a>, <a class="el" href="gb_8h.html#a6e40dcc763efd953181c7400642a9f69">SWITCH_RAM()</a>, and other related macros. See <code>banks.c</code> project for an example.</p> 227<p>Note: You can only do a switch_rom_bank call from non-banked <code>_CODE</code> since otherwise you would switch out the code that was executing. Global routines that will be called without an expectation of bank switching should fit within the limited 16k of non-banked <code>_CODE</code>.</p> 228<h2><a class="anchor" id="autotoc_md88"></a> 229Restoring the current bank (after calling functions which change it without restoring)</h2> 230<p><a class="anchor" id="banking_current_bank"></a>If a function call is made (for example inside an ISR) which changes the bank <em>without</em> restoring it, then the <a class="el" href="gb_8h.html#a98b848953a95ce2fff6fda643575d74a">_current_bank</a> variable should be saved and then restored.</p> 231<p>For example, <b>instead</b> of this code: </p><div class="fragment"><div class="line">void vbl_music_isr(void)</div> 232<div class="line">{</div> 233<div class="line"> // A function which changes the bank and</div> 234<div class="line"> // *doesn't* restore it after changing.</div> 235<div class="line"> some_function();</div> 236<div class="line">}</div> 237</div><!-- fragment --><p>It should be: </p><div class="fragment"><div class="line">void vbl_music_isr(void)</div> 238<div class="line">{</div> 239<div class="line"> // Save the current bank</div> 240<div class="line"> uint8_t _saved_bank = _current_bank;</div> 241<div class="line"> </div> 242<div class="line"> // A function which changes the bank and</div> 243<div class="line"> // *doesn't* restore it after changing.</div> 244<div class="line"> some_function();</div> 245<div class="line"> </div> 246<div class="line"> // Now restore the current bank</div> 247<div class="line"> SWITCH_ROM(_saved_bank);</div> 248<div class="line">}</div> 249</div><!-- fragment --><h2><a class="anchor" id="autotoc_md89"></a> 250Currently active bank: _current_bank</h2> 251<p>The global variable <a class="el" href="gb_8h.html#a98b848953a95ce2fff6fda643575d74a">_current_bank</a> is updated automatically when calling <a class="el" href="gb_8h.html#a1e22a3b60368bb5f3705d625ac2d09cc">SWITCH_ROM()</a>, <a class="el" href="gb_8h.html#a19558f5bbc9fea767f945001ae9cd13f">SWITCH_ROM_MBC1()</a> and <a class="el" href="gb_8h.html#a92d040284342702026eb19dab59b586e">SWITCH_ROM_MBC5</a>, or when a <code>BANKED</code> function is called.</p> 252<p><a class="anchor" id="rom_autobanking"></a></p> 253<h1><a class="anchor" id="autotoc_md90"></a> 254Auto-Banking</h1> 255<p>A ROM bank auto-assignment feature was added in GBDK 2020 4.0.2.</p> 256<p>Instead of having to manually specify which bank a source file will reside it, the banks can be assigned automatically to make the best use of space. The bank assignment operates on object files, after compiling/assembling and before linking.</p> 257<p>To turn on auto-banking, use the <code>-autobank</code> argument with lcc</p> 258<p>For a source example see the <code>banks_autobank</code> project.</p> 259<p>In the source files you want auto-banked, do the following:</p><ul> 260<li>Set the source file to be autobanked <code>#pragma bank 255</code> (this sets the temporary bank to <code>255</code>, which <a class="el" href="docs_toolchain.html#bankpack">bankpack</a> then updates when repacking)</li> 261<li>Create a reference to store the bank number for that source file: <code>BANKREF(<some-bank-reference-name>)</code>.<ul> 262<li>More than one <code><a class="el" href="gb_8h.html#a086293f2afb4c7945460a4496b20aea3">BANKREF()</a></code> may be created per file, but they should always have unique names.</li> 263</ul> 264</li> 265</ul> 266<p>In the other source files you want to access the banked data from, do the following:</p><ul> 267<li>Create an extern so the bank reference in another file is accessible: <code>BANKREF_EXTERN(<some-bank-reference-name>)</code>.</li> 268<li>Obtain the bank number using <code>BANK(<some-bank-reference-name>)</code>.</li> 269</ul> 270<p>Example: level_1_map.c </p><pre class="fragment"> #pragma bank 255 271 BANKREF(level_1_map) 272 ... 273 const uint8_t level_1_map[] = {... some map data here ...}; 274</pre><p>Accessing that data: main.c </p><pre class="fragment"> BANKREF_EXTERN(level_1_map) 275 ... 276 SWITCH_ROM( BANK(level_1_map) ); 277 // Do something with level_1_map[] 278</pre><p>Features and Notes:</p><ul> 279<li>Fixed banked source files can be used in the same project as auto-banked source files. The bankpack tool will attempt to pack the auto-banked source files as efficiently as possible around the fixed-bank ones.</li> 280</ul> 281<p>Making sure bankpack checks all files:</p><ul> 282<li>In order to correctly calculate the bank for all files every time, it is best to use the <code>-ext=</code> flag and save the auto-banked output to a different extension (such as <code>.rel</code>) and then pass the modified files to the linker. That way all object files will be processed each time the program is compiled. <pre class="fragment">Recommended: 283.c and .s -> (compiler) .o -> (bankpack) -> .rel -> (linker) ... -> .gb 284</pre></li> 285<li>It is important because when bankpack assigns a bank for an autobanked (bank=255) object file (.o) it rewrites the bank and will then no longer see the file as one that needs to be auto-banked. That file will then remain in it's previously assigned bank until a source change causes the compiler to rebuild it to an object file again which resets it's bank to 255.</li> 286<li>For example consider a fixed-bank source file growing too large to share a bank with an auto-banked source file that was previously assigned to it. To avoid a bank overflow it would be important to have the auto-banked file check every time whether it can share that bank or not.</li> 287<li>See <a class="el" href="docs_toolchain.html#bankpack">bankpack</a> for more options and settings</li> 288</ul> 289<h1><a class="anchor" id="autotoc_md91"></a> 290Errors related to banking (overflow, multiple writes to same location)</h1> 291<p>A <em>bank overflow</em> during compile/link time (in <a class="el" href="docs_toolchain.html#makebin">makebin</a>) is when more code and data are allocated to a ROM bank than it has capacity for. The address for any overflowed data will be incorrect and the data is potentially unreachable since it now resides at the start of a different bank instead of the end of the expected bank.</p> 292<p>See the <a class="el" href="docs_faq.html#faq_bank_overflow_errors">FAQ entry about bank overflow errors</a>.</p> 293<p>The current toolchain can only detect and warn (using <a class="el" href="docs_toolchain.html#ihxcheck">ihxcheck</a>) when one bank overflows into another bank that has data at its start. It cannot warn if a bank overflows into an empty one. For more complete detection, you can use the third-party <a class="el" href="docs_links_and_tools.html#romusage">romusage</a> tool.</p> 294<h1><a class="anchor" id="autotoc_md92"></a> 295Bank space usage</h1> 296<p>In order to see how much space is used or remains available in a bank, you can use the third-party <a class="el" href="docs_links_and_tools.html#romusage">romusage</a> tool.</p> 297<h2><a class="anchor" id="autotoc_md93"></a> 298Other important notes</h2> 299<ul> 300<li>The <a class="el" href="gb_8h.html#a92d040284342702026eb19dab59b586e">SWITCH_ROM_MBC5</a> macro is not interrupt-safe. If using less than 256 banks you may always use SWITCH_ROM - that is faster. Even if you use mbc5 hardware chip in the cart.</li> 301</ul> 302<h1><a class="anchor" id="autotoc_md94"></a> 303Banking example projects</h1> 304<p>There are several projects in the GBDK 2020 examples folder which demonstrate different ways to use banking.</p><ul> 305<li><code>Banks</code>: A basic banking example</li> 306<li><code>Banks_new</code>: Examples of using new bank assignment and calling conventions available in GBDK 2020 and it's updated SDCC version.</li> 307<li><code>Banks_farptr</code>: Using far pointers which have the bank number built into the pointer.</li> 308<li><code>Banks_autobank</code>: Shows how to use the bank auto-assignment feature of in GBDK 2020 4.0.2 or later, instead of having to manually specify which bank a source file will reside it. </li> 309</ul> 310</div></div><!-- contents --> 311</div><!-- PageDoc --> 312</div><!-- doc-content --> 313<!-- HTML footer for doxygen 1.8.14--> 314<!-- start footer part --> 315<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> 316</div> 317</body> 318</html>