Technical Details/Tips

This chapter contains technical information and tips regarding ASIC.

                              COMPILER LIMITS

Maximum Source Program Size:   Command Line Compiler - Unlimited
                               Integrated Environment - Limited only by
                               available memory

Maximum Object Program Size:   64k bytes--.COM Format:
                                        64k code/data/stack
                              130k+ bytes--.EXE Format:
                                        64k code
                                        64k data
                                        up to 64k stack
                              130k+ bytes--.OBJ Format:
                                        64k ASIC code
                                        64k ASIC data
                                        up to 64k stack
                                        PLUS up to ~500k externally
                                        assembled ".OBJ" files can
                                        be linked into your ASIC
                                        program and called using
                                        the CALL SUB statement.
Maximum Source Line Length     128 bytes - Command Line
                               80 bytes - Integrated Environment

Compiler Symbol Table Size:    Unlimited - can use all available memory

Maximum Number of Arrays:      25

FOR/NEXT Nesting Depth         25

IF/THEN/ELSE Nesting Depth     25

WHILE/WEND Nesting Depth       25

Compiler Memory Requirements  425k

Subroutines per source file   Unlimited


                            COMPILER OPERATION

ASIC is a single pass compiler written in C (Borland C Version 3.1).  Each
source statement is translated directly into machine code.  ASIC compiles
100% in memory for maximum speed.  The compiler does not require any disk
work space.  ASIC generates a minimum of error checking code.  This is
because the ASIC philosophy stresses execution speed.  This does place
greater responsibility on the programmer to check for out of bounds
conditions, etc....


                            MEMORY OPTIMIZATION

ASIC provides 32 bit long integers in addition to 16 bit normal integers.
This allows you to store much larger numbers, however, nothing in life is
free.  Long integers will increase the size of the resulting ".COM" file by
approximately 475 bytes.  If you are not using long integers, be sure to
compile with the "Extended Math" Option turned OFF so that ASIC does not
include these unneeded bytes in your COM or EXE file. Otherwise, ASIC will
include the long integer support code in your file, even if you never
create a single long integer!  Note: by default, this option is turned off
in both the command line and integrated versions of the compiler.

Likewise, the "Decimal Math" option will allow math with fractional results
of very large numbers, but this option will increase your program size.
Use integers or long integers unless you need this fractional precision,
and turn off the "Decimal Math" option.  Note:  by default, this option is
turned off in both the command line and integrated versions of the
compiler.

Also remember that ASIC's debugging option increases your ".COM" file size.
So don't forget to recompile your program with the "Debugging" Option
turned off (after you have finished debugging it, of course).

COM disk files will usually be smaller than EXE files by several hundred
bytes.  However, COM files require 64k of memory to execute.  Additionally,
COM files (because of a DOS requirement), will automatically allocate all
available memory at load time.  EXE files require the actual size of the
program plus 2000 bytes for the stack (4000 bytes for the stack when
compiling with debugging mode).  Thus, your program may be loadable in as
few as 3-4k bytes of memory.  Also note that an ASIC EXE does NOT allocate
all available memory to your program.  ASIC only allocates the amount of
memory your program actually needs.  The following chart summarizes when it
is usually best to use each type of file:

     Use COM files when:
     -------------------

     o  You want to minimize the disk space a program occupies
     o  Your program is smaller than 64k in size

     Use EXE files when:
     -------------------

     o  Your program is larger than 64k in size
     o  You want to minimize your program's run-time memory requirements
     o  You are calling another program using the RUN or CALL Statements

     Use the OBJ option to create an EXE file when:
     ----------------------------------------------

     o using the CALL SUB statement.


                         PERFORMANCE OPTIMIZATION

This section contains tips for making your programs run as fast as
possible.

1)   VARIABLE TYPES - Don't use long integer variables or decimal variables
to store numbers that can fit in a regular integer variable.  Long integer
variables are exponentially slower than regular integers, and decimal
variables are exponentially slower than long integer variables.  If the
number will exceed the range allowed by a regular integer, but is an
integer in the range +/-2,147,483,647, then use a long integer.  If the
number requires one or more decimal places of precision, or is an integer
larger than +/-2,147,483,647, then use a decimal variable.  Always use
integers on FOR/NEXT loops, when possible.

2)   DECIMAL VARIABLES - When using decimal variables, be aware that the
least efficient operation is screen I/O.  Don't PRINT a number unless you
need to. (Note:  The decimal variable format used by ASIC was selected to
optimize speed when adding, subtracting, multiplying, and dividing.  The
trade off in using this format is that it takes longer to convert the
internal format to printable form than it would have with a packed binary
coded decimal (BCD) format.)

