                     *-------------*
                     |  C P L 3 2  |        V1.2  MAY 97
                     *-------------*



This program is commercial, it can be used for an UNLIMITED period at one
computer ONLY at a time. Please read licence.txt .
CPL32 is not Freeware or Shareware. Do not distribute.
CPL32 is created, owned and licensed exclusively by Intelligent Firmware.
Web: www.intelligentfirm.com,  Email: cpl32@intelligentfirm.com .
Reverse-engineering or modifying this software is strictly prohibited.


This is CPL32, the best assembler for true, pure assembly programmers.
Purpose built for 32 bit protected mode programming (supports also 16 bit)
and for embedded systems (ROM) programming. The most important feature of
CPL32 is that it is a real assembler, not a high level language C assembler
like the usual assemblers. In CPL32 you write assembly, not some high level
language, so there is absolutely NO RED TAPE, you do NOT declare variable
types, segments or procedures.
That's why we built CPL32 and its predecessor ASM32, because we couldn't 
manage any more with traditional C-assemblers, like TASM or even A386
(which is an intermediate). Nevertheless, we should point out, that CPL32 
does not support .OBJ files, so in order to make assembly subroutines for 
a program written in a high level language, you have to use an other 
assembler, or make a trick incorporating a .BIN file into the main program.


Main features include:
* Multiple pass. It will pass continuously your source code until all
  forward references are found. (No settings needed).
* 1024 Kbytes of .BIN file output!, unlimited number of source files (up to
  64k each), up to 33792 short labels and 8192 long labels.
  (Short labels: Letter+number Lxxxx, e.g. L1,L100, M50, not M05).
* .BIN files for pure machine code or .COM files for MSDOS/Windows.
* Listing (.LST) file output.
* Symbol (.SYM) file output.
* XREF.COM utility: converts .SYM file to .XRF file which contains all
  labels' addresses.
* Can take input files from catalog (.CAT) file.
* NO RED TAPE: you just program, except from the start address of your
  program, nothing needs to be declared.
* Multiple line If-then-else statements: eg If NC {MOV EAX,EBX ; if flag=NC
                                                   ADD EBX,4
                                                  |MOV EBX,EAX ; else
                                                   ADD EAX,4}  ; endif
* #IF,#ELSE,#ENDIF directives for conditional code generation.
* Profiler support.
* Multiple 32 bit support: As everything in this assembler, you can change
  between 16 and 32 bit code generation any time with just one directive.
* Multiple PUSH/POP instructions merged to one. e.g. PUSH EAX,EBX,CX
* Extremely fast, especially when no .LST file is output.
* Allows hundreds of input files and nested include files.
* Automatically takes input files from file CPL32.CAT if present.
* Interrupt labels: e.g. "MSDOS= INT 21h"
* Runs very well and faster under Windows 95

Exclusive CPL32 features:
* Floating point instruction support.
* MMX instruction support.
* P6 family instruction support (Pentium Pro and Pentium II).
* 4 additional directives.
* Macros

Compiler features include:
* Compiler IF instruction (e.g. IF CX+2>W[abc]/2 {....})
* Compiler LET instruction (e.g. LET W[abc]=CX/2+W[def]-100h)
* Compiler Repeat instruction (e.g. REPEAT EBX*2+1 {....})
* MOVS, CMPS, STOS, SCAS string compiler instructions.
  (e.g. MOVS D,buffer,buffer+BX*4,BX*4)
* Compiler PRINT instruction (e.g. PRINT "ERROR !",7,13,10,10)
 


Acceptable invocation syntax:
1' CPL32 source1 ... sourceX [TO] dest.BIN/.COM [dest.SYM] [dest.LST]
2' CPL32 source.CAT
    where source.CAT includes the files mentioned in 1'
3' CPL32
    Here CPL32.CAT is used as source (if available).


Operators in priority order:
(,) : parenthesis
-   : negate (e.g. -ABC)
!   : not
*,/ : multiply, divide
+,- : plus, minus
<,>,=> ,<= ,=,<> ,&,%: less, greater, greater or equal, less or equal,
                          equal, different, by, word by
                          (e.g. 23h & "A" % 577Bh is equal to 2341577Bh)


Operands:
- decimal (e.g. 23)
- hex     (e.g. 17h)  Should be at least 2 digits + "h"
- binary  (e.g. 11110b)
- ASCII   (e.g. "A" ,"ABC")
- label   (e.g. abc)



Addressing modes:
- immediate: arithmetic expression (e.g. ABC+2)
- register16: AX,CX,DX,BX,SP,BP,SI,DI
- register8:  AL,AH,CL,CH,DL,DH,BL,BH
- register32: EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI
- use16 memory: "["+reg16+"+"/"-"+immediate+"]" where reg16=none,BX,BP,SI,DI,
                BX+SI,BX+DI,BP+SI,BP+DI; immediate is optional.
