[ ### Changed since v3.0 / doc v1.0 ! ]
 --
                             ĿĿĿ
                                          
                                 Ĵ         
                                        
                             
             ĿĿĿĿĿĿ  ĿĿ
                                                 
                Ĵ                  Ŀ    Ĵ   
                              ٳ           Ĵ ڿ 
               
 --
  BAssPasC Compiler version 3.0 CardWare  *  Copyright (C) 1996-99 ESP-team
 --

 Made by:
 ~~~~~~~~
             Gereffy rpd  (GyikSoft)    arpi@banki1.banki.hu
             Pilszy Istvn  (PilaSoft)    Pila.1999C.Piar@email.piar.hu
             Brthzi Andrs (MikroLab)    bar_and@sparta.banki.hu
             Kbler Istvn                 kiskubi@labor.obuda.kando.hu
             Smulovics Pter (Szoke)       smulo@freemail.c3.hu
             ( and many more, just check STAFF.TXT )

     This  document  is  translated  to  English  by  Zoltn  Rajnai  (mrz /
  AstroideA)  by  the  end  of  v2.32. Since then Smulovics Pter (Szoke 0fh
  AtomiK) is the official translater.

 --


                                   Foreword
                                   

     This  documentation is far from being complete, and it's likely that it
  will  never  be complete, since the development of the compiler is running
  faster than the making of the documentation. Because of this, if something
  isn't  clear,  or  something is missing, then please feel free to write an
  email (arpi@banki1.banki.hu) and we will help you (if we can)!

     We  would  be  happy to get any sort of help, for instance if you could
  phrase  something  better than we can (which will not be hard) then please
  write it down and send it to us to put in this documentation!
     And of course if you notice any kind of bug or error in this text or in
  the  compiler  then  let  us  know! If you discover something (i.e. in the
  examples)  that  is  missing from this documentation, then don't hesitate,
  contact  us!  Also  write  to us if you have some new idea, or you wrote a
  good LIB...


                              Table of contents
                              

        1. Introduction

        2. Installation
          2.1. The files                                    -> LIST-ENG.TXT
          2.2. BASSPASC.CFG settings                        -> CFG-FILE.TXT
          2.3. BAPC3 command-line                           -> CMDLINE.TXT
          2.4. The BAPC and TASM problems
          2.5. The BAPC and NASM

        3. The structure of BAP language programs
          3.1. The structure of the program
          3.2. Possibilities
          3.3. Limitations

        4. Compiler directives                              -> CONTROLL.TXT

        5. Basics
          5.1. Assigning values
          5.2. Mathematical and logical operators
          5.3. Abbreviations
          5.4. Labels
          5.5. Variables
          5.6. Constants
          5.7. Strings
          5.8. Segment-prefixes
          5.9. Code-repetition

        6. Instructions
          6.1. Conditional instructions (IF, CASE)          -> CONDITIO.TXT
          6.2. Loop construction (FOR, REPEAT-UNTIL, WHILE)
          6.3. Stack handling   (PUSH, POP)
          6.4. Keyboard and screen handling
          6.5. File-operations  (FILE*)
          6.6. Miscellaneous instructions
          6.7. String-like instructions (STOSx, etc.)
          6.8. The macroset STDBAPC.H [v3.0+]

        7. Modular programming
          7.1. INDIRECT-s
          7.2. The usage of routine packages (LIB-s)
          7.3. INCLUDE-s
          7.4. BAP Object (BPO)
          7.5. The usage of PACKAGE-s                         -> PACKAGE.TXT

        8. Macros and functions                  -> FUNCTION.TXT & MACRO.TXT

        9. The description of the routine packages (LIBs) -> subdir LIB-DOCS

       10. Free registration                                 -> REGISTER.TXT


                               1. Introduction
                              

     This  programming  language  has  been made for those Assembly language
  programmers  who  want  to  make  fast  and  small  program  code, but are
  striving  for  faster  development,  easier  overview  and  less typing.

     In first approach, the BAPC is a expansion for the assembly language in
  the  form  of  a  macro-set.  But  then today it covers the full assembly,
  nearly  everything  can  be written using just the BAPC instructions. With
  the  LIBs  the BAPC can be ranked among the high level computer languages,
  it steps much over the level being just a macroset.
     The  philosophy  of BAPC programming doesn't differ much from assembly,
  but  it results in a smaller, tenser and more perspicuous source. This way
  bigger,  more complicated programs can be written, whose handling was more
  labored  in  asm.  For this BAPC gives lots of possibilities : for example
  the  fast  compiling  of  BPO,  easier  handling  of  binary  files or the
  possibility of defining the visibility of the labels.

   *** For the acquisition of the BAPC  Assembly knowledge is required! ***

     About   this  many  people  forgets  and  with  only  basic  or  pascal
  fundamentals  tries  to  write BAPC programs, and when it doesn't work out
  contacts  us  or  the  mailing  list  revolting  for  help or for a better
  documentation.  In  this  description we WON'T teach you assembly language
  !!!!  You  should learn it from elsewhere, we discuss only the differences
  between  BAPC  and  ASM!  We  suppose  that  the reader knows the assembly
  language,  he  is  alive  to real and protected mode, segments, registers,
  exceptions, file-handling, etc.

     BAP  is a mix of languages, because it mainly includes Pascal, C, Basic
  and  Perl  instructions (with more or less modifications). You may program
  much  easier  and  faster under BAPC than in assembly, but contrast to the
  high level languages the program would be so fast and short as it would be
  written in pure assembly.  The compiler generates directly Assembly (.ASM)
  language, which can be used in many ways: i.e.: can be compiled to .COM or
  .EXE  file  without any changes in the program sources, or can be built in
  another language (i.e.: WATCOM C).

     Something  else:  in  this  documentation,  and  in  other places, this
  program  is being referred to in many ways. The reason for this is that in
  the  beginning  the  BAssPasC  name  gradually  changed,  first  it became
  BASPASC, then BAPC, now we just call it BAP. If we carry on this way, this
  is  going  to be the "B" language... ;-) The official name is "BACP3". The
  version  number  has  been  hit  in because between the different versions
  there  are  a big difference in order of magnitude, and unfortunately some
  incompatibility  (  usually  because of old bugs or limits which have been
  corrected ).

                               2. Installation
                              

     The installation is not difficult. Because you are already reading this
  documentation,  it  is  likely  that  you  have  already  uncompressed the
  program. If not, then I made a mistake... ;)

     Important:  rewrite  the  paths  in  the  CFG  and  BAT  files  to  the
  appropriate directories and you are done.

   2.1. The files
   

    See in LIST-ENG.TXT .


   2.2. BASSPASC.CFG settings
   

    See in CFG-FILE.TXT .

   2.3. BAPC3 command-line
   

     BAPC3.EXE [options] [source[.bp3] [dest[.asm] [errorfile]]]

     for details see CMDLINE.TXT

   2.4. The BAPC and TASM problems
   

     Another  note:  the  compiler  assumes  the  usage  of TASM, but we are
  planning  a  version  for  MASM (only if there is demand for it). But TASM
  versions  are  not compatible, due to this, if you are not using TASM v3.0
  then  we  suggest  using  TASM  with  the  /U300 option, which enables the
  emulation  of  version  3.0.  The  only  difference  (we  noticed) is that
  versions newer than 3.0 of TASM handle segment definitions differently:

        TASM 3.0            -  MOV AX,[ES:DI]
        newer TASM and MASM -  MOV AX,ES:[DI]

     This  is practically indifferent to the BAP compiler, but in the LIB-s,
  the  3.0  forms  were  used,  so it may cause some problems if you compile
  programs which use the LIB-s without the /UT300 option.
     The  other  possible  solution  is  using  the  /NASM option of BAPC at
  compiling, this corrects segment definitions ( theoretically :).

   2.5. The BAPC and NASM
   
   
     The BAPC3 helps NASM assembler in two different way:
     NASM mode: (/NASM option or .NASM at the beginning of the source)
       It  compiles true NASM source, for this reason the generated assembly
    source  can  be directly compiled using NASM. Its drawback, that the ASM
    entities  in the BAPC source should be in NASM syntax, which is not true
    for all the LIBs.
     T2N mode: (/T2N option or .T2N at the beginning of the source)
       The  compiler  makes  a  TASM-NASM  mixed  source,  preparing for the
    conversion using the program ASM2NASM. This way the compiling happens in
    three  different  steps:  BAPC3  -> ASM2NASM -> NASM. In the BAPC source
    both NASM and TASM syntax can be used.

     I  have to give a remark: The BAPC3 is optimized and tested under TASM,
  so  many  problems  can be found using NASM. If you indicate the error for
  us,  we try to correct, or you can do it too, modifying the ASM2NASM ( the
  source can be downloaded from the ESP-team homepage ).
     I  suggest  the  T2N  mode, because in NASM mode many functions doesn't
  work, and even the LIBs cannot be used.

                  3. The structure of BAP language programs
                 

     The compiler accepts (almost) all Assembly instructions and directives,
  and  puts  these  into  the ASM file unchanged. So if we can't use certain
  portions of BAP, we can write those parts in Assembly.
     The  compiler  has  two operating modes: ASM- and BAP-mode. BAP mode is
  assumed  as  the default mode of operation. In this mode, a mixture of BAP
  and  Assembly  can  be  used.  In  ASM-mode only Assembly instructions are
  allowed.  For  more  information  look  at  the  compiler  directives  (4.
  chapter)

   3.1. The structure of the program
   

     In  the  following  section we will introduce a general program format.
  The  data  placed  between  the  relation  signs ("<" and ">") refers to a
  parameter,  so  you  have  to write an actual value there; square brackets
  ("[" and "]") refers to a parameter that can be left out.


    ; [Remark]                               Remarks can be placed anywhere.

    .x86 or .80x86                           This compiles the TASM header.

    USES <1.Library [, 2.Library [,...] ] >  Libraries of LIB extension to
                                             be used.
    INCLUDE <1.header.H [, 2.header [,...]>  Some LIB-s require the header
                                             files (*.H) too.

    <Program body>

    [...]                                    The instructions of the main
                                             program body
    [EXIT]                                   To exit the program.

    [ <Procedure1>::
      [...]
      ret
    ]

    [ <Procedure1>::
      [...]
      ret
    ]

    [...]

   [ INCLUDE file1[,file2...] ]              Procedures stored in other
                                             files

   [ INCLUDEDx file1[,file2...] ]            The required binary data files

     Note:  this was only a general example, most of the instructions can be
  placed anywhere.

     Example: a classical program that writes Hello World:

       .386
       WRITELN'Hello World!'
       EXIT

     Besides  this  the structure of the program is the same as the Assembly
  language  programs,  so  the  rules  are the same i.e.: the placing of the
  procedures,  the Assembly macros (its advisable to use the macros of BAP),
  the loop constructions, etc.

  Comments can be put in a program the following way:
    .COMMENT        ; Don't have to compile from here
    [...]
    .ENDCOMM[ENT]   ; End of the comment, parts needed to be compiled follow
  (This is useful for commenting out large sections of a program)

  Furthermore the notation you are used to from C can be used too:
    /*  Remark ...  */


   3.2. Possibilities
   

    Program lines:
    ~~~~~~~~~~~~~~
     The  main  difference  between  the  BAP  syntax and the syntax used in
  Assembly  is  that  in  BAP,  more instructions can be placed on one line.
  Due  to  this,  instructions which belong together can be put in one line,
  and  the  source  program will become easier to read. The instructions are
  separated by // from each other.

  i.e.:                  MOV AX,10 // MOV BX,10
  or in BAP:            AX:=10//BX:=10

     This will be of great importance in whole line instructions i.e. PUSH(),
  REP(), THENCMD, DO...

    One line written in more lines:
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     Like  in  ANSI  C,  one  instruction can be written in more lines. When
  doing  this  one  has  to  put  a \ sign in the beginning of the following
  lines. (Space and Tab can NOT be used before the \ sign!!). Some examples:

        IF (AX=7 AND BX=6)
      \ OR (AX=6 AND BX=7)
      \ THENCMD !Routine

        or:

      WRITELN'This is a text of more than one line',13,10
      \'of which this is the second line!'

     Note: a full length could be a maximum of SORMAXSIZE !
     ( the current value of SORMAXSIZE can be displayed using BAPC /INFO )


    Procedure:
    ~~~~~~~~~~

  Declaration:
       <Procedure>::
       [...]
       [ret]

  Or the common way:
       <Procedure> PROC NEAR
       [...]
       <Procedure> ENDP
     Note:  the  word  NEAR  can be left out, the compiler will write it for
  you.

     Note:  the declaration using :: or PROC will change the value of ^, due
  to  this,  if  this  is  not  wanted  then <Procedure>:. should be used to
  declare  a  procedure.  This  mainly concerns routines with multiple entry
  points.

  Calling of procedures:
        !<Procedure>
  The result of the compilation:  Call <Procedure>

   3.3. Limitations
   
   
     The  maximal length of the line, the number of labels, and the level of
  instructions  are limited in BAPC. These limits change many times while we
  develop, the current value can be displayed using the INFO instruction :
       BAPC3.EXE /INFO


                            4. Compiler directives
                           

     See in CONTROLL.TXT !
                                  5. Basics
                                 

   5.1. Assigning values
   

     General form: "aa:=bb"
  compiled:
   - if aa=bb, then nothing (i.e. MOV AX,AX makes no sense)
   - if sizeof(aa)<>sizeof(bb) then "MOVZX aa,bb" (i.e. ECX:=DH)
   - if bb=0 and aa=register then "XOR aa,aa" (i.e. AX:=0)
   - otherwise "MOV aa,bb"   (i.e. AX:=3)

     'bb'  can  be  in  a  HI:LO  format  too, meaning we can assign a value
  separately  for  the  lower  and  higher  half  of  bb  separated  by ":".
  I.e."AL:=3:8" is the same as "AL:=16*3+8".
     Note:  if  aa  is not a register, then we the compiler doesn't know the
  size of aa, it will assume it to be a data of 16 bits!

  Assigning values to segment registers
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     When using segment registers one can assign values using the stack too,
  i.e.:  ES=B800h  the  compiler  compiles  this to PUSH 0B8000H//POP ES. or
  i.e.: DS=CS
     This  is  needed  because  you  can not assign direct values to segment
  register like MOV ES,B8000h or MOV DS,CS .

  Assign values to pointers:
  ~~~~~~~~~~~~~~~~~~~~~~~~~~
     register->place_it_points_to
     I.e.: DX->FILENAME (in ASM: LEA DX,FILENAME)

     If  there  is  nothing  after -> , then it will point to the next label
  created   during   indirect-switching,  i.e.:  DX->//VAR  BUFFER:DB*8192 (
  DX->BUFFER // VAR BUFFER:DB 8192 )

     This applies to OFFSET also, i.e.: AX:=OFFSET // CONST SMTHNG:DD=1234

     Remark:  since v3.0+ the // can be omitted before CONST and VAR, -> can
  be written.

  Assigning direct values to registers:
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
i.e.: DOS #(4c00h,BX=CX,,0,SI=7,ofs TABL)
effect:
   MOV AX,4c00h
   MOV BX,CX
   XOR DX,DX    ; OPTIMIZED FORM OF MOV DX,0
   MOV SI,7
   MOV DI,OFFSET TABL
   INT 21H
     If  the  compiler  encounters  #(  and  )  in one line, then the values
  between the parenthesis will be interpreted as direct value assignments.
1. example: #(4c00h)
     There  is no register given, this way the next register in line will be
  assigned the value. (counting starts at AX)
     The order of registers: (default: AX)
       EAX,EBX,ECX,EDX,ESI,EDI,EBP
       AX,BX,CX,DX,SI,DI,BP
       AL,BL,CL,DL,AH,BH,CH,DH
       ES,DS,FS,GS
     - If  there  is  nothing  between  two  commas (,,), then the compiler
  doesn't  modify  the respective register: #(8,,5) -> AX:=8,CX:=5 but BX is
  unchanged
     - If some register is assigned a value of 0, the compiler will optimize
  it with an XOR instruction (this is shorter than MOV)

2. example: #(BX=7) or #(BX:=7)
     There  is  a  register defined here, so the value will be placed in the
  defined register (MOV BX,7 will be put in the .ASM file)
     If  the register is present in the above mentioned register order list,
  then the register counter will be placed to the respective register.
     i.e.: #(BX=7,8) then BX=7 and CX=8, and the register counter will point
  to DX.

  mem->mem value assignment:
  ~~~~~~~~~~~~~~~~~~~~~~~~~~
    RMOV dest,src        =>  AX:=src//dest:=AX
    RMOV dest:=src       =>  AX:=src//dest:=AX
    SMOV dest,src        =>  PUSH src//POP dest
    SMOV dest:=src       =>  PUSH src//POP dest
    RMOV(reg) dest,src   =>  reg:=src//dest:=reg
    RMOV(reg) dest:=src  =>  reg:=src//dest:=reg
  Note:  you can leave the space out after the ), but the source will not be
  as readable. i.e.: RMOV(AX)LABEL1:=LABEL2

  LDD, LDDM, SDD, SDDM instructions:
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 LDD[M] op1:op2,op3  ; op1:=HI(op3) and op2:=LO(op3) ; separation of a 32 bit
                                                       value
    LDD: through the stack: PUSH op3//POP op1//POP op2
    LDDM: with memory indexing: MOV op2,WPT op3 // MOV op1,WPT op3[2]
 SDD[M] op3,op1:op2   ; op3:=(op1 SHL 16)+op2        ; putting a 32 bit value
                                                       together
     Note: you can separate or put together values in memory using the stack
  (SDD,LDD)!

   5.2. Mathematical and logical operators
   

        BAP:       ASM:      function:

       ++aa      INC aa     aa=aa+1        incrementing by 1
       --aa      DEC aa     aa=aa-1        decrementing by 1
       aa+=bb    ADD aa,bb  aa=aa+bb       addition
       aa-=bb    SUB aa,bb  aa=aa-bb       subtraction
       aa&=bb    AND aa,bb  aa=aa AND bb   logical AND
       aa|=bb    OR  aa,bb  aa=aa OR bb    logical OR
       aa?=bb    CMP aa,bb  aa ? bb        comparation
       aa<>bb   XCHG aa,bb  aa<=>bb        exchanging values

     Note: <> (exchanging of values) works even when neither of the operands
  is a register, in this case it uses the stack. I.e.: DS<>ES, MEM1<>MEM2

       >>aaa     SHR aaa,1
       <<aaa     SHL aaa,1
       aaa>>n    ROR aaa,n
       aaa<<n    ROL aaa,n
       aaa>0>n   SHR aaa,n
       aaa<0<n   SHL aaa,n
       aaa>C>n   RCR aaa,n
       aaa<C<n   RCL aaa,n

     Omission of parameters:
     ~~~~~~~~~~~~~~~~~~~~~~~
     You don't need to define all of the parameters for some instructions:
  1.  When  using the SHR,SHL,RCR,RCL,ROR,ROL,SAR instructions, you can omit
  the ,1 . (i.e.: SHL AX = SHL AX,1 )
  2. When using the XOR,ADD,SUB,OR,TEST,AND instructions using one parameter
  assumes the other being the same (i.e.: XOR AX= XOR AX,AX )

   5.3. Abbreviations
   

    SH  = SHORT
    OFS = OFFSET
    BPT = BYTE PTR
    WPT = WORD PTR
    DPT = DWORD PTR
    QPT = QWORD PTR
    TPT = TBYTE PTR

   5.4. Labels
   

 Automatic label generation:
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @:  ; this generates a label, which can be referred to with a @ or a @n
    symbol. When using @n , n refers to a relative line number:
      @0 = @ = the previous @:
      @1 = the next @:
      @-1 = the @ before the previous @:
    This is useful when making loops: @: loop_code // LOOP @

 MULTILABELS:
 ~~~~~~~~~~~~
     Now  you  besides  the  @:  there  is @A:...@Z: too, and each one has a
  different counter. This way there are 27 labels which you can manage! ;-)
     I hope this will be enough for everyone...
   i.e.:
   JMP @A1 >Ŀ
   @:       <Ŀ 
   CX:=10           
