


                                 README file
               for Spontaneous Assembly For C/C++, Version 3.0
               (C) Copyright Acclaim Technologies, Inc., 1993


    This document contains release notes for version 3.0 of Spontaneous
Assembly For C/C++ as well as additions to and/or corrections of documentation
accompanying this product.



General Notes


1.  By default, the library header files only define the resident versions
    of the functions. However, if TSR.H has been included, the header files
    also define the transient and EMS-relocatable versions of the
    functions.


2.  When using C++ to write TSRs, constructor/destructor functions are not
    called for global and static classes.


3.  When writing TSRs, most initializations are performed within transient
    code. To reduce resident code size, the windowing, multitasking, and
    virtual screen systems can all be initialized transient.

    Already-initialized windowing, multitasking, and virtual screen systems can
    be made available to resident functions if a resident entry point calls the
    appropriate ???_resume function, and can be made available to EMS-
    relocatable functions if an EMS-relocatable entry point calls the
    appropriate _e_???_resume function.

    _console_init should always be called by an entry point that will use the
    console I/O system.


4.  To decrease executable size, the C examples can be made to link with
    the Spontaneous Assembly startup code. This can be done by modifying
    the example programs to create a stack (see the Start/Exit technical
    notes), and specifying the startup object module as the first item to
    link, as follows:

    tlink \sa\lib\_starts.obj (the normal command line follows)

    link /NOE \sa\lib\_starts.obj (the normal command line follows)


5.  When using Microsoft C 6.0 or 7.0, the /Zp1 switch MUST BE USED.


6.  When using the Scripted I/O and Data Conversion floating point
    functions the FPCcm or _FPCcm libraries must also be included. To
    coalesce a floating point library with the default SA? and _SA?
    libraries a librarian can be used to add them together as follows:

    lib sas.lib+fpcns.lib;      /* Add non-emulated floating point library to
                                   default library */

    tlib _sas.lib+_fpcbs.lib    /* add Borland specific floating point
                                   library to default Spontaneous Assembly 
                                   library */

7.  Because of some large defines for Scripted I/O Borland/Turbo C user
    need to compile with the #pragma option -50 option to avoid truncating
    the some scripted i/o defines.

    For Microsoft 6.0 and 7.0 user see the warning on page 184 for
    instructions for compiling with Scripted I/O.

8.  When writing TSRs, malloc, calloc, and free are not available from
    transient or EMS-relocatable portions of the program unless a large
    code model is used.


9.  If you get a "symbol space exceeded" error from TLINK (this should only
    happen when linking TSRs with the resident, transient, and EMS-
    relocatable libraries), an update to tlink can be obtained from the
    Borland Support BBS at (408) 439-9096.





Documentation Additions/Corrections


1.  The concluding sentence in the "What Has Been Removed in Spontaneous
    Assembly 3.0" section should refer to "Appendix F in the Spontaneous
    Assembly 3.0 manual" instead of the "2.0 manual". See page 3.


2.  "&status" should be removed from the fourth line from the bottom of
    page 105. It should read as follows:

         _asc_to_uq(strbuf, radix, num2, &sptr);

    Also, "&status" should be removed from the tenth line on page 106. It
    should read as follows:

         _asc_to_uq(strbuf, radix, num1, &sptr);


3.  The "db" reference on the fifth and sixth lines of the code on page 129
    should read as follows:

         "kf_flags     db       0        ;status. . .
         kf_enflags    db       0        ;status. . ."


4.  The T_WRAP bit of the t_statbyte field of the satask structure is no
    longer used by the multitasking system. See pages 142, 144, and 513.


5.  The scripted I/O "_CHRI,char" description should refer to the "_CHRI"
    code instead of the "_LCHR" code. See page 174. 


6.  __BCD code for scripted i/o incorrectly lists 3 arguments. The
    precision parameter is not supported for BCD types. The correct
    arguments are __BCD, width, nformat. See page 182.


7.  The name of the country structure (typedefed as country) used with
    _get_countryinfo and _set_country has been changed to dcountry to avoid
    a naming conflict with Borland/Turbo C's country function and COUNTRY
    structure. This changes the references for this structure on pages 128,
    480, and 674.