3)   MATH FUNCTIONS - The math functions, in order of least efficient to
most efficient, are:  Division, Multiplication, Subtraction and Addition.

4)   DON'T MIX VARIABLE TYPES - When performing calculations using decimal
variables, avoid mixing decimal variables with integer variables.  Although
ASIC will automatically convert the integers to a decimal format
internally, this conversion will slow down your calculations.


                              DEBUGGER LIMITS

Maximum Concurrent Breakpoints     20

Maximum Concurrent Watches         10

Maximum Symbol Length              30 Characters

Maximum Symbols                    Same as Compiler

Maximum Source Statements          Unlimited


                            DEBUGGER OPERATION

When you select the "Debugging code" compiler option, the ASIC compiler
inserts additional machine language instructions into your program.  It
inserts a single statement at the beginning of your program (specifically,
INT 3) which allows it to gain control.  When the ASIC editor is loaded, it
saves the existing INT 3 vector, and installs the ASIC Debugger as INT 3.
In this way, when your program begins executing, the INT 3 statement that
ASIC inserted in your program causes a transfer of control to the debugger.
Once the debugger gains control, it can set or remove additional
breakpoints as needed in your program, plus provide access to the video
memory and variable memory locations with the Swap, Watch, Unwatch, and
Modify Commands.  When you exit the ASIC editor, ASIC deinstalls the
debugger from INT 3, and restores the original interrupt 3 vector.

The compiler also creates a file with a ".DBG" extension which contains the
symbolic information needed by the debugger (i.e., variable names and
offsets, and source statement offsets).

                             DEBUGGER OVERHEAD

Running a program in debugging mode adds a small amount of overhead to your
program (both compiled code size, and execution speed).  Specifically, the
size of the debugging code will be (approximately):

          CodeSizeIncrease = 1 + LinesOfSourceCode

Note that the actual increase will usually be less than the above, since
DIM, DATA, REM, and blank source lines do not require debugging code.  The
reduction in execution speed is very slight in most cases (for you assembly
language programmers out there, a single NOP instruction is executed for
each source line).

In EXE files, the stack size is increased by an additional 2k when
debugging is enabled.


                             BAS2ASI OPERATION

BAS2ASI is ASIC's GWBASIC Program Conversion Utility (see Chapter 11 for
more information on using BAS2ASI).  BAS2ASI is a two pass converter.  Pass
1 (B2A1.EXE) performs the raw conversion of GWBASIC statements to ASIC
statements.  During pass 1, two files are created (filename.TMP and
filename.LBL).  The ".TMP" file contains the raw, unoptimized converted
statements.  The ".LBL" file contains the list of program labels which were
referenced in the GWBASIC program.  After pass 1 completes BAS2ASI calls
Pass 2 (B2A2.EXE) to conduct the code optimization.  During this pass,
unused labels are stripped from the program, and other statement
optimizations are performed.  The optimized program is then written to
filename.ASI, and filename.TMP and filename.LBL are deleted.


                              STORAGE FORMATS

NORMAL INTEGERS are stored in ASIC as two bytes, with the low order byte
appearing first (as per Intel conventions).

LONG INTEGERS are stored in ASIC as four bytes, with the least significant
word first, followed by the most significant word.  Within these two words,
the least significant byte appears first followed by the most significant
byte.

STRING VARIABLES are stored as FIXED 80 character strings terminated by an
ASCII null character for a total length of 81 characters.

STRING CONSTANTS are stored with 1 byte per character in the string
followed by a terminating ASCII null character.

DECIMAL VARIABLES AND CONSTANTS are stored in 8 bytes, from least
significant byte to most significant byte.  They are stored as signed
binary integers, with an implicit decimal point.  The integer values are
adjusted after each multiplication or division to scale the result to the
proper number of decimal places.