>@A:      <
  !ROUTINE//JNZ @ 
LOOP @A

 Local labels: ^
 ~~~~~~~~~~~~~~~
  Assigning values:
    - WITH labelname     ;  ^ = label
    - ENDWITH            ;  ^ = label before WITH
    - name::             ;  ^ = name  (name of subroutine)
    - name PROC [NEAR]   ;  ^ = name  (name of subroutine)
    - name ENDP          ;  ^ = label before PROC
  Note: an underscore (_) is placed before the label: ^ = label + '_'
  i.e.:  ROUTINE:: JCXZ ^END//...//^END: RET
  Importance: the same label can be used in many different subroutines too
              (i.e.: ^END:)
  Note: WITH remembers the last 32 labels, and one label can be a maximum
        of 128 characters long.

 Redefinable label: ~
 ~~~~~~~~~~~~~~~~~~~~
     Value assignment: ~=label
     It doesn't change until the next ~= , so it's independent from the sub-
  routines.  This  can  be used well in LIB-s, when the same value has to be
  accessed  many  times in a LIB, but it shouldn't affect the other LIB-s or
  program parts.

 Start of line label: 
 ~~~~~~~~~~~~~~~~~~~~~~
     This  possibility exists since version 2.3 of BAPC, which makes writing
  smaller  loops  easier. Because instead of writing "@: loop_code//LOOP @",
  it's  enough  to write "loop_code//LOOP ". The compiler generates a label
  to  the  start of the line, and the  found in the same line gets replaced
  by  this label. The only exception to this is the PUSH() instruction, when
  this produces wrong code. Due to this, it puts the label after the PUSH().
   STOSW//LOOP //PUSH(DI) LODSB//++CX//JNZ //PUSH(SI) LODSB//STOSW//LOOP 
   <           <           <

  i.e.: PUSH(BX) !ROUTINE//--BX//JNZ 
  Compiled:
    PUSH BX
      label:
        !ROUTINE
        --BX
      JNZ label
    POP BX

 Special labels:
 ~~~~~~~~~~~~~~~
   ENDIF as a label: jumps to the next ENDIF
   RET, RETC, RETS : jump to the previous (or there is no such instruction
                     before, then the next) instruction like these.

   5.5. Variables
   

     Variables  defined in clear ASM language should be placed separate from
  the code in one place. Something like this:
      VARIABLE1 DW ?
      VARIABLE2 DD ?
      VARIABLE3 DD ?
      ARRAY DB 256 DUP (?)
      ...

     BAP makes it possible to put variables between our code.
     The declaration of the variables is similar to that of PASCAL.
     The example above in BAP form:
         VAR VARIABLE1:DW
         VAR VARIABLE2,VARIABLE3:DD
         VAR ARARY:DB*256
     VAR  instructions  can be written anywhere. It's not necessary to place
  them  after  the  code  in  one  pile. This makes it possible to place the
  variables next to the initialization:
  VAR   VARIABLE:DW   //  VARIABLE:=start_value
     Further,  if the start_value is in a register, then the type definition
  can be omitted and VAR TEMP_AX=AX is enough, this is the same as
  VAR TEMP_AX:DW//TEMP_AX:=AX in practice.
     If  a  variable is a pointer type, then the starting value can be given
  like:
  VAR POINTER->PLACE_IT_POINTS_TO
     This is the same as VAR POINTER:DW//MOV POINTER,OFFSET IT_POINTS_TO...
     Note:  an  array  can  be  assigned  a starting value, but this will be
  placed  in  the first record of the array, and the whole array will NOT be
  filled with this value.

     Note:   Variables   get   placed   in   the  VAR  indirect.  Except  if
  .VARIND=something has been used to redefine the name of the indirect.

   5.6. Constants
   

     In  pure  ASM we declared the constants separated from the code, in one
  place, something like this:
       MYCONSTANT1 DW 1234
       MYCONSTANT2 DB 'Hello world!'
     BAP makes it possible to write the constants between the code.
     In BAP this looks like this:
       CONST MYCONSTANT1:DW=1234
       CONST MYCONSTANT2='Hello world!'
     (So when using strings, you don't have to specify the type)

     Note:  Constants  get  placed  in  the  indirect called CONST. Except if
  .CONSTIND=something has been used to redefine the name of the indirect.

   5.7. Strings
   

     Strings  can  be  defined  in  the parameters of instructions too, they
  don't have to be named separately.
  i.e.: WRITE 'Hello world'
  In ASM this would look like:
    ; code:
    LEA DX,label
    MOV AH,9
    INT 21h
    ...
    ; constants:
    label DB 'Hello world',36

     We can use the string definition in special cases too, with the help of
  STROFS:
      DX:=STROFS'Hello world',36
     or even simpler:
      DX->'Hello world',36

    Notes:
    - OFSSTR can be used instead of STROFS
    - -> can only be used if it is followed by a ' , while you can use STROFS
      followed by numbers: SI:=STROFS 13,10,'Hello',13,10,36
    - STRINGS defined like this get place in the TEXT indirect.

   5.8. Segment-prefixes
   

     CS:,DS:,ES:,FS:,GS:,SS: get compiled 'DB nn', this way they can be used
  before any instruction.
     i.e.: ES:LODSB (in ASM this would be: LODS BYTE PTR [ES:SI])
     Warning! ES: segment can not be redefined! (STOSx,SCASx)

   5.9. Code-repetition
   

    The format is: REP(count) thing_to_repeat
    "thing_to_repeat" gets compiled "count" times after each other.
    i.e.: REP(16) STOSB//AL+=3
    "count"  has  to  be  a  decimal or hexadecimal number, it can not be a
  label or anything else.


                               6. Instructions
                              

   6.1. Conditional instructions (IF, CASE)
   
  

    Conditions:
    ~~~~~~~~~~~
      See in CONDITIO.TXT !!!!!

    THEN label -structure:
    ~~~~~~~~~~~~~~~~~~~~~
       It jumps to the label if the condition is true:
       IF condition THEN label

    THEN/ELSE/ENDIF -structure:
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~
       - ELSE is not mandatory
       - THEN is not mandatory (IF condition  is enough)
       - The maximum nested IF statements is 64.
       IF <condition> THEN
          [instructions...]
          [...]
       ELSE
          [instructions...]
       ENDIF

    THENCMD-structure:
    ~~~~~~~~~~~~~~~~~~
       IF <condition> THENCMD <instructions...>
       this can be used when we have short instructions, i.e.:
       IF AX>CX THENCMD AX:=CX
       note: when using THENCMD the instructions until the end of the line
             (not until //) get compiled to be executed when the command is
             true!
       In practice IF <condition> THENCMD <something> gets compiled like this:
         IF <condition> THEN
           <something>
         ENDIF
       Because of this the use of ELSE after THENCMD is allowed!
       i.e.: IF AX=5 THENCMD WRITELN'AX=5"//ELSE WRITELN'AX<>5'

       Remark: since v3.0 instead of 'THENCMD'  'DO' can be used, too:
         i.e.: IF AX>CX DO AX:=CX

    CASE instruction:
    ~~~~~~~~~~~~~~~~~
  i.e.:  CASE AL OF
        1,3,^XYZ: NOP           ; THENCMD-type
        128:                    ; THEN..ENDIF type
          INSTR1//INSTR2        ; Any number of line can be written
          INSTR3//END         ; the end of the line is marked by "END"
        'A'..'Z':>ROUTINE       ; jump to ROUTINE
        ELSE
          This the place for ELSE  ; if none of the above is true...
        ENDCASE
     Note:  between  CASE and ENDCASE (except if there is a part closed with
  END),  things  before  the  first  colon  are used as the condition, i.e.:
  "abc:   instructions"   is  the  same  as  "IF  case_var  IN[abc]  THENCMD
  instructions"  (where  case_var  is the thing between CASE and OF). So the
  things  written  for  IN[...]  are  valid  for  things before the colon! A
  "abc:>label" is going to be "IF case_var IN[abc] THEN label"!

       6.2. Loop construction
       

      Front testing loops:
      ~~~~~~~~~~~~~~~~~~~~~~

      The cycle gets repeated while the condition is true.
      Note: things stated in CONDITIO.TXT apply to the <condition> !

      WHILE/ENDWHILE structure:
         WHILE <condition>
           <instructions...>
         ENDWHILE

         WHILE/DO structure:
      WHILE <condition> DO <instructions...>
      or
      WHILE <condition> DOCMD <instructions...>


     Back testing loops:
     ~~~~~~~~~~~~~~~~~~~
   REPEAT/UNTIL structure:
      REPEAT
         <instructions...>
      UNTIL condition
   This loops get executed at least once, and until the condition turns
   true. (If the condition is true, then the loop stops)


     Incremental cycles:
     ~~~~~~~~~~~~~~~~~~~
   1. Simple LOOP cycles:
   ~~~~~~~~~~~~~~~~~~~~~~
     LOOP(size) something//something//...
     LOOPF(size) something//something//...

   LOOPF checks with a JCXZ if it can run the cycle.
   'size' goes into CX and will be the number of repetitions.

   2. FOR instructions:
   ~~~~~~~~~~~~~~~~~~~~
   It has 2 main types, CMP type and LOOP type. Both start with a FOR
   and the end of the cycle core is marked with the NEXT instruction!

   1. FOR[P][F][E][An] a[:]=b [DOWN]TO c [STEP x] [DO cmd1//cmd2...]
      F=forward (front testing)
      S=signed  (the numbers are signed)
      E=EQU (if it should reach 'a' or 'b')
      P=push a  (stores the value in the stack for the time of the cycle core)
      An = .ALIGN n  (should only be used when optimizing for speed)

      - TO = counts upwards, DOWNTO counts downwards.
      - If there is a STEP x defined, then the count will go by steps of x
      - if there is a DO defined, then the part after the DO will be the cycle
        core and there is no need for NEXT at the end.

     Working:  the  value of 'a' goes from 'b' to 'c', if flag E, it reaches
  it. Step is +1 if TO, -1 if DOWNTO, 'x' if STEP.

   2. FOR[P]L[P][An][F][S][([lr,]lc)] a:=b [TO|DOWNTO|STEP x] [DO cmd1//...]

      P=push a   (before the L)
      L=loop     (the next parameter)
      E=whether to reach 0
      P=push CX  (after the L)
      An = .ALIGN n
      F=forward testing (JCXZ, if lc is 0, definitely no loop is done)
      S=short  (it uses a LOOP instruction instead of --CX//JNZ , for a cycle
                core that does not exceed 128 bytes in length)
      lr=loop register, default: CX/ECX     (v3.0a17+)
      lc=loop counter, the default value of the loop register

     Working:  the  value of 'a' goes from 'b' to 'c', if flag E, it reaches
  it.  Step  is  +1 if TO, -1 if DOWNTO, 'x' if STEP. The loop register (lr)
  counts continuously from the loop counter (lc) to 1, or to 0 if flag E.
     Remark: If E flag is present, it will looped lc+1 times !

     Note: the order of the options does not matter, except for the order
           of P and L.

   I.e.
   Incorrect:
     FOR a:=b
     FORL a

   Correct:
     FORPL a
       @: PUSH a//...//POP a//loop @
     FORL a:=5
       MOV a,5//@:...//LOOP @
     FORL a TO
       @: ...//++a//LOOP @

   6.3. Complex stack handling
   

  1. PUSH r1,r2,r3... and POP r1,r2,r3...
     (the order does not have to be reversed)

  2. Special values:
     ALL = PUSHA         (i.e.: PUSH ALL,FL,CIM1)
     AD  = PUSHAD
     FL  = PUSHF
     FD  = PUSHFD
     AS  = PUSH ALL,DS,ES

  3. instructions of a whole line: PUSH(r1,r2,...) xxxx
     this saves r1,r2,... in the stack for the time of the xxxx instructions
     ( PUSH r1,r2,...//xxxx//POP r1,r2,...)

  4. If there just a 'PUSH' (nothing following it), then the parameter of
     of the last PUSH instruction gets stored in the stack again, so
     i.e.: PUSH AX//PUSH// stores AX twice in the stack!

     If there just a 'POP' (nothing following it), then the parameter of
     of the last PUSH instruction gets saved from the stack, so
     i.e.: PUSH AX//POP// stores and restores AX from the stack!

     PUSH and POP 'remembers' 32 levels and a can save a line of maximum
     63 characters.

     i.e.:

       PUSH AX//PUSH//PUSH ^LABEL   =>  PUSH AX//PUSH AX//PUSH ^LABEL
       then:
       POP//POP//POP   =>  POP ^LABEL//POP AX//POP AX

   6.4. Keyboard and screen handling
   
   
     Keyboard handling:   ; output: AH=scan code AL=ascii code
     ~~~~~~~~~~~~~~~~~~
  WAITKEY       ; XOR AX//INT 16h     waits for a keypress
  READKEY       ; AH:=1//INT 16h      read the status of the buffer
  READSHIFT     ; AH:=2//INT 16h      state the SHIFT/CTRL/ALT keys
  GETKEYn       ; AH:=n//INT 16h      the previous 3 inst. in another form

     Positioning on the screen:
     ~~~~~~~~~~~~~~~~~~~~~~~~~~
  GOTOXY x,y         ; DL:=x//DH:=y//GOTOXY
  GOTOXY y:x         ; DX:=x+y*256//GOTOXY
  GOTOXY value       ; DX:=value//GOTOXY
  GOTOXY
  WHEREXY

     Writing to the screen:
     ~~~~~~~~~~~~~~~~~~~~~~
  WRITE'string'      ; writing a string
  WRITELN'string'    ; -//- and a linefeed + carriage return
  WRITELN            ; just a linefeed
  WRITESTR label     ; = DX->label//WRITESTR
  WRITESTR           ; = DOS 9
  WRITECHR c1,c2,,c3 ; write characters, if there is nothing between two
                     ; commas, then the last character gets repeated

   Note: the character writing instructions are redefinable:
     .FC option:   FastChar, then the writing will be done by INT 29h
     .CHARCMD=xxx: User defined writing routine (i.e. AH:=15//STOSW)

   6.5. File instructions
   

    General format: FILExxx [VAR] [handle]
    'handle' is the name of the file-variable, VAR can signal, if the
    compiler has the define the variable not us. Instructions:

    Open:
    ~~~~~
     FILEOPEN   =  DOS 3D00h[//handle:=AX]    open file to read
     FILEOPENR  =  DOS 3D00h[//handle:=AX]    open file to read
     FILEOPENW  =  DOS 3D01h[//handle:=AX]    open file to write
     FILEOPENRW =  DOS 3D02h[//handle:=AX]    open file to read and write
     FILEOPENP  =  DOS 3D10h[//handle:=AX]    protected file open to read
     FILECREATE =  CX:=20h//DOS 3Ch[//handle:=AX]  create a file

   Handling:
   ~~~~~~~~~
     FILEREAD   =  [BX:=handle//] DOS 3Fh     read a block
     FILEWRITE  =  [BX:=handle//] DOS 40h     write a block
     FILECLOSE  =  [BX:=handle//] DOS 3Eh     close a file
     FILECALL   =  [BX:=handle//] DOS         general file operation call
   Remark: after FILECLOSE multiple file-handle can be given, too

   Positioning:
   ~~~~~~~~~~~~
     FILEPOS     =  [BX:=handle//] DOS 4200h  from the start of the file
     FILEPOS0    =  [BX:=handle//] DOS 4200h  from the start of the file
     FILEPOSREL  =  [BX:=handle//] DOS 4201h  relative
     FILEPOS1    =  [BX:=handle//] DOS 4201h  relative
     FILEPOSBACK =  [BX:=handle//] DOS 4202h  from the end of the file
     FILEPOS2    =  [BX:=handle//] DOS 4202h  from the end of the file

   Special positioning:
   ~~~~~~~~~~~~~~~~~~~~
     FILEHOME    =  [BX:=handle//] XOR CX//XOR DX//DOS 4200h  jumps to the start of the file
     FILEAPPEND  =  [BX:=handle//] XOR CX//XOR DX//DOS 4202h  jumps to the end of the file
     FILEWHATSIZE=  [BX:=handle//] XOR CX//XOR DX//DOS 4202h  DX:AX=length of the file
     FILEGETPOS  =  [BX:=handle//] XOR CX//XOR DX//DOS 4201h  DX:AX=file position

   FILEPOS like variable:  (since BAPC v2.32)
   ~~~~~~~~~~~~~~~~~~~~~~
     FILEPOS:=x  ->  FILEPOS = x
     FILEPOS+=x  ->  FILEPOS = FILEPOS + x
     FILEPOS-=x  ->  FILEPOS = FILESIZE - x  (NOT FILEPOS=FILEPOS-x !!!)
   Remark: "x" can be a number, no memory variable or register allowed yet!

   Miscellaneous:
   ~~~~~~~~~~~~~~
     FILEDELETE  = Deletes the file
     FILERENAME  = Renames the file
     MKDIR       = Creates a directory
     CHDIR       = Changes the current directory
     RMDIR       = Removes a directory entry

  Example for a short file dumper:
  .386
  DX->'filename',0
  FILEOPEN VAR NUM               ; opening of the file, the name is in DX
  ;
  DX->//VAR BUFFER:DB*8192
  CX:=8192
  FILEREAD                        ; Reading, place in DX, length in CX
  ;
  SI:=DX
  LOOP(AX) WRITECHR LODSB         ; Writing to the screen
  ;
  FILECLOSE                       ; Close the file
  EXIT

   6.6. Miscellaneous instructions
   

   - UPCASE reg  : reg:=UPCASE(reg), a makes the character uppercase.

   - DECODE reg  : reg:=decode(reg), decoding with the codes specified in
                   .CODE=x,y .

   - INTCALL xx  : calls interrupt,  PUSHF//CALL DPT xx

   - DOS         : INT 21h   (calling of DOS-functions)
     DOS xx      : AH:=xx//INT 21h
     DOS xxxx    : AX:=xxxx//INT 21h

   - MOUSE xxxx  : AX:=xxxx//INT 33h
     EGERBE      : turns the mouse cursor on
     EGERKI      : turns the mouse cursor off
     GETMOUSE  =>  BX=buttons, CX=x  DX=y  reads the coordinates of the mouse
     SETMOUSE  <=  CX=x, DX=y              set the coordinates of the mouse
     RESETMOUSE or INITMOUSE  => AX=0 if error, AX=255 if ok, BX=num. of buttons

   - BIOS,
     BIOS xxxx   : VIDEO-BIOS functions, AX:=xxxx//INT 10h

   - DOSEXIT,      Exits the program and returns to DOS...
     DOSEXIT xx  : AX:=4C00h+xx//INT 21h  (xx=return code)

   - EXIT,
     EXIT xx     : by default, it's the same as DOSEXIT, but this one can be
                   redefined with the .EXIT=xxx instruction!!

   - OUTAL and OUTAX  : OUT DX,AL and OUT DX,AX
   - OUTB p1,p2,...  : AL:=p1//OUTAL//AL:=p2//OUTAL...
                       the giving of parameters is the same as with WRITECHR

   - RETC        = CLC//RET   ; Note: these can be referred to as addresses
   - RETS        = STC//RET

   - ALDIV xx -> DB 0D4h,XX  [This non documented instructions divides the
                 value in AL with xx, and the remainder goes into AL, the
                 result goes into AH
                      >> SPEC. CASE: ALDIV 10  DB D4,0A  AMM <<

   6.7. String-like operations
   

   STOSxy:    general form: STOSxy data1,data2...
   ~~~~~~~
   STOSxy (if there is no y, then y=x) gets interpreted the following way:
     it stores the size of data specified in x
     and loads the register with the size in y (B->AL, W->AX, D->EAX)
   This way you can write: STOSBW,STOSWB,STOSDD, or any other combination)
   i.e.:  STOSWB 'H','W'   =>   AL:='H'//STOSW//AL:='W'//STOSW
   i.e.:  STOSB 'H','W'    =>   AL:='H'//STOSB//AL:='W'//STOSB

   OUTB and OUTW, work the same way as STOSx:
   ~~~~~~~~~~~~~
     OUTB x1,x2,...  ->  MOV AL,x1//OUT DX,AL//MOV AL,x2//OUT DX,AL...
     OUTW x1,x2,...  ->  MOV AX,x1//OUT DX,AX//MOV AX,x2//OUT DX,AX...

   REP*n:
   ~~~~~~
   you can specify the number of repetitions directly by REP, i.e.:
   REP*1000 STOSD 0
   compiled:
     CX:=1000
     EAX:=0
     REP STOSD

   6.8  The macroset STDBAPC.H             [v3.0+]
   

     The  instructions in this chapter can be found in the file STDBAPC.H as
  a  macroset,  as  a discharge. Using it the compiling would be faster, and
  the  parameters  can  be  given  much  easier. Another welfare is that the
  macros  are  built  on  each  other like OOP, so modifying a macro all the
  other  macros  are inherited from that are modified too. For this only the
  "INCLUDE STDBAPC.H" line is needed at the beginning of the source.


                            7. Modular programming
                           

   7.1. INDIRECT-s
   

     This  means,  that  we  can  edit  more  than one part at a time of our
  source. So: if we put an instruction, or a group of instructions between {
  }-s, then, the part between the { } gets placed in a temporary file, who's
  name  should  be  written directly after the { . In the future these files
  can  be  fitted  in  the  code  by  referring  to  them with the .INDIRECT
  name1,name2,  ...  instruction, or can be fitted in with and .INDIRECTCALL
  in the appropriate place.

  i.e.:
  .386
  WRITELN'FIRST'
  {XYZ WRITELN'THIRD' }
  WRITELN'SECOND'
  .INDIRECT XYZ
  WRITELN'FOURTH'
  EXIT

  Typical area of use:
   - defining of variable, and constants between the code
   - moving code parts
   - making initialization routines

  Special INDIRECTS also exist:
      VAR   this is where the variables get placed (see at the VAR command)
      CONST this is where the constants get placed (see at the CONTS command)
      TEXT  this is where the texts get placed (see WRITE... and STROFS)
      FPUCONST  this  is  where  the  constants  generated because of FPU get
                placed (i.e. FLD 5.3)
     The name can be changed with the .VARIND= .CONSTIND= ... commands.

  These can be written to directly:
    CONST: DB 'this get placed in CONST!'
  a practical example:
    VAR: .ALIGN 16

     It's  important  to  note,  that the compiler puts all of the indirects
  that haven't been fitted, at the end of the program, the order is the same
  as  the order of the definitions, except that the indirects beginning with
  'VAR' always gets placed last.

   7.2. The usage of routine packages (LIB-s)
   

     You  can  use  routine  libraries with the help of the BAP compiler, of
  which only the used routines get compiled.

     These  routine packages are generally in files of .LIB extension (their
  PMODE  versions  get  a .PML extension), and are in one (or more) separate
  directories,  which  is  (or  are)  defined by the LIBDIR= variable in the
  BASSPASC.CFG  file.  There  is a basic LIB-kit for BAP, which contains all
  the  more important routines, starting from the string operations, all the
  way  to routines to help program the graphic and sound cards. (see chapter
  9.)

     Generally  there  is  a file of .H extension, that belongs to the newer
  (made  relative  to the v2.0+ of BAP) LIB-s, which contains the functions,
  macros and structures. These can be included with the INCLUDE command.

     The commands to use these are the following:

 CALL procedurename  or  !procedurename
 ~~~~~~~~~~~~~~~~~~      ~~~~~~~~~~~~~~
     Calling  of  a  subroutine,  if it is not in the source of the program.
  This routines are looked for in the LIB-s defined by USES.

 .COMPROC procedurename
 ~~~~~~~~~~~~~~~~~~~~~~
     This  asks  for the compilation of the routine, it's like a CALL, but a
  CALL  instructions  does  not  get  compiled.  This  is generally used for
  interrupt handling routines, which are not called with a CALL instruction.

 .DEFPROC procedurename
 ~~~~~~~~~~~~~~~~~~~~~~
     Tells  the  compiler  that  'procedurename' is the name of a procedure.
  This is needed, if for example 'procedurename' gets called as a procedure,
  but  is  defined  to  be something else. (i.e. a label or a variable) It's
  usage  is not mandatory, but advisable if we don't want any warning during
  compilation.
  i.e.:
    CALL ROUTINE_PTR
    .DEFPROC ROUTINE_PTR
    VAR ROUTINE_PTR:DW

 USES lib1,lib2...
 ~~~~~~~~~~~~~~~~~
     It's  advisable  to  use this command at the start of the program. It's
  affect is that, the routines needed will be copied in at the .INDIRECTCALL
  command, or at the end of the program.

 INCLUDEPROC lib1,lib2...
 ~~~~~~~~~~~~~~~~~~~~~~~~
     The  needed  procedures  will  be  we  copied  in  at the place of this
  command.

   7.3. Compiling of INCLUDE files
   

    INCLUDE file.inc [,file2,file3...]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     Inserts a BAP language file or files.
     Note: the header (.H extension) files also get placed in with this, but
  at the very start of the program)

    INCLUDEDx file.dat (x can be B=byte, W=word, D=dword, or Q=qword)
    ~~~~~~~~~~~~~~~~~~
     Inserts a binary data file in the form of DB/DW/DD/DQ.

     If you don't need the whole file, then you can specify a range:
      INCLUDEDB filename[SC,EC]    (SC=start position, EC=end pos. or +size)
     if  the specified number is negative, then it means that it's specified
  relative to the end of the file.
     if EC is positive, then it gets add to SC, so we defined a length. This
  works with all of the INCLUDEDx too of course...
     IF ec>filesize, then the compiler displays a !!Warning!! too.
     Note:  EC  refers  to the last byte (not the byte after the last byte)!
  But  for example with INCLUDEDW, it doesn't refer to the last word, but to
  the last byte...!!


    CODEINCLUDEDx file.dat
    ~~~~~~~~~~~~~~~~~~~~~~
     The data file gets fitted, encoded. (see also DECODE reg and .CODE a,b)

    ASMINCLUDE file.asm
    ~~~~~~~~~~~~~~~~~~~
     Inserts  an  Assembly  language file, and does not compile it, this way
  the compilation will be faster.

   7.4. BAP Object (BPO)
   

     A  .BPO file can be made from a .INC file which can be compiled faster,
  and  does  the  same  thing, with the /BPO switch of the compiler. So it's
  useful to compile (once) those .INC files which are not altered frequently
  into  .BPO  files  and  to  change  the  "INCLUDE  file.INC"  to  "INCLUDE
  file.BPO".
     Note: If you modify the original .INC file, then you have to compile it
  to  .BPO  format  yourself! (The compiler notices the change and gives you
  a warning!)

     This  is  useful  mostly if you are compiling on a slow machine, or the
  whole  source  code  of a program is long, otherwise the speed increase is
  not significant.

     Note:  When  compiling to .BPO you have to make sure, that the .H files
  are  INCLUDE-ed in the .BPO file that you compile, otherwise the macros do
  not  get compiled. You shouldn't compile OOP programs to .BPO, because the
  macro changes will not be inherited.

  The structure of the .BPO file:
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  .FILEINFO filename,size,datetime  ; this is how the compiler knows that...
  .ASM                              ; ...it has been modified
  ...    ;A program (.INC) compiled to ASM
  .BAP
  USES xxxx
  .DEFPROC xxx  ;; So the CALL-s will be ok (not to get a  Proc Not Found)
  .COMPPROC xxx ;; So the .LIB-s will be ok (to compile what we need)
  {indirect1_name  ; The contents of the .IND file-s
  .ASM
  ...  ; the contents of the .IND file
  .BAP
  }
  {indirect2_name
  ...
  }
  ...

   7.5. The usage of PACKAGE-s
   

    See in PACKAGE.TXT .


                           8. Macros and functions
                          

     At the start, macros and functions were 2 different things in BAPC, but
  now they bound together!

  Definition:
    #macroname(input_parameters):output_param=instructions

  Usage:
    macroname(input_parameters)
  or
    macroname input_parameters

  macroname  = name of macro, one word, like it was a label

  input_parameters = register or a label, the used input parameters
                     will be copied here!
                       i.e.:        #MACRO(CX,EAX,ADDRESS)=!ROUTINE
                       calling:    MACRO(BH,DH,12)
                       compiled:   CX:=BX//EAX:=DH//ADDRESS:=12//!ROUTINE

  output_parameter = if the macro is a function then this will be it's output
                     parameter
                         i.e.:        #MACRO(DX):BX=!ROUTINE
                         calling:    ADDRESS:=MACRO(12)
                         compiled:   DX:=12//!ROUTINE//ADDRESS:=BX
                     Note: %n can be used here too!

  instructions = this is where the code that will be executed comes, that goes
                 between the output and the input parameters. This can be left
                 out, but you still have to include the = sign!
                 ( i.e.: #MACRO(AX):AX= )

                 The input parameters can be reached with the %n, just like in
                 batch languages, i.e.: #MACRO=BX:=%1 is the same as #MACRO(BX)=
                 If you refer to something with %n that has not been given when
                 calling the macro, then you will get an error message. Because
                 of this, the parameters that were not mandatory have to be
                 marked with %?n.
                 I.e.: #REP32=DB 67H//REP %?1
                   This can be called two ways:
                      REP32   or:    REP32 LODSB
                   neither of these causes an error when compiling!

 If there are output parameters given when the macro is defined, then the
 macros can be used like functions:
 i.e.: Defining:   #ALLOCMEM(BX):AX=DOS 48h
      Calling:    MEMSG:=ALLOCMEM(1000h)

  Special output parameters can be given, i.e.:
  def:    #NUM:(%1 IN ['0'..'9'])=
  call:  IF NUM(AL) AND NUM(AH) THENCMD WRITELN'This is a number!!!'

  The output parameter can change, according to the input parameter:
  i.e.:  #MEM_ADD:%3=%3:=%1//%3+=%2
        ADDRESS3:=MEM_ADD(ADDRESS1,ADDRESS2,AX)
        (the third parameter here refers to the register to be used)

     With  these  macros, it's possible to write object oriented programs in
  BAP.  Furthermore,  BAP  instructions can be redefined, i.e. after #MOV=MOV
  %2,%1  the compile "goes crazy", because it switches the parameters of the
  MOV instructions! =)
     A  good  practical  example  of this is when the redefining the WAITKEY
  instr. when you want to use a screensaver or a keybar...

    The "only-function"-s
    ~~~~~~~~~~~~~~~~~~~~~
     As  I  have  stated,  in  the  beginning,  macros  and functions were 2
  different things, some things - mainly due to compatibility reasons - have
  stayed:

  SETOUT routinename=outputparam   ; the defining of outgoing parameters
  I.e.: after SETOUT !ROUTINE2=CX   AX:=!ROUTINE2 compiled: is !ROUTINE//AX:=CX

     Note:  if we refer to a routine like a function, whose parameter has not
  been  specified  with SETOUT, then by default the parameter is going to be
  AX.  i.e.:  DX=!ROUTINE  compiled:  !ROUTINE//DX:=AX  (only if there was no
  SETOUT!)

 The detailed description of the syntax and parameterization of macros can be
 found in MACRO.TXT, the list of inbuilt, special macros and functions is in
 FUNCTION.TXT !

                  9. The description of the routine packages
                 

     These  could  be  found  in  the  LIB-DOC  directory  in  a file called
  libname.TXT,  if  not,  then  a  documentation  of  that  LIB has not been
  completed.  :(  In  this  case, I recommend the reading of the .H and .LIB
  files,  generally  you  can  understand  everything from the comments. The
  reviewing of the sample programs is also very helpful...


                            10. Free registration
                           

  Because BAP is CardWare, the registration is totally free!!!

  The registration:
  - read and fill out REGISTER.TXT !!!
  - Get in contact with us, and send it to us, in the reply, you will get a
    BASSPASC.REG file, which you will have to copy in your compiler directory

    - send it in an E-mail, this would be the easiest solution.

      my address:  Gereffy rpd
                     (GyikSoft)
                arpi@banki1.banki.hu

         in the SUBJECT write: BASSPASC REGISTRATION

    - or send via snail mail, but DO send a disk, and a self addressed,
      stamped envelope too! (if you're not Hungarian, then it's not the
                        recommended way, but just do it, if you think!)
      (if you've written a good program too, then send it along! :-)
      the address:    Brthzi Andrs
                         (Boogie)
                      1043, Budapest
                       Nyr utca 53.

     I'm sure you are thinking: if it's FREE, then what's the use of it? The
  answer  is  simple: because BAssPasC is a new initiative, we would like to
  keep  track of how well it spreads, how many people use it, is it worth it
  to make new versions, or are we the only ones using it? So if you like it,
  and would like new versions, then write to us, and register your copy!

  Why is it good to register?
    - you will constantly get the info of new versions (if you want to)
    - if you are stuck, or don't understand something, then you can write
      us in E-mail and we will help you (if we can)

 --------------------------------- THE END ------------------------------------