8.  The TIME_FLEXHR and TIME_CTIME formatting options for time conversion
    are flip/flopped. The actual value for TIME_FLEXHR is (0x00) and for
    TIME_CTIME is (0x03). This changes the documentation for these values
    on pages 85, 294, 761, and 763.


9.  The _exit and _exit_ok functions are only provided when using the
    Spontaneous Assembly startup code. No inline versions of these
    functions are available. The notes for these functions should contain
    an additional statement which reads, "This function is only available
    when using Spontaneous Assembly startup code." See page 428.


10. The return values the _tmr_read and _ticks_to_time funtions should read
    as follows:

         std_time *_tmr_read(std_time *trmtimr);
         std_time *_ticks_to_time(unsigned long tticks, std_time *stime);


11. The "Returns" information for the _get_adaptinfo function should read
    as follows:

         "0 if adapter is present in the system.
         adaptinfo     information. . .

         -1 if adapter is not present in the system.
         adaptinfo     structure. . ."

    See page 471.



12. The method for installing Spontaneous Assembly Heap Management as
    outlined on pages 109-110 is no longer current. The specified files
    have been replaced with macros defined in SAHEAP.H (which is included
    by MEMALLOC.H) which initialize the Spontanous Assembly heap management
    for the compiler being used. The following steps replace the
    installation instructions on the above mentioned pages:

    #include <memalloc.h>
    ...
    HEAP     /* macro determines compiler and init functions to use
                for initializing Spontaneous Assembly heap management. */
         ...
         void main(void)
         {
         ...
         }
    
    Again, with the new installation method no special linking steps need
    to be followed as documented on page 110.

    If Spontaneous Assembly start-up code is being used, then use the
    HEAP_SA macro instead of HEAP.

    The HEAP_TSR macro is provided for heap management in TSRs.

    If only the default heap (a near heap in small data models and a far heap
    in large data models), the NHEAP, NHEAP_SA, and NHEAP_TSR macros can be
    used instead to reduce the amount of heap initialization code linked into
    the final program.


13. _pack_cmplinit and _unpack_cmplinit are not the same functions. See
    pages 626 and 790. Additionally, _get_packcmpl and _get_unpackcmpl
    return the completion percent since the ..._cmplinit function was
    called, not since the compression/decompression system was initialized.
    See pages 497 and 513.


14. The eighth symbolic constant (representing standard video mode values
    which may be returned) listed under the "Notes" section for _get_vmode
    should be changed from "MONO" to "MONO80". See page 517.


15. The _get_vpage syntax line on page 517 line should read as follows:

         "char _get_vpage(void);" instead of "int _get_vpage(void);"

    Also, the _get_vpagecnt syntax line on page 518 should read as follows:

         "char _get_vpagecnt(void);" instead of "int _get_vpagecnt(void);"


16. The word "near" under "Syntax" should be changed to "far" for the
    following functions: _isr_getstat (page 562), _isr_hremove (page 563),
    _isr_install (page 563), _isr_remove (page 565). Also, though the
    _isr_... functions are documented as accepting near pointers to the
    isrctrl structures, these functions expect far pointers. See pages 562-
    566.


17. The _keyfeed_append keyf structure definition should be changed to
    match the structure definition in the technical notes. See pages 231
    and 573.

    Also, the _keyfeed_insert keyf structure definition should be changed to
    match the structure definition in the technical notes. See pages 231 and
    574.


18. The _on_exit functions must be far functions. See page 621.


19. The one line example in the "Notes" section of the _on_exit function
    should read as follows:

         "void far exit_func(void);"


20. The _open_h syntax line should read as follows:

         "int _open_h(const char *namestr. . ." 

             instead of 

         "int _openh(const char *filename, const char *namestr. . ."

    See page 623.


21. The "Syntax" information for _restore_screen should read

         "int _restore_screen(void. . ."

    and the "Returns" line should read

         "0 if the screen was successfully restored.
         -1 if the saved video state is invalid."

    Also, the following paragraph should be added to the "Notes" for this
    function:

         "0 is returned if the function was successful; -1 is returned only if
         the adapter type in the saved video state is invalid. The results are
         undefined if the specific video display page is not supported by the
         indicated display adapter."

    See page 658.