ARRAYS - Each element in an array requires two bytes.  (Don't forget arrays
have an element zero (i.e.  DIM A(2) is comprised of A(0), A(1), and A(2)).

Examples:

          Item           Data Type           Storage Requirements
          A              Integer Variable         2 bytes
          17             Integer Constant         2 bytes
          A&             Long Integer Variable    4 bytes
          55555&         Long Integer Constant    4 bytes
          A$             String Variable          81 bytes
          "ABC"          String Constant          4 bytes
          "A"            String Constant          2 bytes
          A@             Decimal Variable         8 bytes
          1.23456        Decimal Constant         8 bytes
          12345@         Decimal Constant         8 bytes
          DIM A(10)      Integer Array            22 bytes
          DIM A(1)       Integer Array            4 bytes
          DIM A&(10)     Long Int Array           44 bytes
          DIM A$(10)     String Array             891 bytes
          DIM A@(10)     Decimal Array            88 bytes

As you can see, string variables are expensive in terms of storage space.
Since string constants are stored at actual length +1, It is MUCH more
efficient to store short strings as constants in ASIC in terms of storage
space.  There is no performance advantage to constants over variables,
however.

In disk files, strings, decimals, and integers are written out in the above
formats.  Note that unlike GWBASIC/BASICA, integer and decimal values are
NOT expanded into strings when written, and conversely, not converted from
strings when read.  String variables and constants are written out as ASCII
strings terminated by a null character (however, the null can be
suppressed).  Thus, string variables when written to disk, take the same
space byte for byte as string constants.

The reason behind fixed length string variables was avoidance of string
"garbage collection".  In addition to slight performance advantages, there
is the added benefit of providing a string memory address which never
changes.  Thus once VARPTR retrieves the address of a variable, you never
have to worry about it changing.


                                MEMORY MAP

COM File Memory Map

The following describes the structure of the ".COM" file created by ASIC.
All addresses are in Hexadecimal.


     Description                        Address Range
------------------------------          -------------
Program Segment Prefix (PSP)            0000 - 00FF
 (Created/Required by DOS)

Transfer to Program Code                0100 - 0102
String Conversion Buffer                0103 - 0109
Input Buffer                            010A - 015B
Screen Width                            015C
Color/Attribute Byte                    015D
Screen Graphics Mode                    015E
Cursor Position                         015F - 0160
File Control Table                      0161 - 0169
ERROR System Variable                   016A - 016B
System Subroutine Vectors               016C - 017F
EXTENDED System Variable                0180 - 0181
RND Seed                                0182 - 0185
Math Work Area                          0186 - 018D
DEFSEG System Variable                  018E - 018F
Start DATA Block Pointer                0190 - 0191
Current DATA Block Pointer              0192 - 0193
Reserved for future use                 0194 - 0195
Optional Sys Subroutine Vectors         0196+
and Work Areas (decimal math option)
System Subroutines                      Address Varies
          |
          |
          v
Data Segment                            Address Varies
          |
          |
          |
          v
Code Segment                            Address Varies
          |
          |
          |
          v
          ^
          |
          |
Program Stack  (builds downward)        FFFF


EXE File Memory Map

The following describes the structure of the ".EXE" file created by ASIC.
In the COM file format the code, data, and stack are all in the same memory
segment.  In an ASIC EXE format file, the code, data, and stack each reside
in their own segment.  Addresses are given as offsets from the CS (Code
Segment), DS (Data Segment), or SS (Stack Segment) registers.


     Description                        Address Range
------------------------------          -------------
Program Segment Prefix (PSP)            CS: minus 00FF
(Created/Required by DOS, and
immediately precedes the
code segment)
          |
          |
          v
Code Segment (CS:)
     User Program                       0000 +
          |
          |
          v
     System Subroutines                 Address Varies
          |
          |
          v
Data Segment (DS:)
     Program Data Area #1               0000 - 0102
     String Conversion Buffer           0103 - 0109
     Input Buffer                       010A - 015B
     Screen Width                       015C
     Color/Attribute Byte               015D
     Screen Graphics Mode               015E
     Cursor Position                    015F - 0160
     File Control Table                 0161 - 0169
     ERROR System Variable              016A - 016B
     System Subroutine Vectors          016C - 017F
     EXTENDED System Variable           0180 - 0181
     RND Seed                           0182 - 0185
     Math Work Area                     0186 - 018D
     DEFSEG System Variable             018E - 018F
     Start DATA Block Pointer           0190 - 0191
     Current DATA Block Pointer         0192 - 0193
     Reserved for future use            0194 - 0195
     Optional System Sub Vectors        0196+
     and Work Areas (decimal math option)
     Program Data Area #2               Address Varies
          |
          |
          v
Stack (SS:)  (builds downward)          0000 - 07D0 (0FA0--debug mode)

          NOTE:  The format of an EXE file created using the
          "B/OBJ" option is essentially the same as the one
          produced by the "B/EXE" option, except that the "B/OBJ"
          output file may contain additional code or data
          segments linked in from other OBJ or LIB files.