Release notes for BIEW version 5.1.1
====================================

  This document contains up-to-date information for end-users and developers.

Limitations of use of this release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Min. screen width:                   80  characters
Max. screen width:                   255 characters
Min. screen height:                  3   rows
Max. screen height:                  unlimited
Min. colors:                         2
Max. colors:                         16
Dynamic resizing of size of screen:  no
Max. size of viewing file:           2Gb

Known problems in this release:
===============================

Known problems at developing-time:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- When I try used *scanf* function family, then in many development systems
  I found bugs for those functions. I mostly recommend use strto* function 
  family instead.
- Project contain "danger" code for some platforms. 
  (See: lib/sysdep/ia32/dos/timer.c, ...)
  I mostly recommend use -O2 switch for gcc with any other keys.
- After building of project with Cygnus GNU development systems
  (like: cygwin, glibc-2.1.x e.t.c.) in Percent dialogs wrong
  displayed elapsed time. In hours position displayed 03 instead 00.
  Because of this problem does not exists in other GNU ports
  (like os2-emx, dos32-djgpp), therefore it problem of library, but
  not BIEW.
- Wrong displayed contents of LX format, when file consist from
  "Iterated data page type II" pages.
- About problem with different results of fastcall and cdecl versions
  under Win32: It may be a deep-hidden bug of biew or bug of gcc,
  because in some snapshots of biew it appeared also under other gcc related
  development systems. (Notes: compiled with GCC CDECL version works correctly,
  as compiled with Watcom and TopSpeed, where fastcall is used by default!!!)

