[comp.sys.amiga.tech] New RKM:AutoDocs & Includes MAJOR problem!

baer@percival.UUCP (Ken Baer) (03/09/89)

I bought the new RKM:Autodocs & Includes the other day with great delight.
The manual is a vast improvement over its predescesors.  I was particularly
pleased with the fact that the parameter types were actually listed with
the function descriptions.  HOWEVER, to my dismay, I discovered that the
type sizes are WRONG!  Those of us who use Manx C, know that when you 
pass an integer to an Amiga system function (like Draw()), you have to
cast it to LONG (or it must me LONG in the first place).  But, in the new
RKM, these variables are listed as SHORT!!  Not as LONG!  I guarentee
that if you call Draw(rp, (SHORT)x, (SHORT)y)  you'll either go somewhere
wierd, or crash horribly.  At least this seems to be consistent through
the manual, so you can do a mental global search and replace on the SHORTS
and turn them to LONGS.  My heart goes out to all new Amiga developers who
try to use these functions.  Most of us know what a pain it is when you
find out the manual you trusted is wrong.

Hey CATS folx.  Other than this problem, I think the manual is EXCELLENT.
I can't wait for the new Libraries and Devices to come out!

-- 
	-Ken Baer.  					 
   //   Hash Enterprises: When the Going gets Wierd, the Wierd go Professional
 \X/    USENET - baer@percival.UUCP,  PLINK - KEN BAER,
        BIX - kbaer,  "while (AINTGOTNOSATISFACTION) { do stuff }" - RJ Mical

daveh@cbmvax.UUCP (Dave Haynie) (03/10/89)

in article <1467@percival.UUCP>, baer@percival.UUCP (Ken Baer) says:
> Keywords: RKM, parameter type, Manx, WARNING Will Robinson!

> HOWEVER, to my dismay, I discovered that the type sizes are WRONG!  Those 
> of us who use Manx C, know that when you pass an integer to an Amiga system 
> function (like Draw()), you have to cast it to LONG (or it must be LONG in 
> the first place).  But, in the new RKM, these variables are listed as 
> SHORT!!  Not as LONG!  I guarentee that if you call Draw(rp, (SHORT)x, 
> (SHORT)y)  you'll either go somewhere wierd, or crash horribly.  

Here we have another case of "something's wrong, it must be Commodore who
screwed up!".  Possibly not.  I would expect the RKM/Autodocs to reflect
the parameter size that the routine is actually expecting.  Of course, as
we all know, those routines pass parameters in registers, and regardless 
of how the underlying routine uses it, the register contents at the point
of function call is 32 bits wide.  I suspect that the point of confusion 
here is in the Manx bindings to the ROM routines.  Each high level language
has to work out just how it's going to call a function.  C has to provide
bindings for each function which supply C visable function names and turn
C style stack parameters into the registers a particular routine requires.
Obviously, stack parameters are very dependent on size, so your stub code
and function invocation must match exactly.  It's just as likely, if not
moreso, that Manx built their stubs incorrectly.  They'll still work right
if you're following the Manx conventions, but if they've defined their
conventions to be different than the Commodore-Amiga conventions, you can't
rightly call Commodore "wrong" for this.

> My heart goes out to all new Amiga developers who try to use these 
> functions.  Most of us know what a pain it is when you find out the manual 
> you trusted is wrong.

When Manx adds function prototyping, these kind of problems should go away,
regardless of who's conventions the stub code follows.

> 	-Ken Baer.  					 
-- 
Dave Haynie  "The 32 Bit Guy"     Commodore-Amiga  "The Crew That Never Rests"
   {uunet|pyramid|rutgers}!cbmvax!daveh      PLINK: D-DAVE H     BIX: hazy
              Amiga -- It's not just a job, it's an obsession

bryce@cbmvax.UUCP (Bryce Nesbitt) (03/10/89)

In article <1467@percival.UUCP> baer@percival.UUCP (Ken Baer) writes:
|
|HOWEVER, to my dismay, I discovered that the
|type sizes are WRONG!

No, the manual is correct.  The confusion lies with your compiler.


|Those of us who use Manx C, know that when you 
|pass an integer to an Amiga system function (like Draw()), you have to
|cast it to LONG (or it must me LONG in the first place).  But, in the new
|RKM, these variables are listed as SHORT!!  Not as LONG!  I guarentee (sic)
|that if you call Draw(rp, (SHORT)x, (SHORT)y)  you'll either go somewhere
|wierd (sic), or crash horribly.