22. The maximum sleep time for a task as documented on page 756 is
    incorrect, the maximum value for std_time.hours with respect to a task
    is 231 hours.


23. The "Syntax" information for _set_adapter should read as follows:

         "0 if adapter was successfully selected.
         -1 if adapter was successfully selected."

    See page 665.


24. The eighth symbolic constant (representing the standard values of
    "mode") listed under the "Notes" section for _set_vmode should be
    changed from "MONO" to "MONO80". See page 691.


25. When using the stack_1k, stack_2k, stack_4k, stack_8k, stack_16k, and
    stack_32k variables, one of the SA header files (other than those that
    make code/data transient, ems-relocatable, or stack) MUST be included.
    If an SA header file is not included, no compiler error or warning will
    occur, but no stack space will be linked. See pages 719 and 721.


26. Though _tsr_initc is documented as accepting default function pointers,
    this function expects far pointers (except in TINY, where near pointers
    are expected). This function should not be used for TSRs that will run
    in an OS/2 DOS session. See pages 768-769.


27. The source file names for the following functions need to have the
    initial underscores removed:

                                         Listed Source     Actual Source
    Page #        Function                 File Name         File Name

    303           _bioskey_off           _TDBKF.ASM        TDBKF.ASM
    303           _bioskey_on            _TDBKN.ASM        TDBKN.ASM
    395           _directkey_off         _TDDKF.ASM        TDDKF.ASM
    395           _directkey_on          _TDDKN.ASM        TDDKN.ASM
    416           _erq_8off              _TDEQ8F.ASM       TDEQ8F.ASM   
    417           _erq_8on               _TDEQ8N.ASM       TDEQ8N.ASM
    417           _erq_16off             _TDEQ16F.ASM      TDEQ16F.ASM  
    418           _erq_16on              _TDEQ16N.ASM      TDEQ16N.ASM
    418           _erq_21off             _TDEQ21F.ASM      TDEQ21F.ASM  
    418           _erq_21on              _TDEQ21N.ASM      TDEQ21N.ASM
    419           _erq_28off             _TDEQ28F.ASM      TDEQ28F.ASM  
    419           _erq_28on              _TDEQ28N.ASM      TDEQ28N.ASM
    421           _erq_off               _TDEQF.ASM        TDEQF.ASM
    421           _erq_on                _TDEQN.ASM        TDEQN.ASM
    551           _idle_off              _TDIDLEF.ASM      TDIDLEF.ASM
    551           _idle_on               _TDIDLEN.ASM      TDIDLEN.ASM
    575           _keyfeed_off           _TDKFF.ASM        TDKFF.ASM
    576           _keyfeed_on            _TDKFN.ASM        TDKFN.ASM
    724           _stimer_off            _TDTMRF.ASM       TDTMRF.ASM
    724           _stimer_on             _TDTMRN.ASM       TDTMRN.ASM
    758           _task_yield            _TKYIELD.ASM      TKYIELD.ASM
    767           _tsr_emsinit           _TDEINIT.ASM      TDEINIT.ASM


28. The source file names of the following functions and variables have
    been changed.

                                         Listed Source     Actual Source
    Page #        Function                 File Name         File Name

    266           _adapter_init          _CIOADNT.ASM      CIOADINT.ASM
    313           cbrk_pending           MDCBKDIS.ASM      MDPEND.ASM
    315           c_code                 UTCCODE.ASM       _UTCCODE.ASM
    374           _dec_to_fixpi          _DFDCXSI.ASM      _DCDCXSI.ASM
    452           _fmem_pbrkn            _MMFPBRKN.ASM     _MMFPBKN.ASM
    464           _fstr_right            _STFR2GHT.ASM     _STFRGHT.ASM
    518           _get_vpage             _CIOGVP.ASM       CIOGVPG.ASM  
    518           _get_vpagecnt          _CIOGVPC.ASM      CIOGVPGC.ASM
    608           monitor_type           CIOCVARS.ASM      CIOCVAR.ASM 
    646           rand_seed              IMRNDW.ASM        IMRNSD.ASM


