+the GET_VAR and SET_VAR macros (or one of the helper macros described
+below). This is due to the 16bit segment nature of the X86 cpu when
+it is in "real mode". The C entry code will set DS and SS to point to
+the stack segment. Variables not on the stack need to be accessed via
+an explicit segment register. Any other access requires altering one
+of the other segment registers (usually ES) and then accessing the
+variable via that segment register.
+
+There are three low-level ways to access a remote variable:
+GET/SET_VAR, GET/SET_FARVAR, and GET/SET_FLATPTR. The first set takes
+an explicit segment descriptor (eg, "CS") and offset. The second set
+will take a segment id and offset, set ES to the segment id, and then
+make the access via the ES segment. The last method is similar to the
+second, except it takes a pointer that would be valid in 32-bit flat
+mode instead of a segment/offset pair.
+
+Most BIOS variables are stored in global variables, the "BDA", or
+"EBDA" memory areas. Because this is common, three sets of helper
+macros (GET/SET_GLOBAL, GET/SET_BDA, and GET/SET_EBDA) are available
+to simplify these accesses.
+
+Global variables defined in the C code can be read in 16bit mode if
+the variable declaration is marked with VAR16, VAR16VISIBLE,
+VAR16EXPORT, or VAR16FIXED. The GET_GLOBAL macro will then allow read
+access to the variable. Global variables are stored in the 0xf000
+segment, and their values are persistent across soft resets. Because
+the f-segment is marked read-only during run-time, the 16bit code is
+not permitted to change the value of 16bit variables (use of the
+SET_GLOBAL macro from 16bit mode will cause a link error). Code
+running in 32bit mode can not access variables with VAR16, but can
+access variables marked with VAR16VISIBLE, VAR16EXPORT, VAR16FIXED, or
+with no marking at all. The 32bit code can use the GET/SET_GLOBAL
+macros, but they are not required.
+
+
+GCC 16 bit stack limitations:
+
+Another limitation of gcc is its use of 32-bit temporaries. Gcc will
+allocate 32-bits of space for every variable - even if that variable
+is only defined as a 'u8' or 'u16'. If one is not careful, using too
+much stack space can break old DOS applications.
+
+There does not appear to be explicit documentation on the minimum
+stack space available for bios calls. However, Freedos has been
+observed to call into the bios with less than 150 bytes available.
+
+Note that the post code and boot code (irq 18/19) do not have a stack
+limitation because the entry points for these functions transition the
+cpu to 32bit mode and reset the stack to a known state. Only the
+general purpose 16-bit service entry points are affected.
+
+There are some ways to reduce stack usage: making sure functions are
+tail-recursive often helps, reducing the number of parameters passed
+to functions often helps, sometimes reordering variable declarations
+helps, inlining of functions can sometimes help, and passing of packed
+structures can also help. It is also possible to transition to/from
+an extra stack stored in the EBDA using the stack_hop helper function.
+
+Some useful stats: the overhead for the entry to a bios handler that
+takes a 'struct bregs' is 42 bytes of stack space (6 bytes from
+interrupt insn, 32 bytes to store registers, and 4 bytes for call
+insn). An entry to an ISR handler without args takes 30 bytes (6 + 20
++ 4).
+
+
+Debugging the bios:
+
+The bios will output information messages to a special debug port.
+Under qemu, one can view these messages by adding '-chardev
+stdio,id=seabios -device isa-debugcon,iobase=0x402,chardev=seabios' to
+the qemu command line. Once this is done, one should see status
+messages on the console.
+
+The gdb-server mechanism of qemu is also useful. One can use gdb with
+qemu to debug system images. To use this, add '-s -S' to the qemu
+command line. For example:
+
+qemu -L mybiosdir/ -fda myfdimage.img -s -S
+
+Then, in another session, run gdb with either out/rom16.o (to debug
+bios 16bit code) or out/rom32.o (to debug bios 32bit code). For
+example:
+
+gdb out/rom16.o
+
+Once in gdb, use the command "target remote localhost:1234" to have
+gdb connect to qemu. See the qemu documentation for more information
+on using gdb and qemu in this mode. Note that gdb seems to get
+breakpoints confused when the cpu is in 16-bit real mode. This makes
+stepping through the program difficult (though 'step instruction'
+still works). Also, one may need to set 16bit break points at both
+the cpu address and memory address (eg, break *0x1234 ; break
+*0xf1234).