The ROM INTERFACE will accept a SHORT, as documented:

	Draw(rp,  x,     y)
	     a0   d0:16  d1:16
	SHORT x,y;

The d0:16 and d1:16 indicate that 16 bit values are allowed in the registers.
"SHORT" is the proper type.  However the Manx "C to ROM stubs" insist
on a long.

We could SAY that the function needs a long, but that would deny compilers
the opportunity to take advantage of short arithmetic.  Your compiler
documentation should have made this point clear.

-- 
|\_/|  . ACK!, NAK!, EOT!, SOH!
{O o} .     Bryce Nesbitt, Commodore-Amiga, Inc.
 (")        BIX: bnesbitt
  U	    USENET: cbmvax!bryce@uunet.uu.NET -or- rutgers!cbmvax!bryce
Lawyers: America's untapped export market.

papa@pollux.usc.edu (Marco Papa) (03/10/89)

In article <6195@cbmvax.UUCP| daveh@cbmvax.UUCP (Dave Haynie) writes:
|in article <1467@percival.UUCP|, baer@percival.UUCP (Ken Baer) says:
|| Keywords: RKM, parameter type, Manx, WARNING Will Robinson!
|
|| HOWEVER, to my dismay, I discovered that the type sizes are WRONG!  Those 
|| of us who use Manx C, know that when you pass an integer to an Amiga system 
|| function (like Draw()), you have to cast it to LONG (or it must be LONG in 
|| the first place).  But, in the new RKM, these variables are listed as 
|| SHORT!!  Not as LONG!  I guarentee that if you call Draw(rp, (SHORT)x, 
|| (SHORT)y)  you'll either go somewhere wierd, or crash horribly.  
|
|Here we have another case of "something's wrong, it must be Commodore who
|screwed up!".  Possibly not.  I would expect the RKM/Autodocs to reflect
|the parameter size that the routine is actually expecting.  Of course, as
|we all know, those routines pass parameters in registers, and regardless 
|of how the underlying routine uses it, the register contents at the point
|of function call is 32 bits wide.  I suspect that the point of confusion 
|here is in the Manx bindings to the ROM routines.  Each high level language
|has to work out just how it's going to call a function.  C has to provide
|bindings for each function which supply C visable function names and turn
|C style stack parameters into the registers a particular routine requires.

Actually things are not as bad as they look, simply because every 
implementation of the 'C' langage has to respect the following rule,
excerpted from page 186 of K&R:

"Any actual argument of type float are converted to double before the call;
any of type char or short are converted to int;"
                    ^^^^^                  ^^^

I myself have been using the Draw(rp, x, y) function with x and y declared
either as SHORT or as LONG with no apparent problem [my programs were compiled
with +L so that SHORT and LONG have different size].

-- Marco Papa 'Doc'





-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
uucp:...!pollux!papa       BIX:papa       ARPAnet:pollux!papa@oberon.usc.edu
 "There's Alpha, Beta, Gamma and Diga!" -- Leo Schwab [quoting Rick Unland]
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

elg@killer.Dallas.TX.US (Eric Green) (03/11/89)

in article <1467@percival.UUCP>, baer@percival.UUCP (Ken Baer) says:
> pleased with the fact that the parameter types were actually listed with
> the function descriptions.  HOWEVER, to my dismay, I discovered that the
> type sizes are WRONG!  Those of us who use Manx C, know that when you 
> pass an integer to an Amiga system function (like Draw()), you have to
> cast it to LONG (or it must me LONG in the first place).  But, in the new
> RKM, these variables are listed as SHORT!!  Not as LONG!  I guarentee

Note that this is a problem with Manx's "wrapper" functions, not with
the Autodocs etc. The Rom Kernel was designed to be accessed via
assembler. When it says a parameter is "SHORT", what it is really
saying is, "OK, load the parameter using an ordinary 16-bit MOV into
register <n>".  Manx calls the Rom Kernel via "stub code" written in
assembly, which translates from Manx's "on-the-stack" form of
parameter passing to Exec's "In-the-registers" form of parameter
passing. Manx does it wrong in a number of places, depending on what
version of the compiler you have.

--
|    // Eric Lee Green              P.O. Box 92191, Lafayette, LA 70509     |
|   //  ..!{ames,decwrl,mit-eddie,osu-cis}!killer!elg     (318)989-9849     |
| \X/   

jac@ssibbs.UUCP (James Crotinger) (03/12/89)

In article <15751@oberon.USC.EDU>, papa@pollux.usc.edu (Marco Papa) writes:
> 
> "Any actual argument of type float are converted to double before the call;
> any of type char or short are converted to int;"
>                     ^^^^^                  ^^^

   If a function is prototyped, this is no longer necessarily the case. 
These required conversions used to be a major source of inefficiency in
trying to do numerical work with C since you really don't need double
precision for most things. ANSI addressed this issue by stating that if
a function is prototyped then the extension does not have to take place.

   Speaking of numerical work, when are we likely to see single precision
IEEE libraries, and when we do finally get them, will the compilers support
using both float and double in the same program? Many numerical problems
only require double precision in a few critical areas to eliminate accuracy
problems, and it is a waste to use double precision everywhere else. 
> 
> -- Marco Papa 'Doc'
> 
   jim

-- 
                                        
                               Jim Crotinger
                               crotinger%mit.mfenet@nmfecc.arpa

ecphssrw@io.csun.edu (Stephen Walton) (03/15/89)

A summary so far:  Ken Baer (baer@percival.UUCP) objected that the new RKM
is wrong when it says that arguments to some routines are shorts.  Bryce
Nesbitt (bryce@cbmvax) points out that the RKM is correct inasmuch as such
routines look at only the lower most 16 bits of the register with their
arguments.
     Dave Haynie (daveh@cbmvax) speculates that Manx may have its
C->Assembler glue routines wrong.  This may be true: in a call to
Draw(rastport, x, y) where x and y are shorts, Manx pushes shorts onto
the stack but pulls off longs for the D0 and D1 contents when compiled
with 16-bit ints.  The code stub
{
    long rp;		/* dummy */
    short x, y;
    Draw(rp, x, y);
}
generates for the Draw() the code:
	move.w -8(a5),-(a7)
	move.w -6(a5),-(a7)
	move.l -4(a5),-(a7)
	jsr    _Draw

where _Draw does:
	movea.l 4(a7),a1
	movem.l 8(a7),d0-d1

and then jumps to the Draw entry point.  Does Lattice 4.n/5.n do this
"correctly" if we are agreed that shorts are, in fact, correct?

In article <15751@oberon.USC.EDU>, papa@pollux (Marco Papa) writes:
>
>"Any actual argument of type float are converted to double before the call;
>any of type char or short are converted to int;"
>                    ^^^^^                  ^^^
>I myself have been using the Draw(rp, x, y) function with x and y declared
>either as SHORT or as LONG with no apparent problem [my programs were compiled
>with +L so that SHORT and LONG have different size].

Yes, but int and LONG have the same size, so this code will work fine
with the (faulty) Manx glue routines.  And herein is the real problem:
nearly all Amiga code out of CBM so far was written with a 32-bit length
for ints, so SHORTs were promoted to ints before the library code was
executed anyway.  Should we now take it to be OK for routines such as
Draw() for which the RKM specifies SHORT arguments to actually be called
with 16-bit arguments in an environment where sizeof(int)=16 bits?
--
Stephen Walton, Dept. of Physics & Astronomy, Cal State Univ. Northridge
RCKG01M@CALSTATE.BITNET       ecphssrw@afws.csun.edu
swalton@solar.stanford.edu    ...!csun!afws.csun.edu!ecphssrw

cks@ziebmef.uucp (Chris Siebenmann) (03/19/89)

 There's two orthagonal issues involved; how the libraries take their
arguments, and how your compiler's stub functions (that call into the
libraries) take theirs. For better or worse, the job of the RKM is to
document how the libraries take their arguments, and in this context
they are completely correct. Draw() only does look at the low 16 bits
of some of its arguments. 

 Now we come to Lattice. In the early days, Lattice had 32-bit-wide
ints, so all arguments to functions were 32 bits wide, including
arguments to RKM stub functions, and people wrote code to this
assumption. 

 Now along comes Manx, with either 16 or 32 bit ints. They could have
chosen to define a new interface to the library functions, where
shorts actually were passed as shorts in 16-bit int mode (and thus
match the RKM descriptions), or maintain compatability with Lattice and
make all parameters to libraries 32 bits wide. For better or for worse,
they chose the latter, and lots of code has now been written that
uses that fact.

 As Dave Haynie says, all these problems will got away when people move
to function prototypes.

-- 
	"Though you may disappear, you're not forgotten here
	 And I will say to you, I will do what I can do"
Chris Siebenmann		uunet!{utgpu!moore,attcan!telly}!ziebmef!cks
cks@ziebmef.UUCP	     or	.....!utgpu!{,ontmoh!,ncrcan!brambo!}cks