29. The divide by zero function, critical error manager, and fail functions
    cannot be relocated to EMS memory in a TSR. See pages pages 220-221,
    225-226, 768-769.


30. The VSCRN structure on page 242 and 815 incorrectly show each element
    name prefixed with "vs_". This prefix should not be used when accessing
    structure elements.


31. When disk buffering is used with virtual screens, the offset within the
    file to buffer to is specified in the BUFFER field of the VSCRN
    structure. When initializing this field with a long int (an offset into
    a file), the value must be type cast as a void far *, as follows (see
    page 243):

         screen.buffer = (void far *)(16*1024);


32. Microsoft C 7.0 gives erroneous "near call to 'function' in different
    segment" warnings when calling transient or EMS-relocatable functions
    from a TSR. These messages should be ignored.


33. Due to compiler restrictions, only SMALL and MEDIUM can be supported
    with Microsoft C 7.0.


34. Device drivers cannot do any file I/O before going resident and cannot
    use any environment functions (see page 235).


35. If the virtual screen system will use disk buffering with the virtual
    screen system from resident code, the resident version of
    _set_vsworkbuf must be called AFTER going resident (see page 693-694).


36. If the virtual screen system will use disk buffering with the virtual
    screen system from EMS-relocatable code, the EMS-relocatable version of
    _set_vsworkbuf must be called AFTER going resident (see page 693-694).


37. Be aware that calling _tsr_enable can cause the program to be
    re-entered through interrupts BEFORE going resident (see page 226).


38. A common problem with TSRs is not allocating enough resident stack
    space. A symptom of insufficient stack space is the TSR crashing in
    inconsistent places. Try increasing the stack space whenever an
    unexplainable TSR problem is encountered, as this will often solve the
    problem (see page 229).


39. When using the TINY model for a TSR with BORLAND, all modules with
    transient code must be compiled with the -zPDGROUP command line
    options. NOTE: only use this switch in the TINY model, and only on
    modules whose code is transient (see page 216).


40. When using the BORLAND IDE, the include files that make code/data
    transient or EMS-relocatable are ignored by the compiler (see page
    216).


41. Entry definition functions (in TSRs and non-TSR programs that use the
    TSR system) should be declared as follows (see page 220):

         void far "func_name" ("bk/dk/idle/stmrspec" * const);

    Fail functions should be declared as follows (see page 220):

         void far "func_name" ("bk/dk/idle/stmrspec" * const, char causefail,
                  char entryfail);

    Keyfeed functions should be declared as follows (see page 232-233):

         int far "func_name" (keyf far * const, int code, char command);


42. When declaring keyf structures, the "kfptr" type is provided in TSR.H
    for type casting if compiler errors or warnings are generated. For
    example (see page 231):

         int far keyf_check (keyf far * const kf, int code, char cmd);
         int keyfeed1[5];
         keyf feed_keys = {(keyf near *)-2,keyfeed1,(int near *)-1,0,0,1,3,3,
                  (kfptr)-1,(kfptr)keyf_check};

    NOTE: The first element in the structure must ALWAYS be initialized to
    "(keyf near *)-2"


43. erqspec structures can be initialized as follows (see page 227-228):

    IDLE_DEF (erq_popup,display_window,_None,256,erq_fail,1);
    erqspec erq_struc = {(erqspec near *)-2,{0,0,0,0},{0,0,0,0},
             0,2,3,&erq_popup};

    NOTE: The first element in the structure must ALWAYS be initialized to
    "(erqspec near *)-2".


44. The first element in an isrctrl structure must ALWAYS be initialized to
    "(isrctrl far *)-2" (see page 229).


45. A stack should only be linked in non-TINY programs and in device
    drivers (see page 229, 235). This is handled in the TSR templates
    provided.

    For example,

    #if  !__TINY__
    extern unsigned int stack_2k = 0;
    #endif