Known problem at run-time (this problem of OS's):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- When biew-OS/2 is running under OS/2 v4.5 UNI_040 in fullscreen
  mode sometime it generated TRAP in POINTER$ device. (Better run it
  in windowed mode or use last patched UNI_039 kernel (at 03.11.1999)
  or last patched UNI_040 kernel (at 28.03.2000)).
- Biew-Win32 does not work properly under WinNT-4.0 SP3 and older.
- Sometime, when biew-Win32 is running under WinNT-4.0 (SP4-5) and
  system perform swapping after quitting of biew You may receive GPF.

A few words about calling convention:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Watcom manual says:

__cdecl:
Defines the calling convention used by Microsoft compilers.

Notes:
1.	All symbols are preceded by an underscore character.
2.	Arguments are pushed on the stack from right to left.
        That is, the last argument is pushed first.  
        The calling routine will remove the arguments from the stack.
3.	Floating-point values are returned in the same way as structures.
        When a structure is returned, the called routine returns a pointer 
        in register AX/EAX to the return value which is stored in the data 
        segment (DGROUP).
        (NK: In 32-bit version floating-point values are returned in 80x87
             register ST(0)).
4.	For the 16-bit compiler, registers AX, BX, CX and DX, and segment
        register ES are not saved and restored when a call is made.
5.	For the 32-bit compiler, registers EAX, ECX and EDX are not saved and
        restored when a call is made.

__stdcall:
(32-bit only) The __stdcall keyword may be used with function definitions, 
and indicates that the 32-bit Win32 calling convention is to be used.

Notes:

1.	All symbols are preceded by an underscore character.
2.	All C symbols (extern "C" symbols in C++) are suffixed by "@nnn" 
        where "nnn" is the sum of the argument sizes (each size is rounded up
        to a multiple of 4 bytes so that char and short are size 4). When the
        argument list contains "...", the "@nnn" suffix is omitted.
3.	Arguments are pushed on the stack from right to left. That is, the last
        argument is pushed first. The called routine will remove the arguments
        from the stack.
4.	When a structure is returned, the caller allocates space on the stack.
        The address of the allocated space will be pushed on the stack
        immediately before the call instruction. Upon returning from the call,
        register EAX will contain address of the space allocated for the return
        value. Floating-point values are returned in 80x87 register ST(0).
5.	Registers EAX, ECX and EDX are not saved and restored when a call is
        made.

__syscall:
(32-bit only) The __syscall keyword may be used with function definitions,
and indicates that the calling convention used is compatible with functions
provided by 32-bit OS/2.

Notes:
1.	Symbols names are not modified, that is, they are not adorned with
        leading or trailing underscores.
2.	Arguments are pushed on the stack from right to left. That is, the last
        argument is pushed first.  The calling routine will remove the arguments
        from the stack.
3.	When a structure is returned, the caller allocates space on the stack.
        The address of the allocated space will be pushed on the stack
        immediately before the call instruction. Upon returning from the call,
        register EAX will contain address of the space allocated for the return
        value. Floating-point values are returned in 80x87 register ST(0).
4.	Registers EAX, ECX and EDX are not saved and restored when a call is
        made.

__pascal:
(16-bit only) Defines the calling convention used by OS/2 1.x and 
Windows 3.x API functions.
Notes:

1.	All symbols are mapped to upper case.
2.	Arguments are pushed on the stack in reverse order. That is, the first
        argument is pushed first, the second argument is pushed next, and so on.
        The routine being called will remove the arguments from the stack.
3.	Floating-point values are returned in the same way as structures.
        When a structure is returned, the caller allocates space on the stack.
        The address of the allocated space will be pushed on the stack
        immediately before the call instruction. Upon returning from the call,
        register AX will contain address of the space allocated for the return
        value.
4.	Registers AX, BX, CX and DX, and segment register ES are not saved and
        restored when a call is made.

Optimization notes:
~~~~~~~~~~~~~~~~~~~
Intel P-III manual says:               Athlon-K7 manual says:

(System Programming Guide, Order       (Publication # 22007 Rev: D
Number 243192 (pages 443 and           Issue Date: August 1999 (pages 21 and
below)):                               below)):

 [14.1.1. General Code Optimization    C Source Level Optimizations:
 Guidelines]

Write code that can be optimized by    This chapter details C programming 
the compiler. For example:             practices for optimizing code for the 
                                       AMD Athlon  processor:
*******************************************************************************
- Minimize the use of global           Avoid frequently de-referencing pointer 
  variables, pointers, and complex     arguments inside a function. Since the 
  control flow statements.             compiler has no knowledge of whether 
                                       aliasing exists between the pointers, 
                                       such de-referencing can not be optimized
                                       away by the compiler. This prevents data
                                       from being kept in registers and 
                                       significantly increases memory traffic.

- Do not use the "register" modifier.  --------------[ N/A ]----------------

- Use the "const" modifier.            Use the "const" type qualifier as much as
                                       possible. This optimization makes code
                                       more robust and may enable higher
                                       performance code to be generated due to
                                       the additional information available to
                                       the compiler. For example, the C standard
                                       allows compilers to not allocate storage
                                       for objects that are declared const, if
                                       their address is never taken.

- Do not defeat the typing system.     --------------[ N/A ]----------------

- Do not make indirect calls.          --------------[ N/A ]----------------

- Sign Extension is usually quite      If possible, use unsigned integer types
  expensive.                           over signed integer types. The unsigned
                                       types convey to the compiler that data
                                       cannot be negative, which allows some
                                       optimizations not possible with signed
                                       and potentially negative data.

--------------[ N/A ]----------------  Optimize Switch Statements:
                                       recommended to sort the cases of a switch
                                       statement according to the probability of
                                       occurrences, with the most probable first.
                                        int days_in_month, short_months,
                                            normal_months, long_months;
                                         switch (days_in_month) {
                                            case 31: long_months++; break;
                                            case 30: normal_months++; break;
                                            case 28:
                                            case 29: short_months++; break;
                                            default: printf ("month has fewer"
                                            "than 28 or more than 31 days\n");
                                         }

--------------[ N/A ]----------------  Declare Local Functions as Static:
                                       Functions that are not used outside the
                                       file in which they are defined should
                                       always be declared static, which forces
                                       internal linkage. Otherwise, such
                                       functions default to external linkage,
                                       which might inhibit certain optimizations
                                       with some compilers for example,
                                       aggressive inlining.

--------------[ N/A ]----------------  Use Prototypes for All Functions:
                                       Prototypes can convey additional
                                       information to the compiler that might
                                       enable more aggressive optimizations.

- For best performance, make sure      C Language Structure Component Considerations
  that data structures and arrays      - Sort structure members according to
  greater than 32 bytes, are 32-byte     their base type size, declaring members
  aligned, and that access patterns      with a larger base type size ahead of
  to data structures and arrays do       members with a smaller base type size.
  not break the alignment rules.       - Pad the structure to a multiple of the
                                         largest base type size of any member:
                                         struct {
                                           double x;
                                           long k;
                                           char a[5];
                                           char pad[7]; } baz;

- ALIGNMENT OF DATA ON THE STACK       Sort Local Variables According to Base
  Use static variables instead of      Type Size:
  dynamic (stack) variables.           When a compiler allocates local variables
  On the Pentium processor, accessing  in the same order in which they are
  64-bit variables that are not 8-byte declared in the source code, it can be
  aligned will cost an extra 3 clocks. helpful to declare local variables in
  On the P6 family processors,         such a manner that variables with a
  accessing a 64-bit variable will     larger base type size are declared ahead
  cause a data cache split.            of the variables with smaller base type
                                       size:
                                        double z[3];
                                        double x, y;
                                        long foo, bar;
                                        float baz;
                                        short ga, gu, gi;

- Use minimum sizes for integer and    Use 32-bit data types for integer code. 
  floating-point data types, to        Compiler implementations vary, but 
  enable SIMD parallelism.             typically the following data types are
                                       included int, signed, signed int,
                                       unsigned, unsigned int, long, signed long,
                                       long int, signed long int, unsigned long,
                                       and unsigned long int.

--------------[ N/A ]----------------  Avoid Unnecessary Integer Division:
                                       Integer division is the slowest of all
                                       integer arithmetic operations and should
                                       be avoided wherever possible.

- Unroll all very short loops. Loops   Complete unrolling reduces register
  that execute for less than 2 clocks  pressure by removing the loop counter.
  waste loop overhead.                 To completely unroll a loop, remove the
                                       loop control and replicate the loop body
                                       N times. In addition, completely
                                       unrolling a loop increases scheduling
                                       opportunities. Only unrolling very large
                                       code loops can result in the inefficient
                                       use of the L1 instruction cache.

--------------[ N/A ]----------------  Always Inline Functions with Fewer Than
                                       25 Machine Instructions

- Pay attention to the branch          Place branch targets at or near the
  prediction algorithm for the target  beginning of 16-byte aligned code windows.
  processor. This optimization is      This technique helps to maximize the number
  particularly important for P6 family of instructions that are filled into the
  processors. Code that optimizes      instruction-byte queue.
  branch predict-ability will spend
  fewer clocks fetching instructions.

- Take advantage of the SIMD           Use 3DNow! Instructions:
  capabilities of MMXT technology and  Unless accuracy requirements dictate
  Streaming SIMD Extensions.           otherwise, perform floating-point 
                                       computations using the 3DNow! instructions
                                       instead of x87 instructions. The SIMD 
                                       nature of 3DNow! instructions achieves
                                       twice the number of FLOPs that are
                                       achieved through x87 instructions. 3DNow!
                                       instructions also provide for a flat
                                       register file instead of the stack-based
                                       approach of x87 instructions.

- Avoid partial register stalls:       Avoid Partial Register Reads and Writes:
  On P6 family processors, when a      In order to handle partial register
  large (32-bit) general-purpose       writes, the AMD Athlon processor
  register is read immediately after   execution core implements a data-merging
  a small register (8- or 16-bit)      scheme. In the execution unit, an
  that is contained in the large       instruction writing a partial register
  register has been written, the read  merges the modified portion with the
  is stalled until the write retires   current state of the remainder of the
  (a minimum of 7 clocks). Consider    register. Therefore, the dependency 
  the example below:                   hardware can potentially force a false 
    MOV AX, 8                          dependency on the most recent instruction
    ADD ECX, EAX ;Partial stall        that writes to any part of the register.
                 ;occurs on access of  Example 1 (Avoid): 
                 ;the EAX register       MOV AL, 10 ;inst 1
  Here, the first instruction moves      MOV AH, 12 ;inst 2.
  the value 8 into the small register  Inst 2 has a false dependency on inst 1.
  AX. The next instruction accesses    Inst 2 merges new AH with current the 
  sequence results in a partial        large register EAX. This code EAX 
  register stall.                      register value forwarded by inst 1. In
                                       addition, an instruction that has a read
  Pentium R and Intel486T processors   dependency on any part of a given 
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   architectural register has a read
  do not generate this stall.          dependency on the most recent instruction
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^          that modifies any part of the same 
                                       architectural register. 
                                       Example 2 (Avoid):
                                         MOV BX, 12h ;inst 1
                                         MOV BL, DL  ;inst 2
                                         MOV BH, CL  ;inst 3
                                         MOV AL, BL  ;inst 4
                                       Inst 2 false dependency on completion of
                                       inst 1. Inst 3, false dependency on 
                                       completion of inst 2. Inst 4, depends on
                                       completion of inst 2.
     
- Align all data.                      Avoid Memory Size Mismatches:
 - Align 8-bit data on any boundary    - Align 8-bit data on any boundary
 - Align 16-bit data to be contained   - WORD accesses are aligned if they
   within an aligned 4-byte word.        access an address divisible by 2.
 - Align 32-bit data on any boundary   - DWORD accesses are aligned if they
   that is a multiple of 4.              access an address divisible by 4.
 - Align 64-bit data on any boundary   - QWORD accesses are aligned if they 
   that is a multiple of 8.              access an address divisible by 8.
 - Align 80-bit and 128-bit data on    - TBYTE accesses are aligned if they
   a 128-bit boundary (that is, any      access an address divisible by 16.
   boundary that is a multiple of 16 
   bytes).                             

 - A loop entry label should be        --------------[ N/A ]----------------
   16-byte aligned when it is less
   than 8 bytes  away from that
   boundary.

 - A label that follows a conditional  --------------[ N/A ]----------------
   branch should not be aligned.

 - A label that follows an             --------------[ N/A ]----------------
   unconditional branch or function
   call should be 16-byte aligned when
   it is less than 8 bytes away from
   that boundary.

 Aligment penalties:                   Avoid misaligned data references. A
 - On a Pentium R processor, a         misaligned store or load operation
   misaligned access costs 3 clocks.   suffers a minimum 1-cycle penalty in
 - On a P6 family processor, a         the AMD Athlon processor load/store
   misaligned access that crosses a    pipeline.
   cache line boundary costs 6 to 9
   clocks.
 - On a P6 family processor,
   unaligned accesses that cause a
   data cache split stall the
   processor. A data cache split is
   a memory access that crosses a
   32-byte cache line boundary.
     
- Dynamic Allocation Using MALLOC      Dynamic Memory Allocation Consideration:
  When using dynamic allocation, check Dynamic memory allocation ( malloc in C
  that the compiler aligns doubleword  language) should always return a pointer
  or quadword values on 8-byte         that is suitably aligned for the largest
  boundaries. If the compiler does not base type (quadword alignment). Where
  implement this alignment, then use   this aligned pointer cannot be guaranteed,
  the following technique to align     use the technique shown in the following
  doublewords and quadwords for        code to make the pointer quadword aligned,
  optimum code execution:              if needed. This code assumes the pointer
  1. Allocate memory equal to the size can be cast to a long. Example: 
     of the array or structure plus 4
     bytes.
  2. Use "bitwise" and to make sure
     that the array is aligned, for
     example:
       double a[5];                     double* p;
       double *p, *newp;                double* np;
       p = (double*)malloc              p = (double *)malloc
         ((sizeof(double)*5)+4)           (sizeof(double)*number_of_doubles+7L);
       newp = (p+4) & (-7)              np = (double *)((((long)(p))+7L)&(8L));

- Organize code to minimize            !!!!!!!! [SAME ] !!!!!!!!!!!!!!!!!!!!!
  instruction cache misses and
  optimize instruction prefetches.

- Avoid prefixed opcodes other than    --------------[ N/A ]----------------
  0FH.

- Use software pipelining.             !!!!!!!! [SAME ] !!!!!!!!!!!!!!!!!!!!!

- Always pair CALL and RET (return)    --------------[ N/A ]----------------
  instructions.

- Avoid self-modifying code.           !!!!!!!! [SAME ] !!!!!!!!!!!!!!!!!!!!!

- Do not place data in the code        !!!!!!!! [SAME ] !!!!!!!!!!!!!!!!!!!!!
  segment.

- Avoid instructions that contain 4 or Use Short Instruction Lengths:
  more micro-ops or instructions that  Assemblers and compilers should generate
  are more than 7 bytes long. If       the tightest code possible to optimize
      ^^^^^^^^^^^^^^^^^^^^^^^          use of the I-Cache and increase average
  possible, use instructions that      decode rate. Wherever possible, use
  require 1 micro-op.                  instructions with shorter lengths.
  Pentium R processors without MMXT    Using shorter instructions increases the
  technology do not execute a set of   number of instructions that can fit into
  paired instructions if either        the instruction-byte queue.
  instruction is longer than 7 bytes;
  Pentium R processors with MMXT       avoid:
  technology do not execute a set of   81 C3 FB FF FF FF:  add ebx, -5
  paired instructions if the first     preffered:
  instruction is longer than 11 bytes  83 C3 FB:           add ebx, -5
  or the second instruction is longer
  than 7 bytes. Prefixes are not 
       ^^^^^^^^
  counted.
  The P6 family processors have 3
  decoders that translate Intel
  Architecture macro instructions into
  micro operations (micro-ops, also
  called "uops"). The decoder
  limitations are as follows:
  The first decoder (decoder 0) can
  decode instructions up to 7 bytes in
                      ^^^^^^^^^^^^^
  length and with up to 4 micro-ops in
  one clock cycle. The second two
  decoders (decoders 1 and 2) can
  decode instructions that are 1 micro-
  op instructions, and these
  instructions will also be decoded in
  one clock cycle.

  So, for best performance on all
  Intel processors, use simple
  instructions that are less than 8
  bytes in length.

 [14.1.2. Guidelines for Optimizing
 MMXT Code]

- Do not intermix MMXT instructions    There is no penalty for switching 
  and floating-point instructions.     between x87 FPU and 3DNow!/MMX
                                       instructions in the AMD Athlon processor.

- Use the opcode reg, mem instruction  Avoid Address Generation Interlocks:
  format whenever possible. This       It is advantageous to schedule loads and
  format helps to free registers and   stores that can calculate their addresses
  reduce clocks without generating     quickly, ahead of loads and stores that
  unnecessary loads.                   require the resolution of a long
                                       dependency chain in order to generate
                                       their addresses.

- Put an EMMS instruction at the end   FEMMS instruction should be used to
  of all MMXT code sections that you   ensure the same code also runs optimally
  know will transition to floating-    on the AMD-K6 processor. The FEMMS
  point code.                          instruction is supported for backward
                                       compatibility with the AMD-K6 processor,
                                       and is aliased to the EMMS instruction.

 [14.1.3. Guidelines for Optimizing
 Floating-Point Code]

- Understand how the compiler handles  - Use Multiplies Rather Than Divides
  floating-point code. Look at the     - Use FFREEP to Pop One Register from the 
  assembly dump and see what             FPU Stack
  transforms are already performed on  - For branches that are dependent on
  the program. Study the loop nests in   floating-point comparisons, use the
  the application that dominate the      FCOMI/FCOMIP/FUCOMI/FUCOMIP instructions.
  execution time. Determine why the      These instructions are much faster than
  compiler is not creating the fastest   the classical approach using FSTSW,
  code. For example, look for            because FSTSW is essentially a 
  dependences that can be resolved by    serializing instruction on the AMD
  rearranging code                       Athlon processor. When FSTSW cannot
                                         be avoided (for example, backward
                                         compatibility of code with older
                                         processors), no FPU instruction should
                                         occur between an FCOM[P], FICOM[P],
                                         FUCOM[P], or FTST and a dependent
                                         FSTSW. This optimization allows the use
                                         of a fast forwarding mechanism for the
                                         FPU condition codes internal to the AMD
                                         Athlon processor FPU and increases
                                         performance.

- Look for and correct situations      Ensure All FPU Data is Aligned:
  known to cause slow execution of
  floating-point code, such as:
  - Large memory bandwidth             Misaligned memory accesses reduce the
    requirements.                      available memory bandwidth.
  - Poor cache locality.
  - Long-latency floating-point
    arithmetic operations.

- Do not use more precision than is    Avoid Using Extended-Precision Data:
  necessary. Single precision          Store data as either single-precision or
  (32-bits) is faster on some          double-precision quantities. Loading and
  operations and consumes only half    storing extended-precision data is
  the memory space as double precision comparatively slower.
  (64-bits) or double extended
  (80-bits).

- Use a library that provides fast     Minimize Floating-Point-to-Integer
  floating-point to integer routines.  Conversions
  Many library routines do more work
  than is necessary.

- Insure whenever possible that        --------------[ N/A ]----------------
  computations stay in range. Out of
  range numbers cause very high
  overhead.

- Schedule code in assembly language   Use the FXCH instruction rather than
  using the FXCH instruction. When     FST/FLD pairs:
  possible, unroll loops and pipeline  Using FXCH is preferred over the use of
  code.                                FST/FLD pairs, even if the FST/FLD pair
                                       works on a register. An FST/FLD pair adds
                                       two cycles of latency and consists of two
                                       OPs.

- Perform transformations to improve   --------------[ N/A ]----------------
  memory access patterns. Use loop
  fusion or compression to keep as
  much of the computation in the cache
  as possible.

- Break dependency chains.             --------------[ N/A ]----------------

 [14.6.3. Write Allocation Effects]
P6 family processors have a "write     --------------[ N/A ]----------------
allocate by read-for-ownership" cache,
whereas the Pentium R processor has a
"no-write-allocate; write through on
write miss" cache.

 boolean array[max]; 
  /* 1-In "boolean" in this example
     there is a "char" array. Here, it
     may well be better to make the
     "boolean" array into an array of
     bits, thereby reducing the size
     of the array, which in turn
     reduces the number of cache line
     fetches. */
 for(i=2;i<max;i++) {
   array = 1;
 }
  for(i=2;i<max;i++) {
   if( array[i] ) {
    for(j=2;j<max;j+=i) {
     if( array[j] != 0 ) { 
       array[j] = 0;          
/* check to see if value is already 0. 
if the value is already zero before
writing (as shown in the following
example), thereby reducing the number
of writes to memory (dirty cache
lines) */
     }
    }
   }
  }

Source code notes:
==================
All source of project has written in ibm-866 code page
(equ: ibm-437 + russian letters).
All names of files must be in 8.3 model, no symlinks e.t.c
(Project builds in DOS environment).
For detail read comments in makefile.inc

What's todo:
============
(This block contain a lot of ideas. Not all will released, but most of them)

+ Remake twin library for using unicode or dbcs
+ Accelerating video i/o
+ ONE OF:
  - mman support / preemptive memory allocation in bbio technology
  - support for 64-bits file systems.
+ Fully-featured support for LE, LX, a.out, arch, elf, *nix formats
  (if possible with using binutils or scripts)
+ Dissasemblers for other platform (if their users coded it)
+ OS/2 mouse-bug fix.
+ Any base for hex-mode (probably it will digit mode viewer)
+ C (.c .cpp .h .hpp) syntax hilighting
+ Bookmarks (screen-shot functionality)
+ Search and replace (non-interactive)
+ Powered search with wildcard (templates like *?)
  (Note: In this case Boyer-Moore optimization is not allowed)
+ block operations like:
   recode with external tables (non codepage)
   reverse block (word-dword) (big-little endian - endianify)
   sort block
+ capable showing the stack of calls (Is it needed???)
+ Search within crypted bytes (Is it needed???)
+ Window classes -> most effective mouse usage (this will start 6.x series)
+ Add support for dynamically linked plugins and addons.
  (this will in 6.x series)
+ Fully featured Java support

Sweet dreams:
~~~~~~~~~~~~~
+ Format-related writting. (Insert new sections, change size of existsing
  sections and rebind them e.t.c.). 
++ First step: attempt to try particular restore corrupted file.
++ Next step: optimization of binary files on assembler level
   (Note: not all formates allowed it).