- use32 memory: "["+reg32+"+"+X+"*"+reg32+"+"/"-"+immediate+"]" where
                reg32,X and immediate are optional, X="1"/"2"/"4"/"8"
- Floating point register: ST0,ST1,...,ST7
- MMX register: MM0,MM1,...,MM7

From the above you can easily understand that:
1' All memory references are always in brackets [...], anything which is not
   in brackets is ALWAYS immediate. e.g. ABC=20 ; MOV AX,ABC : (so AX=20) ;
   MOV AX,[ABC] : (so AX=contents of [20]).
2' In memory references, the immediate always follows the registers.
   (e.g. MOV AX,[BCh+BX] is NOT allowed).

In cases where the operand size is not specified implicitly, you have to
use "B"/"W"/"D" prefixes, instead of the hideous "BYTE/WORD/DWORD PTR"
(e.g. PUSH W[1000h] ; INC D[ABC])
When the memory addressed is not in the default segment (DS, SS for (E)BP
and ESP references), you have to provide a segment override prefix, either
in front of the whole instruction or in front of the "[".
(e.g. MOV AX,CS:[ABC*2] ).


Directives:
- EVEN  : aligns in word boundary.
- DEVEN : aligns in double word boundary.
- HEVEN : aligns in hex (=16) byte boundary.
- DHEVEN : aligns in double hex (=32) byte boundary (equal to Pentium/II
           cache line size).
- PEVEN : aligns in page (=4K) boundary.
- ALIGN <value> : aligns in <value> boundary. (Sets code generation at next
                  <current addr> MOD <number>)
- ORG addr  : sets code generation to continue at <addr>.
- BEGIN addr : sets initial address of code generation at <addr>
               (e.g. BEGIN 100h generates .COM file).
- ASM32 : dummy directive which can be used for identifying that the source
          files are for ASM32 (other assemblers will report error).
- CPL32 : dummy directive as previous (ASM32 will report error).
- CPU proc : Selects CPU type <proc>: all instructions following are checked
             to be compatible with that CPU. Default is 386.
             <proc>: 086,186,286,386,486,Pentium or 586,Pentium_MMX or 586MMX,
                     P6 or 686.
- USE16/USE32: Select instruction and operand size model for the following
               instructions.
- INCLUDE filename: Temporary takes source code from <filename>.
- INCLBIN filename: Include <filename> as is! This is very useful for including
                    pictures, data, other code generator's code, etc.
- IF flag : Conditional execution.
- #IF arithmetic representation : Conditional assembly.
- #ENDIF: End of conditional assembly
- #ELSE: Conditional assembly.
- #PROFS "name",[[seg:]reg] : Inform profiler that routine <"name"> started
                          and that data at <seg:reg> is of special interest.
- #PROFE ["name"],[[seg:]reg] : Inform profiler that routine <"name"> has
                 finished and that data at <seg:reg> is of special interest.
- DB b1,...,bx : Define data Bytes. <bx>=single bytes or ASCII strings.
                 (e.g. DB 13,10,"Press any key",7,13,10,10,"$").
- DW w1,...,wx : Define data Words. <wx>=single word.
- DD d1,...,dx : Define data Dwords. <dx>=single double word.
- DS size,[b1] : Define space of size. <size> bytes filled with b1.
- DB3 t1,...,tx: Define data triple bytes. <tx>=24bit three byte number 
                 (6 hex digits). Very usuful in 32bit mode as addresses.
- DB5 f1,...,fx: Define five bit bytes. <fx>=single 5 bit bytes (0-31) or
                 ASCII strings. Very useful for economically representing 
                 text/numbers.
- label EQU value: Assigns an arithmetic 32bit value to a label.
- label = value: The same much nicer.
- MACRO : Defines a label as Macro name.
- #EM :   Ends a macro


DUP: Instead of the DUP directive (in DB,DW,DDs) ASM32/CPL32 uses the much more
     convenient brackets. (e.g. DB 100 dup(0) -> DB 100 [0])
JMPS: Instead of the "JMP SHORT" instruction ASM32/CPL32 uses "JMPS"


Conditional execution: All the time in x86 assembly the programmer needs
to make if-then or if-then-else. To do that he has to use labels and
jmp instructions. A much easier way is ASM32/CPL32's system. e.g.:
          CMP AL,2                      CMP AL,2
          JC N1 ; <2 ?                  IF NC {MOV BX,"1V"
          MOV BX,"1V"          ---->          |MOV BX,"2V"}
          JMPS N2                       MOV [T1],BX
      N1: MOV BX,"2V"
      N2: MOV [T1],BX
In between the { } many instructions and other IFs can be inserted.
In case there is no else needed, no "|" should be used; and then if only a
single instruction follows the IF, no { } are necessary. (.e.g. IF C RET)


