+<sect>CONIO implementation<label id="conio"><p>
+
+The console I/O is speed optimized therefore support for XEP80 hardware
+or f80.com software is missing. Of course you may use stdio.h functions.
+
+
+<sect>Technical details<label id="techdetail"><p>
+
+<sect1><tt/atari/<#if output="info|latex2e"> details</#if><p>
+
+<sect2><#if output="info|latex2e"><tt/atari/ </#if>Load chunks<p>
+
+An <tt/atari/ program contains two load chunks.
+
+<enum>
+<item>"system check"<label id="syschk">&nl;
+This load chunk is always loaded at address $2E00, and checks if the system has
+enough memory to run the program. It also checks if the program start address is not
+below MEMLO. If any of the checks return false, the loading of the program is aborted.&nl;
+The contents of this chunk come from the SYSCHKCHNK memory area of the linker config file.
+<item>main program&nl;
+This load chunk is loaded at the selected program start address (default $2000) and
+contains all of the code and data of the program.&nl;
+The contents of this chunk come from the MAIN memory area of the linker config file.
+</enum>
+
+
+<sect1><tt/atarixl/<#if output="info|latex2e"> details</#if><p>
+
+<sect2>General operation<p>
+
+The <tt/atarixl/ target banks out the ROM while the program is running in
+order to make more memory available to the program.
+
+The screen memory is by default located at the top of available memory,
+$BFFF if BASIC is not enabled, $9FFF if BASIC is enabled.
+Therefore, in order to create a largest possible continuous memory area,
+the screen memory is moved below the program load address. This gives
+a memory area from <program load addr> to $CFFF.
+
+The startup code installs wrappers for interrupt handlers and ROM routines.
+When an interrupt or call to a ROM routine happens, the wrappers enable the
+ROM, call the handler or routine, and disable the ROM again.
+
+The "wrapping" of the ROM routines is done by changing the ROM entry
+point symbols in <tt/atari.inc/ to point to the wrapper functions.
+
+For ROM functions which require input or output buffers, the wrappers
+copy the data as required to buffers in low memory.
+
+<sect2><#if output="info|latex2e"><tt/atarixl/ </#if>Load chunks<label id="xlchunks"><p>
+
+An <tt/atarixl/ program contains three load chunks.
+
+<enum>
+<item>"system check"<label id="syschkxl">&nl;
+This load chunk is always loaded at address $2E00, and checks if the system is
+suitable for running the program. It also checks if there is enough room between MEMLO
+and the program start address to move the text mode screen buffer there. If any of the
+checks return false, the loading of the program is aborted.&nl;
+The contents of this chunk come from the SYSCHKCHNK memory area of the linker config file.
+<item>"shadow RAM prepare"&nl;
+The second load chunk gets loaded to the selected program load address (default $2400).
+It moves the screen memory below the program load address, copies the character generator
+from ROM to its new place in RAM, and copies the parts of the program which reside in
+high memory below the ROM to their place. The high memory parts are included in this load chunk.&nl;
+At the beginning of this load chunk there is a .bss area, which is not part of the
+EXE file. Therefore the on-disk start address of this load chunk will be higher than the
+selected start address. This .bss area (segment LOWBSS) contains the buffers for the
+double buffering of ROM input and output data. If you add contents to this segment be aware
+that the contents won't be zero initialized by the startup code.&nl;
+The contents of this chunk come from the SRPREPCHNK memory area of the linker config file.
+<item>main program&nl;
+This load chunk is loaded just above the LOWBSS segment, replacing the code of
+the previous load chunk. It contains all remaining code and data sections of the program,
+including the startup code.&nl;
+The contents of this chunk come from the RAM memory area of the linker config file.
+</enum>
+
+<sect2>Moving screen memory below the program start address<p>
+
+When setting a graphics mode, the ROM looks at the RAMTOP location. RAMTOP
+describes the amount of installed memory in pages (RAMTOP is only one byte).
+The screen memory and display list are placed immediately below RAMTOP.
+
+Now in order to relocate the screen memory to lower memory, the startup code
+puts a value into RAMTOP which causes the ROM routines to allocate the display
+memory below the program start address and then it issues a ROM call to setup
+the regular text mode.
+
+<sect2>Selecting a good program load address<label id="loadaddr"><p>
+
+Due to the movement of the screen memory below the program start, there are some
+load addresses which are sub-optimal because they waste memory or prevent a
+higher resolution graphics mode from being enabled.
+
+There are restrictions at which addresses screen memory (display buffer and display
+list) can be placed. The display buffer cannot cross a 4K boundary and a display
+list cannot cross a 1K boundary.
+
+The startup code takes this into account when moving the screen memory down.
+If the program start address (aligned to the next lower page boundary) minus
+the screen buffer size would result in a screen buffer which spans a 4K
+boundary, the startup code lowers RAMTOP to this 4K boundary.&nl;
+The size of the screen buffer in text mode is 960 ($3C0) bytes. So, for
+example, a selected start address of $2300 would span the 4K boundary
+at $2000. The startup code would adjust the RAMTOP value in such way that
+the screen memory would be located just below this boundary (at $1C40).
+This results in the area [$2000-$22FF] being wasted.
+Additionally, the program might fail to load since the lowest address used
+by the screen memory could be below MEMLO. (The lowest address used in this
+example would be at $1C20, where the display list would allocated.)
+
+These calculations are performed by the startup code (in the first two
+load chunks), but the startup code only takes the default 40x24 text mode
+into account. If the program later wants to load TGI drivers which set
+a more memory consuming graphics mode, the user has to pick a higher
+load address.
+Using higher resolution modes there is a restriction in the ROM that it
+doesn't expect RAMTOP to be at arbitrary values. The Atari memory modules
+came only in 8K or 16K sizes, so the ROM expects RAMTOP to only have
+values in 8K steps. Therefore, when using the highest resolution modes
+the program start address must be at an 8K boundary.
+
+
+<sect2>Character generator location<label id="chargenloc"><p>
+
+The default <tt/atarixl/ linker config file (<tt/atarixl.cfg/) leaves the
+character generator location at the same address where it is in ROM
+($E000). This has the disadvatage to split the upper memory into
+two parts ([$D800-$DFFF] and
+[$E400-$FFF9]). For applications which
+require a large continuous upper memory area, an alternative linker
+config file (<tt/atarixl-largehimem.cfg/) is provided. It relocates the
+character generator to $D800, providing a single big upper
+memory area at [$DC00-$FFF9].
+
+With the character generator at a different address than in ROM, the routines
+which enable and disable the ROM also have to update the chargen pointer.
+This code is not enabled by default. In order to enable it,
+uncomment the line which sets CHARGEN_RELOC in <tt/libsrc/atari/Makefile.inc/
+and recompile the <tt/atarixl/ runtime library.
+