•  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-FileUsing GEMSYS
by Lonny PursellWWW: http://gfabasic.net/

Rev 3  3/12/2018
_______________________

The manual is quite vague on this command and does not even state the parameter
is optional.

There's two ways to use GEMSYS. Here's two examples that hopefully clarify its
use. It's the same function call written both ways. All the examples contain
$F% to force an integer return value, this is very important.

' example #1: with parameter
' GFA fills in the GCONTRL() array itself
FUNCTION graf_mouse(mode&,ptr%)
  $F%     !gemsys never returns a float, yet another speed up
  GINTIN(0)=mode&
  ADDRIN(0)=ptr%
  GEMSYS 78
  RETURN GINTOUT(0)
ENDFUNC

In this first example GFA takes the opcode and uses it as an offset into a
table, where it fetches all the values for GCONTRL() on its own. This reduces
the chance of a typo. This method works for any AES call if the opcode falls in
the range of 10 to 131. The original library is only as up-to-date as the day
it was released, many of the newer AES calls have null entries. This actually
produces a smaller binary. I like to refer to this method as 'short form'.

' example #2: with no parameter
' GCONTRL() values must be supplied
FUNCTION graf_mouse(mode&,ptr%)
  $F%
  GCONTRL(0)=78
  GCONTRL(1)=1
  GCONTRL(2)=1
  GCONTRL(3)=1
  GCONTRL(4)=0
  GINTIN(0)=mode&
  ADDRIN(0)=ptr%
  GEMSYS
  RETURN GINTOUT(0)
ENDFUNC

In the second example the GCONTRL() entries must be passed. You need some good
docs if you are going to code this stuff. It can be rather tedious. I call this
method 'long form'. This method must be used for any opcode over 131 or entries
in the table that are empty.

So how do you know if a given opcode has a correct entry in the GEMSYS table?
For the original library that's easy. All the built-in calls such as APPL_xxx,
WIND_xxx, and so on have valid table entries because GFA itself uses this table
internally.

The updated library will has the following GEMSYS table entries added:

    appl_yield
    appl_search
    appl_control
    appl_getinfo
    menu_popup
    menu_attach
    menu_istart
    menu_settings
    objc_sysvar
    objc_xfind
    graf_multirubber
    wind_draw
    wind_new
    rsrc_rfix
    shel_rdef
    shel_wdef
    shel_help
    form_popup

This brings the GEMSYS table up to N.AES v2 specifications. Bindings can then
be written in short form for these calls. The new range for GEMSYS is 10 to
135.

Exotic bindings for MagiC, XaAES, and Geneva that go beyond opcode 135 will
have to be written in long form. I do not plan to increase the size of the
table any further.

I did a speed test using the same call, short form versus long form and only in
the editor is there a noticeable difference. Compiling the speed test yields
the same result for both methods.

I noticed with N.AES its doesn't seem to care if you forget to set GCONTRL() 2
to 4 when using the long form. This is a side effect of the newer AES
implementations and they seem to handle the input arrays differently than TOS.
I do not recommend omitting these parameters on older TOS versions. I did some
testing and found it will cause them to fail.

GCONTRL(4) however appears to be an exception to the rule. Looking in the TOS
4.04 source code archive you will find that GCONTRL(4) is not really used.
Whoever wrote the AES dispatcher made RSRC_GADDR() a special case, since its
the only call that uses ADDROUT(). Bindings missing GCONTRL(4)=blah will work
regardless. Have a look at file gembind.c in the TOS 4.04 archive.

I don't know if Mr. Ostrowski dis-assembled TOS or someone at Atari fed him
some inside info, but GFA since day one has never set GCONTRL(4) for any of the
built in AES calls.   ;o)

So, what can we conclude from all this? If you need to write a binding, try to
use the short form if GEMSYS supports it as it will reduce your code size
without a speed penalty. If you must use the long form, don't bother setting
GCONTRL(4) and save a few a bytes, Frank would be proud.  :D

_______________________________________________________________________________

After doing even further study in the dis-assembler it's still possible to
squeeze even more bytes and speed out of the long form if you must use it. Say
for example you want to use an XaAES call and thus a binding is required. Since
opcode 137 doesn't have a table entry you must use the long form.

' example #2: long form
FUNCTION appl_options(mode&,p1&,p2&,p3&,p4&,VAR out1&,out2&,out3&,out4&)
  $F%
  GCONTRL(0)=137
  GCONTRL(1)=5
  GCONTRL(2)=5
  GCONTRL(3)=0
  GCONTRL(4)=0
  GINTIN(0)=mode&
  GINTIN(1)=p1&
  GINTIN(2)=p2&
  GINTIN(3)=p3&
  GINTIN(4)=p4&
  GEMSYS
  out1&=GINTOUT(1)
  out2&=GINTOUT(2)
  out3&=GINTOUT(3)
  out4&=GINTOUT(4)
  RETURN GINTOUT(0)
ENDFUNC

' example #3: alternate long form
FUNCTION appl_options(mode&,p1&,p2&,p3&,p4&,VAR out1&,out2&,out3&,out4&)
  $F%
  GCONTRL(1)=5
  GCONTRL(2)=5
  GCONTRL(3)=0
  GCONTRL(4)=0      !remove to save another 8 bytes
  GINTIN(0)=mode&
  GINTIN(1)=p1&
  GINTIN(2)=p2&
  GINTIN(3)=p3&
  GINTIN(4)=p4&
  GEMSYS 137
  out1&=GINTOUT(1)
  out2&=GINTOUT(2)
  out3&=GINTOUT(3)
  out4&=GINTOUT(4)
  RETURN GINTOUT(0)
ENDFUNC

This will shorten your binary by 6 bytes and technically it's faster. The line
GCONTRL(0)=13 produces a library call and some addition instructions whereas
GEMSYS 137 produces just a MOVE.W #137,d0. You can also drop the line
GCONTRL(4)=0 and save a total of 14 bytes, but if you are paranoid about
compatibility you might not want to. ;)