Conditional assembly: Some times it is very useful to use an assembly file
(.ASM) in more than one program (e.g. CBENCH,CBENCHP,DBENCH,RBENCH have
all but one files common), or to have multiple version of the same program
(e.g. shareware/registered). Then a label should be declared and that label
used in following #IF statements in order to distinguish between versions.
e.g.:  #IF shareware
        DB "S H A R E W A R E"
       #ELSE
        DB "Registered!"
       #ENDIF
Here the label <shareware> decides whether the first or the second string
will be assembled by its value (true<>0, false=0). Also more complicated
statements can be used (e.g. #IF cbench+shareware>1).



COMPILER INSTRUCTIONS:

COMPDATA : If compiler instructions are going to be used, COMPDATA instruction
           *must* be used once only. COMPDATA allocates space (usually 24h
           bytes) needed for compiler instructions' workspace.
CREGS reg,...,reg: Declares 1 or more registers as available for compiler's
                   use. Always compiler instructions require some registers
                   to use. Default is (E)AX,(E)DX. When a register is
                   declared as compiler available, that means that whenever
                   a compiler instruction is used, this register will get
                   overwritten. But you are still allowed to use a compiler
                   register for source or destination of compiler instructions.
                   This instruction can be used as many times as one needs it.
SIGNED : Specifies that the following compiler arithmetic operations will
         use signed arithmetic.
UNSIGNED: Specifies that the following compiler arithmetic operations will
          use unsigned arithmetic. (DEFAULT)
LET reg/mem "=" <expr> : Set <register/memory> to value of <expression>.
                         <expr>: any valid compiler expression.
                         e.g. LET W[average]= (W[v1]+W[v2]+W[v3])/3
IF [NOT] <expr> =,<>,>,=>,<,<= <expr> : As simple IF <flag> but instead
                 of a flag it uses 2 full expressions. IFs can be nested.
                 <expr>: any valid compiler expression. 
                 e.g. (AX+2)/B[SI] > 2-AX 
REPEAT <expr> {...} : Repeats what follows in the "{"s <expr> times.
                      Repeats can be nested.
STOS B/W/D, <dest>, <len>, <data> . Store using STOSB/STOSW/STOSD.
                      Direction is set by the direction flag (CLD/STD).
                      <dest>=expression assigned to (E)DI.
                      <len>=expression assigned to (E)CX.
                      <data>=expression assigned to (E)AX.
SCAS B/W/D, <dest>, <len>, <data> . Scan using SCASB/SCASW/SCASD. 
                                    Exactly as the previous one.
MOVS B/W/D, <source>, <dest>, <len> . Move using MOVSB/MOVSW/MOVSD.
                      Direction is set by the direction flag (CLD/STD).
                      <source>=expression assigned to (E)SI.
                      <dest>=expression assigned to (E)DI.
                      <len>=expression assigned to (E)CX.
CMPS B/W/D, <source>, <dest>, <len> . Compare using CMPSB,CMPSW,CMPSD.
                                      Exactly as the previous one.
PRINT b1,...,bx : Print data bytes. <bx>=single bytes or ASCII strings.
                  (e.g. PRINT 13,10,"Press any key",7,13,10,10).
                  This instruction can only be used where the user's 
                  program implements the INT 38h as a printing function.
                  Label "EN" must be defined as the terminating character,
                  e.g. EN="$" (Look at the .LST file to see INT38's format).
                  

In order to learn to use the compiler instructions the user should write
a small dummy program with a single compiler instruction and assemble it.
When this assembles correctly the user should look at the .LST file to see
how the instruction was compiled. This process should be repeated more than
once for each compiler instruction.


       
Macros: Macros are used whenever a specific operation is used many times.
        Example:       ; Saturating Add
                  ADDS MACRO
                       ADD #1,#2
                       IF C MOV #1,-1 ; -1 is the maximum for any register size
                       #EM

               After this declaration, we can use many times in the program
               the new 'instruction' ADDS op1,op2 
               (e.g. ADDS AX,BX  ,  ADDS B[abc],10 )
        The #1,...,#9 in a Macro's declaration represent the operands of
        the new 'instruction' which the macro creates.
        A Macro must always end with "#EM".



More examples can be found in the file EXAMPLE.ASM .
We are building an optimizer for CPL32's compiler instructions which will 
be send to you as soon as it's ready.



LIMITED WARRANTY

THESE PROGRAMS AND ACCOMPANYING WRITTEN MATERIALS ARE PROVIDED "AS IS" WITHOUT
WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED
TO THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
PURPOSE.  NEITHER THE AUTHOR NOR ANYONE ELSE WHO HAS BEEN INVOLVED IN THE
CREATION, PRODUCTION OR DELIVERY OF THIS PRODUCT SHALL BE LIABLE FOR ANY
DIRECT, INDIRECT, CONSEQUENTIAL OR INCIDENTAL DAMAGES ARISING OUT OF THE USE
OR INABILITY TO USE SUCH PRODUCT EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