46. The TSR structure definitions in the manual are inaccurate (wrong types
    are listed). The structures are defined as follows:

         typedef struct __idlespec{
            struct __idlespec near * next_spec;
            void (near/far * entry_func)(struct __idlespec * const);
            void (near/far * fail_func)(struct __idlespec * const);
            void (near * near * check_list)(void);
            void (near * near * save_list)(void);
            void (near * near * restore_list)(void);
            int stack_len;
            int entry_mask;
         } idlespec;

         typedef struct __stmrspec{
            struct __stmrspec near * next_spec;
            void (near/far * entry_func)(struct __stmrspec * const);
            void (near/far * fail_func)(struct __stmrspec * const);
            void (near * near * check_list)(void);
            void (near * near * save_list)(void);
            void (near * near * restore_list)(void);
            int stack_len;
            int entry_mask;
            int wait_ticks;
            int retry_ticks;
            int rld_ticks;
         } stmrspec;

         typedef struct __bkspec {
            struct __bkspec near * next_spec;
            void (near/far * entry_func)(struct __bkspec * const);
            void (near/far * fail_func)(struct __bkspec * const);
            void (near * near * check_list)(void);
            void (near * near * save_list)(void);
            void (near * near * restore_list)(void);
            int stack_len;
            int entry_mask;
            int bios_code;
         } bkspec;

         typedef struct __dkspec {
            struct __dkspec near * next_spec;
            void (near/far * entry_func)(struct __dkspec * const);
            void (near/far * fail_func)(struct __dkspec * const);
            void (near * near * check_list)(void);
            void (near * near * save_list)(void);
            void (near * near * restore_list)(void);
            int stack_len;
            int entry_mask;
            char scan_code;
            int keyflags;
         } dkspec;

         typedef struct {
            void near * next;
            std_time start;
            std_time stop;
            unsigned char intspec;
            unsigned int waitticks;
            unsigned int retryticks;
            void near * eds;
         } erqspec;

         typedef struct __keyf {
            struct __keyf near * next;
            int near/far * buffer;
            int near * nextcode;
            char flags;
            char enhflags;
            char repeat;
            char flush;
            char flushcnt;
            int (near/far * getfunc)(struct __keyf far * const, int, char);
            int (near/far * chkfunc)(struct __keyf far * const, int, char);
         } keyf;


47. _restore_screen returns an int. 0 is returned if successful, -1 is
    returned if the adapter type specified in the saved screen information
    is invalid.


48. _video_on and _video_off do not work on EGA adapters. See page 812.


49. _set_vsworkbuf must be called before _vscreen_create is used to create
    a disk buffered screen. See pages 815-816.


50. _save_vstate and _restore_vstate do not save/restore the cursor
    position. See pages 659 and 661.


51. The refresh field of the vscrn structure may be set to -1 to inherit
    the active video refresh state. See page 243.


52. WARNING! Although the video mode example (on page 50) does locate the
    nonstandard video modes on many adapters, some adapters do not
    appropriately validate extended video mode requests. These adapters may
    hang the system if the wrong video mode is selected. And they may, in
    some remote cases, even damage the monitor. Base Two Development
    assumes no responsibility for your use of this example code.


53. Functions installed with ON_EXIT must be FAR functions.


54. If the Spontaneous Assembly heap management 




                                     README
                      for Spontaneous Assembly, Version 3.0
                 (C) Copyright Acclaim Technologies, Inc., 1993


This document contains release notes for Spontaneous Assembly Version 3.0
as well as additions and/or corrections to the accompanying documentation.



General Notes


1.  WARNING! Although the video mode example (see page 18) does locate
    nonstandard video modes on many adapters, some adapters do not
    appropriately validate extended video mode requests. These adapters may
    hang the system if the wrong video mode is selected. In some remote
    cases, extended video mode requests could even damage the monitor.
    BASE TWO DEVELOPMENT ASSUMES NO RESPONSIBILITY FOR YOUR USE OF THIS
    EXAMPLE CODE.


2.  Due to assembler restrictions, when using MASM 5.1 all ASSUME statements
    must be preceded by a percent sign and a space ("% "). For example:

    % assume                cs:@codeseg


3.  Rebuilding any of the libraries requires MASM 6.0+ or TASM 1.0+.


