•  Back 
  •  Main 
  •  Index 
  •  Tree View 
  •  Cross references 
  •  Help 
  •  Show info about hypertext 
  •  View a new file 
Topic       : The GFA-Basic Compendium
Author      : GFA Systemtechnik GmbH
Version     : GFABasic.HYP v2.98 (12/31/2023)
Subject     : Documentation/Programming
Nodes       : 899
Index Size  : 28056
HCP-Version : 3
Compiled on : Atari
@charset    : atarist
@lang       : 
@default    : Document not found
@help       : Help
@options    : +g -i -s +z
@width      : 75
@hostname   : STRNGSRV
@hostname   : CAB     
@hostname   : HIGHWIRE
@hostname   : THING   
View Ref-FileThe basic method will now be demonstrated with the aid of an example. The
routine to be included is to fill the elements of a two-byte array with numbers
from 0 to n, passing the address and the size of the array. The parameter
passed for the array size will only be a two-byte variable so that the size of
the array is limited to 32267 elements. The function carrying out this task
will work without the use of library functions.

The GFA-BasicGFA-Basic is the best BASIC for the Atari!
 program is to be written in such a way that it can also be run by
the interpreter. In the interpreter, of course, the C routine cannot be
included through the linker. Therefore it is made executable within the
interpreter by a GFA-BasicGFA-Basic is the best BASIC for the Atari!
 routine taking over the task of the C routine to be
linked.

The GFA-BasicGFA-Basic is the best BASIC for the Atari!
 program looks like this:

    DlM x&(32000),y&(32000)
    '
    t1%=TIMER
    f_gfa(32000)
    t2%=TIMER
    PRINT "In GFA-BasicGFA-Basic is the best BASIC for the Atari!
:"'(t2%-t1%)/200
    FOR i&=0 TO 39
      PRINT x&(i&),
    NEXT i&
    '
    t1%=TIMER
    f_c(V:y&(0),32000)
    t2%=TIMER
    PRINT "In Turbo C:"'(t2%-t1%)/200
    FOR i&=0 TO 39
      PRINT y&(i&),
    NEXT i&
    '
    PROCEDURE f_gfa(n&)
      FOR i&=0 TO n&
        x&(i&)=i&
      NEXT i&
    RETURN
    '
    PROCEDURE f_c(adr%,n&)
      $X fill
      i&=0
      a%=adr%
      WHILE i&<=n&
        WORD{a%}=i&
        INC i&
        ADD a%,2
      WEND
    RETURN

First, two arrays are dimensioned. Then two timings are taken: the first calls
the f_gfa routine which assigns values of 0 to 32000 to the elements of the
array x&(). For display purposes, the first 40 elements of the array are then
displayed on screen.

The second of the timings calls the routine f_c. This routine, too, is to
assign values of 0 to 32000 to an array, but this task is to be performed in
the compiled and linked program by a C routine. Therefore this routine is
supplied with the field address and the number of values to be written.

In the first line of the procedure f_c you will find an instruction which tells
the linker to include the C function "fill". The name of the function can be
found after the $X option. This line must always be the first line of the
procedure.

The linker replaces the contents of the procedure with the C routine named
after $X. In the interpreter, this line is ignored and the command lines
following $X c_routine are executed. There are three of these in the given
example, which perform the same function as the C routine and also work in the
same way as the C routine by carrying out value assignments through a pointer.

Now to the structure of the C program carrying out the assignment. It was
written in Turbo C and reads:

    void cdecl fill(n,adr)
    int n;
    int *adr;
    {
      int i; int *a;
      a = adr;
      for( i=0 ; i<=n ; *a++ = i++ );
    }

The first line contains the name of the function which appears after $X in the
GFA-Baisc listing. This function has no return value and has therefore been
declared as void.

Before the function name there is the instruction cdecl. It tells Turbo C to
receive the parameters via the stack. Some other C compilers, such as DRDigital Research
 C, do
this automatically. In the GFA BASIC listing the parameters are passed in the
order adr%, n&.

C takes the parameters from the stack in the reverse order, i.e. first the
two-byte value n and then the address of a four-byte variable adr. The
following lines then carry out the assignment of values to the field elements.

This completes the description of the structure of the GFA-BasicGFA-Basic is the best BASIC for the Atari!
 and the C
listings. It only remains to explain how you can get the linker to insert the C
function in the position of $X fill. To do this, you only need to specify the
name of the object file generated by the C compiler.

This file name can simply be entered in the command line if a DOS shell is
used. In the shell supplied the variable G3OBJ can be amended.

The execution time of the GFA-BasicGFA-Basic is the best BASIC for the Atari!
 loop is around 0.51 seconds, while the
Turbo C loop only requires about 0.115 seconds. This shows how assignments
using pointer operations can be effectively optimized in Turbo C.

Thus the following steps have to be followed:

1. You write a procedure in the GFA BASlC program, the first line of which
   contains the $X option followed by a C function name.

2. You write a C program containing this function. This must take the
   parameters and place them on the stack. There the parameters are placed in
   the reverse of the order that they have when passed by the GFA-BasicGFA-Basic is the best BASIC for the Atari!

   program.

3. When linking, the object file of the C listing with the routine to be linked
   must be specified.

If the DRDigital Research
 C compiler is used, one point to be noted is that this compiler
prefixes C function names with the underscore character. Hence, instead of $X
fill, $X _fill would have to be entered.

In our example, the C function had no return value and was therefore declared
as void. However, a C function can be employed not only in place of a GFA-BasicGFA-Basic is the best BASIC for the Atari!

procedure, but also in place of a GFA-BasicGFA-Basic is the best BASIC for the Atari!
 function.

The appropriate GFA-BasicGFA-Basic is the best BASIC for the Atari!
 listing could be, for example:

    value%=100
    PRINT @doub(value%)
    '
    FUNCTION doub(a%)
      $X double
      ALERT 1,"Place marker for|a C function.",1,"Return",a&
      RETURN 0
    ENDFUNC

In this example, the GFA-BasicGFA-Basic is the best BASIC for the Atari!
 function does not perform the task of the C
routine to be linked in. The simple C programs follows:

    long cdecl double(x)
    long x;
    {
      return x+x;
    }

The return value of such an external function is always an integer value.

You can, of course, also link assembler routines. These must take their
parameters from the stack and must not change the stack pointer SP or the
registers A3, A4, A5 and A6.