This file contains constraints of the QNICE-FPGA (env1) design, that should
be mentioned, when writing the documentation.

Written by sy2002 / Last modified in December 2016

==============================================================================
    SD Card
==============================================================================

* We tested microSD and microSDHC cards in the built-in card slot using a
  Nexys 4 DDR board. Presumably everything also works fine with normal sized
  SD cards and miniSD cards on other boards and other readers.
* All SD V1 and SD V2 cards are working. We tested capacities between
  64 MB and 2 GB using also different card brands (Nokia, SanDisk, Transcend).
* When it comes to SDHC cards, i.e. cards larger than 2 GB, the following are
  tested as working: SanDisk 32 GB microSDHC Class 4,
  Transcend 32 GB microSDHC Class 10, Elegant 32 GB
* NOT WORKING are cards like SanDisk "Ultra" Class 10 cards (80 MB/sec). Use
  slower cards instead, like SanDisk's 32 GB Class 4 card. So for summing it
  up: If you want to be on the safe side, then use cards SD cards (no SDHC,
  no SDXC) with a capacity of a maximum of 2 GB.
* MBR partition table
* FAT32 with a 512 byte sector size.
  ATTENTION: FAT16 and others are not supported, you probably need to 
  manually format the SD Card to be sure, that you are running with FAT32.
* Maximum 65.535 files per folder.
* File names are ASCII only (no Unicode).
* MAC USERS: Do not use the GUI version of the disk utility, as you cannot
  control, if the tool creates FAT16 or FAT32. Use the command line
  version of diskutil instead:

  sudo diskutil eraseDisk FAT32 <name> MBRFormat /dev/<devicename>

  Find out <devicename> using "diskutil list". <name> can be chosen
  arbitrarily.

==============================================================================
    USB Keyboard
==============================================================================

When attaching an USB keyboard, be sure to use one that supports the old
USB boot mode standard. Not all newer keyboards are compatible. These
keyboards are tested and work:

* Cherry KC 1000
* Logitech Ultra-Flat Y-BP62a
* Tacens Scriba
* VIVANCO 36641 IT-KB USB PS2

==============================================================================
    VGA
==============================================================================    

The monitor needs to support 640x480 and 640x400 in 60 Hz.

==============================================================================
    Encoding / Languages / Fonts
==============================================================================

* No support for UTF-8.

* All monitor library functions, including gets and puts, are assuming, that
  one character is one byte in size. That means, for example, that if you use
  gets to enter the German character "ä" (Umlaut for ae) or
  "ß" (Umlaut for ss), the following is happening:

  a) On a modern OS like Mac OS or Windows, the default encoding is UTF-8.
     So, if you press the "ä" key, while using STDIN=UART on real hardware
     using terminal software or on the emulator using the command line of
     the OS, the operating system will send the UTF-8 encoded "ä", which are
     the following *TWO* bytes: C3 A4.

     Obviously, this means that QNICE will store these two bytes within the
     string. If you use puts to print this string on a UTF-8 enabled system,
     you will see the right character "ä" again, so it kind of feels seamless
     for the end user and nearly everything works.

     But: If you enter e.g. "ä" and then press Backspace (BS) - as gets is
     not aware of UTF-8 - the remaining character in the string is C3, which
     will lead to funny effects.

     Also, if you entered an "ä" using gets via STDIN=UART/STDOUT=UART, then
     everything looks good, as your OS and the resulting terminal emulation
     will be aware of UTF-8. But if you then output exactly this string on
     STDOUT=VGA, then you will see the two charactes "Ã€", because this is
     how the modified "lat9w-12_sy2002" font is encoded in Q-NICE currently.

  b) If you entered an "ä" using STDIN=USB, then a German keyboard would
     send the code E4, which would be displayed correctly on the STDOUT=VGA
     screen as "ä".

     But if you used STDIN=USB and STDOUT=UART, then pressing an "ä" or any
     other non standard ASCII key will result to displaying wrong characters.