4.  To use TASM's ideal mode, edit the include files and change all of the
    leading dots on macro names to leading underscores. The underscore macro
    naming convention must also be used in your code. For example, .CODESEG
    would be renamed and referenced as _CODESEG in the include file and in
    source code which uses it.


5.  When writing TSRs, most initializations are performed within transient
    code. To reduce resident code size, the windowing, multitasking, and
    virtual screen systems can all be initialized from the transient portion
    of the program.

    Already-initialized windowing, multitasking, and virtual screen systems
    become available to resident functions only after the resident entry point
    calls the appropriate ..._RESUME function. These systems can also be made
    available to EMS-relocatable functions if an EMS-relocatable entry point
    calls the appropriate E_..._RESUME function.

    CONSOLE_INIT should always be called by an entry point that uses the console
    I/O system. See page 21.


6.  If "out of memory" errors are encountered when assembling, the
    SA_EXTRN.INC file may be removed to reduce the memory requirements for
    assembling the file. If SA_EXTRN.INC is not used, all functions that are
    used by the module must be declared with the .EXTRN macro.


7.  MASM 6.0+ and TASM are recommended for writing TSRs. When using these
    assemblers, only the those check/save/restore functions that are
    actually used are linked into the final program.


8.  A "symbol space exceeded" error is possible when TLINK is used to link
    TSRs with a very large number of symbols along with the resident,
    transient, and EMS-relocatable libraries. To resolve this problem, an
    update to TLINK must be obtained from the Borland Support BBS at
    408/439-9096.




Documentation Additions/Corrections


1.  The T_WRAP bit of the t_statbyte field of the TASK structure is no
    longer used by the multitasking system. See pages 60, 64, and 218.


2.  The returns described for ASC_TO_DATE and ASC_TO_TIME on pages 147 and
    148 are incorrect. Instead, the SI register is modified to point to the
    first unconvertible character in instr (similar to the ASC_TO_...
    functions in the data conversion unit). The returns for ASC_TO_DATE
    should read as follows:

    JE if the conversion was successful.
    Date in dword format (date):
    DX      year (1980-2099)
    AH      month (1-12)
    AL      day (1-31)
    SI      address of the first character in instr which could not be converted

    JA if numeric overflow occurred.
    DX;AX   undefined
    SI      address of the first character in instr which could not be converted

    ...

    and for ASC_TO_TIME as follows:

    JE if the conversion was successful.
    Time in dword format (time):
    DH      hours (0-255)
    DL      minutes (0-59)
    AH      seconds (0-59)
    AL      hundredths of seconds (0-99)
    SI      address of the first character in instr which could not be converted

    JA if numeric overflow occurred.
    SI      address of the first character in instr which could not be converted

    ...

            
3.  The description of the "_CHRI" code in the Scripted I/O technical notes
    should refer to the "_CHRI" code instead of the "_LCHR" code. See page
    80.


4.  The __BCD scripted I/O code is incorrectly shown with 3 arguments
    throughout the documentation. The precision parameter is not supported
    for BCD types. The correct arguments are "__BCD, width, nformat". See
    pages 89, 155, 163, 214, 223, 228, 259, 271, and 279.


5.  The description of NSTART?.OBJ should read "DOSSEG ordering is used"
    instead of "TSR segment ordering is used". See page 106.


6.  ON_EXIT functions must perform far returns. See pages 247 and 248.


7.  PACK_CMPLINIT and UNPACK_CMPLINIT are not the same functions, as
    documented. In addition, completion percentages returned by GET_PACKCMPL
    and GET_UNPACKCMPL are measured since the last time the corresponding
    ..._CMPLINIT function was called (NOT since the
    compression/decompression system was initialized, as documented). See
    pages 28, 210, 218, 250, and 313.


8.  For PACK_CMPLINIT and UNPACK_CMPLINIT, the second paragraph under
    "Notes" should be deleted from the reference section. See pages 250 and
    313.


9.  TSR_INITC should not be used for TSRs that will run in an OS/2 DOS
    session. See page 304.


10. The critical error manager installed by TSR_INITC must perform a far
    return. See page 304.


11. The divide by zero function, critical error manager, and fail functions
    cannot be relocated to EMS memory in a TSR. See pages 118-119, 123-124,
    and 304-305.

