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-FileC:addr([x,y,...])
addr: avar (at least 32-bit, ideally integer-type: adr%)
x, y: iexp
The function C: calls a C or assembler subroutine, located at the address addr.
The parameters in brackets (x, y...) will be passed to the routine. The
parameter passing is via the stack, as in C. The parameters can be sent as
32-bit longwords with the prefix 'L:', or 16-bit words with the prefix 'W:'.
If there is no prefix, a word value will be sent. When the function is called,
first the return address and then the parameters will be found on the stack.
So, for example:
VOID C:adr%(L:x,W:y,z) leads to the following situation on the stack:
(sp) --> Return address (4 bytes)
4(sp) --> x (4 bytes)
8(sp) --> y (2 bytes)
10(sp) --> z (2 bytes)
The value returned by the function is the contents of register d0 on return
from the subroutine (for which RTS must be used).
Example:
The assembler program used here fills an area of memory (e.g. an array)
starting from a certain address with the numbers (longwords) from 0 to n.
206F0004 move.l 4(sp),a0 ; Start address
202F0008 move.l 8(sp),d0 ; Number of values
7200 moveq.l #0,d1 ; Counter
6004 bra.s ct_2 ; Loop re-entry point
20C1 ct_1: move.l d1,(a0)+ ; Loop, value write
5281 addq.l #1,d1 ; Increment counter
B081 ct_2: cmp.l d1,d0 ; finished?
64F8 bcc.s ct_1 ; no, around again ->
4E75 rts ; Return to GFA BASIC
The program is:
FOR i%=1 TO 11
READ a%
asm$=asm$+MKI$(a%)
NEXT i%
DATA $206F,$0004,$202F,$0008,$7200,$6004
DATA $20C1,$5281,$B081,$64F8,$4E75
'
DIM x%(10000)
asm%=V:asm$
~C:asm%(L:V:x%(0),L:10000)
PRINT "E.g. x%(12) = ";x%(12)
--> The array x%() is filled with the numbers from 0 to 10000, corresponding
to:
FOR i%=1 TO n%
x%(i%)=i%
NEXT i%
To insert an assembler program in a GFA BASIC 3 program, the INLINE command can
also be used. First a file is created containing the assembler code above by
using (after the above read-data loop):
BSAVE "COUNT.INL",V:asm$,22
Then type in the following program:
INLINE asm%,22
DIM x%(10000)
~C:asm%(L:V:x%(0),L:10000)
Then, while still in the Editor with the cursor on the line containing the
INLINE instruction, press the Help key. From the resulting menu choose 'Load',
and from the File select box select the file COUNT.INL. It will be loaded into
and area specially allocated within the program, and will be saved with the
program when it is Saved in the normal way. See INLINE, Chapter 2, section
Memory Management.
Memo: For compiler options see section 'Register Saving'.
The 'C' routine must be written using the 'cdecl' parameter passing
method. Registers a3 to a7 must remain unchanged.
Internally L:b| or L:b! is handled like so:
moveq #0,d0 ;clr d0
move.b -32768(a5),d0 ;insert the variable
move.l d0,-(sp) ;as long
Internally L:w& is handled like so:
movea.w -32768(a5),a2 ;sign extended
pea (a2) ;as long
Internally L:f# is handled like so:
lea -32768,a0
bsr VFFTOI ;float to integer (->d0)
move.l d0,-(sp) ;as long
Undocumented feature: Also allows semi-colons as parameter separators.
~C:asm%(W:10;L:65000)
If you do stat&=C:asm%() and it returns a word, gfa will throw error #4.
I'm not sure why GFA cares about the upper word, it should be dropped.
Compiled results seem to be ok. Best solution is to return a long and
make sure the upper word is cleared.