* As a summary, and with the exception of some funny, but not really 
  dangerous, effects when using Backspace (BS) or DEL, you can already
  currently, where no UTF-8 support is there, use non standard characters on
  QNICE, as long as you stick either to (STDIN=STDOUT=UART) or to
  (STDIN=USB and STDOUT=VGA). As soon as you stard mixing, it is not working
  correctly, any more.

* PS/2 (USB) keyboard: Currently, the monitor switches hardcoded to the
  German keyboard layout. Though, the hardware is capable to handle an English
  layout also (hw register $FF13, bits 2 .. 4). If you have a non-german
  keyboard, you might want to change this in monitor/qasm.asm (search for
  the string KBD$LOCALE_DE).

* The VGA display uses a slightly modified version of "lat9w"
  which is mostly compatible with ISO/IEC 8859-15 as described here:
  https://en.wikipedia.org/wiki/ISO/IEC_8859-15
  You can look at the font by browsing this textfile:
  vhdl/vga/lat9w-12.txt

==============================================================================
    Standard C Library
==============================================================================    

* No support for float and double, yet.

* stdin works line buffered and the buffer size is 160 words, i.e. when
  pressing DEL or BS you can maximally go back 159 characters. There is no
  limit on the amount of characters that can be entered, the only limit is
  how "far you can go back" when pressing DEL or BS. If you want to
  enlarge the buffer, then you need to compile the standard C library while
  defining QMON_LINEBUFFER_SIZE to the value you want it to be.

* While the C compiler, linker and assembler of the VBCC toolchain are
  open source and therefore included to our distribution package, the
  standard C library is not. Therefore you need to contact the author,
  if you need the sources. We are delivering a linkable version of the
  standard C library, though: c/vbcc/targets/qnice-mon/lib/libvc.a
  and of course all the header files in c/vbcc/targets/qnice-mon/include.
  So you are able to work with the standard C library as you would expect
  it, even without having the source of the lib itself.

* The heap size is currently set to 4096 words. Short version: It grows
  upwards coming from the end of the application and therefore grows towards
  the stack which is coming downwards from somewhere near 0xFEFF. Currently
  there are no checking mechanisms that check a collision between stack and
  heap.

  Some more details: For avoiding having a lot of 0x0000 elements in the .out
  files, we currently use the so called "unsafe heap" mechanism, which means,
  that the heap is basically a pointer to one word after the last word of the
  application program itself. Have a look at
  c/qnice/vclib/targets/qnice-mon/libsrc/stdlib/_heap.c to learn more. In the
  standard C library Makefile, which it located at
  c/qnice/vclib/targets/qnice-mon/Makefile the heap size can be changed by
  defining HEAPSIZE.
  Currently, we are not having any memory and/or heap
  management mechanisms on operating system level, so obtaining "core memory"
  currently just means increasing the heap pointer, as you can see here:
  c/qnice/vclib/targets/qnice-mon/libsrc/stdlib/_core.c
  That also means, we cannot free core memory and that means, for avoiding
  memory leaks, it is important, that the THRESHOLD defined in the Makefile
  is 2 words lower than HEAPSIZE / 4, so in our case as we have 4096 words
  of heap, THRESHOLD = (4096 / 4) - 2 = 1022.
  For more details about why is that, you need to know details of the malloc
  implementation, which is currently not open source (see above).

* If you happen to have access to the standard library source code, then
  copy it to c/vclib and run the script c/make-vclib.sh to compile it.
  (Don't forget to enter "source setenv.source" before doing so.) The script
  is merging the QNICE specific changes of the standard c library, which
  are located at c/qnice/vclib with the vanilla version of the c library
  and then starts the compilation.
  The result, i.e. the binary standard library and the startup code are then
  copied to c/vbcc/targets/qnice-mon/lib: libvc.a and startup.o