12. A common problem encountered when writing TSRs is failure to allocate
    enough resident stack space. A symptom of insufficient stack space is
    crashing of the TSR in inconsistent places. Increasing the stack space
    whenever an unexplainable TSR problem is encountered will often solve
    the problem. See page 127.


13. If the virtual screen system is initialized to use disk buffering from
    resident or EMS-relocatable code, the corresponding resident or EMS-
    relocatable version of SET_VSWORKBUF must be called AFTER going
    resident. See page 268.


14. TSR_ENABLE allows programs to be reentered through interrupts before the
    program is resident. If TSR_ENABLE is used, the programmer must take
    steps to prevent the resident and transient portions of the program from
    using the same non-sharable program or system resources. See page 124
    and Appendix E.


15. A stack must always be created in a device driver TSR. See page 133.
    This support is provided in the TSR templates.


16. VIDEO_ON and VIDEO_OFF do not work on EGA adapters. See pages 316-317.


17. SET_VSWORKBUF must be called before VSCREEN_CREATE can be used to create
    a disk buffered screen. VSCREEN_CREATE returns the E_INSMEM error code
    if SET_VSWORKBUF has not been called with an adequate work buffer. See
    pages 140-141 and 318.


18. RESTORE_SCREEN returns JNC if the screen was restored successfully, and
    JNC if the adapter type specified in the saved screen information is
    invalid.


19. Contrary to the documentation, the REFRESH field of the VSCRN structure
    may be set to -1 to inherit the active video refresh state. See page
    141.


20. The reference section description for SET_ADAPTER fails to indicate that
    this function leaves the windowing system in an undefined state. The
    warning paragraph which appears under SET_DIMENS should also appear
    under SET_ADAPTER. See pages 264 and 266.


21. The source code example for locating nonstandard screen dimensions
    (pages 18-19) is incomplete, as follows:

    Currently documented as follows:

    mode_loop:      call    set_vmode       ;change to extended mode
                    call    is_textmode     ;is it a text mode?
                     jne    mode_next       ;  n: don't remember it
                    ...                     ;save mode (AL minus NOCLEAR)
                    push    ax              ;preserve current mode
                    call    get_dimens      ;get text mode screen dimensions
                    ...                     ;save dimensions (AX)
                    pop     ax
    mode_next:      inc     ax


    The example should be changed as follows:

    mode_loop:      call    set_vmode       ;change to extended mode
                    call    is_textmode     ;is it a text mode?
                     jne    mode_next       ;  n: don't remember it
                    push    ax
                    and     al,not NOCLEAR  ;strip NOCLEAR bit from mode
                    cmp     al,video_mode   ;was mode change successful?
                     jne    mode_skip       ;  n: don't use this mode
                    ...                     ;save mode (AL minus NOCLEAR)
                    call    get_dimens      ;get text mode screen dimensions
                    ...                     ;save dimensions (AX)
    mode_skip:      pop     ax
    mode_next:      inc     ax

    This code only works if the active virtual screen is currently open or if
    the virtual screen system is not in use.


22. If SET_VMODE is called to select an extended video mode on a non-open
    virtual screen, the screen dimensions are assumed to be 132x60 until the
    screen is opened and the actual screen dimensions can be determined. For
    this reason, 16K buffers are recommended for all extended video modes
    unless the mode and the actual screen dimensions for that mode are
    indicated in the screen descriptor dimensions before VSCREEN_CREATE is
    called. See pages 138-139.


23. The MONO video mode equate defined in version 2.0 has been renamed to
    MONO80, and a new MONO equate has been defined for use with the
    MONITOR_TYPE variable. References to MONO in the 2.0 manual should be
    changed to MONO80 to avoid confusion. (See the 2.0 reference section
    descriptions for GET_VMODE and SET_VMODE).


24. The virtual screen descriptors are incorrect in the virtual screen
    sample code (see page 143). The PRIMARY descriptor should be defined as
    "<-1,,,,,1,1>" and the SECONDARY descriptor should be defined as
    "<-2,,,,,0,0>" (each with one additional comma).


25. Functions installed with ON_EXIT must perform a far return (retf).

