[comp.sys.amiga.tech] Assembly question from turnip

lphillips@lpami.wimsey.bc.ca (Larry Phillips) (10/27/90)

In <15433@cbmvax.commodore.com>, valentin@cbmvax.commodore.com (Valentin Pepelea) writes:
>In article <2728cc8d-a00comp.sys.amiga.tech@tronsbox.xei.com>
>dfrancis@tronsbox.xei.com (Dennis Francis Heffernan) writes:
>>
>>	Well, I've hit a good one.  I've finally gotten around to trying to l
>>learn assembly on this beast, and my first program crashes.
>>
>>getvarmem     move #4,a6                    ;get memory for variables
>>              move.b #60,D0
>>              move.l #0,D1
>>              jsr _LVOAllocMem(A6)
>>              bne 1$
>>              jmp giveup                    ;didn't get 60 bytes?  SHEESH!
>>1$            move.l D0,vars                ;stash the address for variables
>
>The first problem is with the first instruction. What is the data width of
>that instruction? What data width does your assembler default to? Replace
>that instruction with "move.l #4,a6".

Wooooooops! That should be 'move.l 4,a6', and not the immediate operation.

-larry

--
It is not possible to both understand and appreciate Intel CPUs.
    -D.Wolfskill
+-----------------------------------------------------------------------+ 
|   //   Larry Phillips                                                 |
| \X/    lphillips@lpami.wimsey.bc.ca -or- uunet!van-bc!lpami!lphillips |
|        COMPUSERVE: 76703,4322  -or-  76703.4322@compuserve.com        |
+-----------------------------------------------------------------------+

dfrancis@tronsbox.xei.com (Dennis Francis Heffernan) (10/27/90)

	Well, I've hit a good one.  I've finally gotten around to trying to l
learn assembly on this beast, and my first program crashes.  Not surprising.
WHERE it crashes is- the first call to AllocMem.
	Consider the following:

getvarmem     move #4,a6                    ;get memory for variables
              move.b #60,D0
              move.l #0,D1
              jsr _LVOAllocMem(A6)
              bne 1$
              jmp giveup                    ;didn't get 60 bytes?  SHEESH!
1$            move.l D0,vars                ;stash the address for variables

              move.l a4,tailadd(vars)       ;put tail in vars
              move.l d4,taillen(vars)

	'vars' has been EQUR'ed to a5.  The program never gets past the call to
AllocMem.  I've been using SRT, and it shows all the registers clear except
a6 (which is 4, like it should be), d0 (set to 60 up there) and a4 and d4 
(which hold the address and length of the command tail.  I deliberately cleared
all the other registers before this routine.)  SRT reports the PC is at 4,
which doesn't make any sense to me.  I did xref the offset for AllocMem (and
everything else- I'm using CAPE and it has an autoxref feature.  I even 
disassembled the executable to see if it had the right offset in there and it
does.)
	I must be missing something stupid.  If you know what it is, send 
email.  Or post it, if it's bad enough to warrant (more) public humiliation.

	PS- know any good PD debugging tools? ;-)

dfrancis@tronsbox.xei.com   ...uunet!tronsbox!dfrancis     GEnie: D.HEFFERNAN1
------------------------------------------------------------------------------
"I don't understand why you make such a big deal out of everything...haven't
you learned; if it's not happenning to me it's not important?" -Murphy Brown

d88ricwe@odalix.ida.liu.se (Rickard Westman) (10/27/90)

dfrancis@tronsbox.xei.com (Dennis Francis Heffernan) writes:

>	Well, I've hit a good one.  I've finally gotten around to trying to l
>learn assembly on this beast, and my first program crashes.  Not surprising.
>WHERE it crashes is- the first call to AllocMem.
>	Consider the following:

>getvarmem     move #4,a6                    ;get memory for variables

Try            move.l 4,a6

>              move.b #60,D0

Try            move.l #60,D0

>              move.l #0,D1
>              jsr _LVOAllocMem(A6)

All system calls expect longwords as arguments(*).  If you do "move.b #60,D0"
only the lower 8 bits of D0 are set - the rest of them could be set to 
anything.  If you don't use a size designator at all (as in the first line)
most assemblers will default to word size, leaving you with the same type of 
problem.  So - *always* use ".l" when dealing with system call arguments.

This is not why your program crashed, however.  To call AllocMem() you need
the exec.library base pointer in a6.  This pointer is stored at the fixed 
address 4.  But remember that it is a *pointer* to the library base, not the
library base itself.  You need one more level of indirection, which is what you
get if you use "move.l 4,a6" instead of "move.l #4,a6".

/RiW

-----

(*)  This may not be entirely true.  I think there is one or two functions
     that use words, but they are clearly an exception.

gm@ionic.UUCP (Greg Miller) (10/28/90)

>In article <15433@cbmvax.commodore.com> valentin@cbmvax.commodore.com (Valentin Pepelea) writes:
>In article <2728cc8d-a00comp.sys.amiga.tech@tronsbox.xei.com>
>dfrancis@tronsbox.xei.com (Dennis Francis Heffernan) writes:
>>
>>      Well, I've hit a good one.  I've finally gotten around to trying to l
>>learn assembly on this beast, and my first program crashes.
>>
>>getvarmem     move #4,a6                    ;get memory for variables
>>              move.b #60,D0
>>              move.l #0,D1
>>              jsr _LVOAllocMem(A6)
>>              bne 1$
>>              jmp giveup                    ;didn't get 60 bytes?  SHEESH!
>>1$            move.l D0,vars                ;stash the address for variables
>
>The first problem is with the first instruction. What is the data width of
>that instruction? What data width does your assembler default to? Replace
>that instruction with "move.l #4,a6".

 Wait-a-sec!

 He certainly doesn't want to do that!

 Try:

 move.l 4,a6

 Or for those of us who have this strange preference for descriptive labels:

 move.l _AbsExecBase,a6


>
>The second problem is with the test for the return value. Hey, wait a minute,
>you are not testing for the return value at all! Here is what you should do:
>
>               jsr     _LVOAllocMem(a6)        ; Try to allocate memory
>               tst.l   d0                      ; Is the return value zero?
>               beq     giveup                  ; Branch if so
>               move.l  d0,vars                 ; Stash the address
>
>Valentin
>--
>The Goddess of democracy? "The tyrants    Name:    Valentin Pepelea
>may destroy a statue,  but they cannot    Phone:   (215) 431-9327
>kill a god."                              UseNet:  cbmvax!valentin@uunet.uu.net
>             - Ancient Chinese Proverb    Claimer: I not Commodore spokesman be

--

     +----------------------------------------------------------------+
     | A sign of mismanagement, over-    |  Greg Miller               |
     | complication and overall idiocy:  |  ..ames!sharkey!ionic!gm   |
     |                                   |  gm@ionic.uucp             |
     |                                   |                            |
     |      "Designed By Committee"      |                            |
     +----------------------------------------------------------------+

robin@niksula.hut.fi (Jarto 'Robin' Tarpio) (10/28/90)

In article <15433@cbmvax.commodore.com> valentin@cbmvax.commodore.com (Valentin Pepelea) writes:
   In article <2728cc8d-a00comp.sys.amiga.tech@tronsbox.xei.com>
   dfrancis@tronsbox.xei.com (Dennis Francis Heffernan) writes:
   >
   >	Well, I've hit a good one.  I've finally gotten around to trying to l
   >learn assembly on this beast, and my first program crashes.
   >
   >getvarmem     move #4,a6                    ;get memory for variables
   >              move.b #60,D0
   >              move.l #0,D1
   >              jsr _LVOAllocMem(A6)
   >              bne 1$
   >              jmp giveup                    ;didn't get 60 bytes?  SHEESH!
   >1$            move.l D0,vars                ;stash the address for variables

V:   The first problem is with the first instruction. What is the data width of
V:   that instruction? What data width does your assembler default to? Replace
V:   that instruction with "move.l #4,a6".

	The correct one is:  move.l  4,a6
	Or shorter:          move.l  4.w,a6

	That #4 moves the value 4 into A6. You have to move the address
	which is in 4 to A6.

V:   The second problem is with the test for the return value. Hey, wait a minute,
V:   you are not testing for the return value at all! Here is what you should do:
V:
V:		   jsr	_LVOAllocMem(a6)	; Try to allocate memory
V:		   tst.l	d0			; Is the return value zero?
V:		   beq	giveup			; Branch if so
V:		   move.l	d0,vars			; Stash the address



More comments:

   >getvarmem     move #4,a6                    ;get memory for variables

	move.l  4.w,A6

   >              move.b #60,D0

	moveq.l #60,D0		This one cleans the whole registed. If D0
				contains "something big" before your move.b,
				you only change the lowest byte and D0 will
				contain a big number and you ask for a huge
				amount of memory.

   >              move.l #0,D1

	moveq.l #0,D0		Those "quick" moves produce smaller code
				and are faster.

   >              jsr _LVOAllocMem(A6)

	tst.l D0		Just like Valentin wrote...

   >              bne 1$

	bne.s 1$		Optimization...

   >              jmp giveup                    ;didn't get 60 bytes?  SHEESH!
   >1$            move.l D0,vars                ;stash the address for variables

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*               StarSoft Ky (ECO101)   Helsinki University of Technology    *
* Jarto Tarpio  Member of Amiga Developers' Support Program, Europe (ADSPE) *
*               * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*         //    robin@niksula.hut.fi   robin@otax.tky.hut.fi                *
*        //     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*   \\  //                                                                  *
*    \\//       Snif. @batcomputer.hut.fi is dead ! @joker.hut.fi won.. :-( *
*                                                                           *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

lphillips@lpami.wimsey.bc.ca (Larry Phillips) (10/28/90)

In <272a5374-a00.6comp.sys.amiga.tech-1@tronsbox.xei.com>, dfrancis@tronsbox.xei.com (Dennis Francis Heffernan) writes:
>	OK, I *knew* it had to be something stupid.  In all the sample code
>I looked at, I somehow never noticed that it was a dollar sign in front of
>the four and not a number sign.
>	It hath been expunged.  I had already knocked out the byte references
>in favor of longwords or moveq instructions.
>
>	As for checking the condition codes, I was under the impression that
>any time you moved a zero into a data register, the zero flag was set.  I 
>don't see then how the system calls could NOT set the flag, but I'll take your
>words for it.

There is no guarantee that the last operation to affect the condition codes is
the one you are interested in (the move of the result to D0). In other words,
the result might be moved to D0, then something else moved to or from another
data reg, before control is returned to your program.

>	NEW QUESTION:  When you do an AllocMem(), do you get a pointer to the
>TOP of the allocated area or the BOTTOM?  I'd think it'd be the top, but
>after that first mistake...  (You want a better one?  Try this:

Well, it all depends on what you call the top or the bottom of the allocated
memory. I don't know your background, and if it includes any Intel CPU
programming, it's likely to be different from the more sane processors. :-)

The returned result is the address of the bottom of the allocated memory, or in
other words, the lowest address.

-larry

--
It is not possible to both understand and appreciate Intel CPUs.
    -D.Wolfskill
+-----------------------------------------------------------------------+ 
|   //   Larry Phillips                                                 |
| \X/    lphillips@lpami.wimsey.bc.ca -or- uunet!van-bc!lpami!lphillips |
|        COMPUSERVE: 76703,4322  -or-  76703.4322@compuserve.com        |
+-----------------------------------------------------------------------+

chem194@canterbury (John Davis, programmer at large, chemistry department) (10/28/90)

In article <15433@cbmvax.commodore.com>, valentin@cbmvax.commodore.com (Valentin Pepelea) writes:
> In article <2728cc8d-a00comp.sys.amiga.tech@tronsbox.xei.com>
> dfrancis@tronsbox.xei.com (Dennis Francis Heffernan) writes:
>>
>>	Well, I've hit a good one.  I've finally gotten around to trying to l
>>learn assembly on this beast, and my first program crashes.
>>
>>getvarmem     move #4,a6                    ;get memory for variables
>>              move.b #60,D0
>>              move.l #0,D1
>>              jsr _LVOAllocMem(A6)
> The first problem is with the first instruction. What is the data width of
> that instruction? What data width does your assembler default to? Replace
> that instruction with "move.l #4,a6".
> 
> The second problem is with the test for the return value. Hey, wait a minute,
> you are not testing for the return value at all! Here is what you should do:

It's a lot simpler than that, and I'm amazed no-one picked it up!!! 

               move #4,a6 
should be 
               move 4,a6

the poor guy's moving the literal value 4 to a6, instead of the contents 
of location 4 ( execbase pointer ). No wonder things fall over in a 
large, screaming heap!
  
the comment about size is valid, you should declare the size as .l, though
most assemblers will default to .l if you don't specify one. Also checking
the return values would be a good idea ....
 

-----------------------------------------------------------
| o  John Davis - CHEM194@canterbury.ac.nz               o |
| o  (Depart)mental Programmer,Chemistry Department      o |
| o  University of Canterbury, Christchurch, New Zealand o | 
| o                                                      o |
| o  co-sysop AmigaINFO BBS,1200/2400 baud CCITT,        o |
| o           24 hours a day, ph NZ +3-3371-531          o |


ze, a good asem will 

dfrancis@tronsbox.xei.com (Dennis Francis Heffernan) (10/28/90)

	OK, I *knew* it had to be something stupid.  In all the sample code
I looked at, I somehow never noticed that it was a dollar sign in front of
the four and not a number sign.
	It hath been expunged.  I had already knocked out the byte references
in favor of longwords or moveq instructions.

	As for checking the condition codes, I was under the impression that
any time you moved a zero into a data register, the zero flag was set.  I 
don't see then how the system calls could NOT set the flag, but I'll take your
words for it.

	NEW QUESTION:  When you do an AllocMem(), do you get a pointer to the
TOP of the allocated area or the BOTTOM?  I'd think it'd be the top, but
after that first mistake...  (You want a better one?  Try this:
	jsr _LVOClose
	No problem, right...?  ;-)  Thankfully, I caught this one with Timo
Rossi's debugger/monitor, Mon- and thanks for the mail, Timo!  I had already
found Mon on a local board.  Of course, the sucker still crashes, but in a 
different spot now...)


dfrancis@tronsbox.xei.com   ...uunet!tronsbox!dfrancis     GEnie: D.HEFFERNAN1
"...when Fortran was introduced, it was claimed that Fortran would largely
eliminate coding and debugging!  Of course, that claim proved to be quite false"
- UNIVERSAL ASSEMBLY LANGUAGE, Robert M. Fitz & Larry Crocket 

lphillips@lpami.wimsey.bc.ca (Larry Phillips) (10/29/90)

In <1990Oct29.205140.28826@zorch.SF-Bay.ORG>, xanthian@zorch.SF-Bay.ORG (Kent Paul Dolan) writes:
>lphillips@lpami.wimsey.bc.ca (Larry Phillips) writes:
>> dfrancis@tronsbox.xei.com (Dennis Francis Heffernan) writes:
>[...]
>>>	As for checking the condition codes, I was under the impression that
>>>any time you moved a zero into a data register, the zero flag was set.  I 
>>>don't see then how the system calls could NOT set the flag, but I'll take your
>>>words for it.
>
>>There is no guarantee that the last operation to affect the condition codes is
>>the one you are interested in (the move of the result to D0). In other words,
>>the result might be moved to D0, then something else moved to or from another
>>data reg, before control is returned to your program.
>
>WHAT? How can you do multitasking at  all,  if  whatever's  the  68000's
>version of the program status register's set of condition  flags,  isn't
>restored after a context switch? I guess my ignorance  is  showing,  but
>this sure isn't how the world used to look the last time I worked at the
>assembly  level.  What  did  I  miss?

We are speaking of calling a system routine here, and staying within one task.
There is no context switch at all. The sequence is something like this...


	set up regs, remembering that D0, d1, a0, and a1 are 'scratch'
	call system routine 
	check for return code in d0, if applicable
  act on result

The condition codes at the return from the system routine reflect _something_
the routine did before it returned control to us. The thing is, we know what
the system routine did, at least to the extent that is documented in the
autodocs (or in any library), but we do not have any knowledge of how it did
what it does. Because the condition codes are not guaranteed to reflect the
returned value in D0, we cannot do a test as the first operation after thr
return, and expect it to always show the result. This is in spite of any
observed behaviour on programs that work.

A good example is (if I remember correctly), DoIO. In 1.3, the condition code
was set to reflect the contents of D0 (an observation borne out by a program I
wrote when run on my particular system). The same program broke under 2.0,
because the condition code no longer reflected the return value.  It did not
break because CBM did something wrong, but because I made the mistake of
ass-u-m(e)-ing that the condition code acted in the observed way.  From the
documentation supplied by CBM, it can be argued that not only did they not do
anything wrong, but that they actually _did not change DoIO at all_, from its
documented behaviour.

-larry

--
It is not possible to both understand and appreciate Intel CPUs.
    -D.Wolfskill
+-----------------------------------------------------------------------+ 
|   //   Larry Phillips                                                 |
| \X/    lphillips@lpami.wimsey.bc.ca -or- uunet!van-bc!lpami!lphillips |
|        COMPUSERVE: 76703,4322  -or-  76703.4322@compuserve.com        |
+-----------------------------------------------------------------------+

xanthian@zorch.SF-Bay.ORG (Kent Paul Dolan) (10/30/90)

lphillips@lpami.wimsey.bc.ca (Larry Phillips) writes:
> dfrancis@tronsbox.xei.com (Dennis Francis Heffernan) writes:
[...]
>>	As for checking the condition codes, I was under the impression that
>>any time you moved a zero into a data register, the zero flag was set.  I 
>>don't see then how the system calls could NOT set the flag, but I'll take your
>>words for it.

>There is no guarantee that the last operation to affect the condition codes is
>the one you are interested in (the move of the result to D0). In other words,
>the result might be moved to D0, then something else moved to or from another
>data reg, before control is returned to your program.

WHAT? How can you do multitasking at  all,  if  whatever's  the  68000's
version of the program status register's set of condition  flags,  isn't
restored after a context switch? I guess my ignorance  is  showing,  but
this sure isn't how the world used to look the last time I worked at the
assembly  level.  What  did  I  miss?

Kent, the man from xanth.
<xanthian@Zorch.SF-Bay.ORG> <xanthian@well.sf.ca.us>

peterk@cbmger.UUCP (Peter Kittel GERMANY) (10/30/90)

In article <1990Oct29.205140.28826@zorch.SF-Bay.ORG> xanthian@zorch.SF-Bay.ORG (Kent Paul Dolan) writes:
>lphillips@lpami.wimsey.bc.ca (Larry Phillips) writes:
>
>>There is no guarantee that the last operation to affect the condition codes is
>>the one you are interested in (the move of the result to D0). In other words,
>>the result might be moved to D0, then something else moved to or from another
>>data reg, before control is returned to your program.
>
>WHAT? How can you do multitasking at  all,  if  whatever's  the  68000's
>version of the program status register's set of condition  flags,  isn't
>restored after a context switch?
                  ^^^^^^^
He didn't talk about a context switch but about returning from a
system function called by your program, and this hasn't anything
to do with multitasking and task switching. He explained what can
happen near the very end of such a library routine, shortly before
the finishing RTS. The simple summary is: Do a TSTB or other check
for the flags by your own, but don't rely on the flags being set
just after RTSing.

-- 
Best regards, Dr. Peter Kittel  // E-Mail to  \\  Only my personal opinions... 
Commodore Frankfurt, Germany  \X/ {uunet|pyramid|rutgers}!cbmvax!cbmger!peterk

eeh@public.BTR.COM (Eduardo E. Horvath eeh@btr.com) (10/31/90)

In article <1990Oct29.205140.28826@zorch.SF-Bay.ORG> xanthian@zorch.SF-Bay.ORG (Kent Paul Dolan) writes:
>lphillips@lpami.wimsey.bc.ca (Larry Phillips) writes:
>> dfrancis@tronsbox.xei.com (Dennis Francis Heffernan) writes:
>[...]
>>>	As for checking the condition codes, I was under the impression that
>>>any time you moved a zero into a data register, the zero flag was set.  I 
>>>don't see then how the system calls could NOT set the flag, but I'll take your
>>>words for it.
>
>>There is no guarantee that the last operation to affect the condition codes is
>>the one you are interested in (the move of the result to D0). In other words,
>>the result might be moved to D0, then something else moved to or from another
>>data reg, before control is returned to your program.
>
>WHAT? How can you do multitasking at  all,  if  whatever's  the  68000's
>version of the program status register's set of condition  flags,  isn't
>restored after a context switch? I guess my ignorance  is  showing,  but
>this sure isn't how the world used to look the last time I worked at the
>assembly  level.  What  did  I  miss?
>
>Kent, the man from xanth.
><xanthian@Zorch.SF-Bay.ORG> <xanthian@well.sf.ca.us>

	Multitasking has nothing to do with it.  The problem is that there is no
guarantee that the last executed that affects the condition codes in the library
call consists of loading the return value.  It is quite concievable that there
is other internal maintenance code that has the side-effect of changing the CCR.
It is also possible that someone has SetFunction()'ed that particular routine or
has installed some code to monitor all system calls.  If there is an enveloping
routine installed, it almost certainly does not load the return code as the last
intruction before the function return.  It is always better to be safe than to
visit the Guru.

	If you really don't like adding an additional compare instruction, you
can store the result to memory and branch on the result of that.  Since you will
need to move the return value anyway, it does not create any additional
overhead.


=========================================================================
Eduardo Horvath				eeh@btr.com
					..!{decwrl,mips,fernwood}!btr!eeh
	"Trust me, I know what I'm doing." - Sledge Hammer
=========================================================================

jdege@ (Jeff Dege) (11/01/90)

In article <1990Oct29.205140.28826@zorch.SF-Bay.ORG> xanthian@zorch.SF-Bay.ORG (Kent Paul Dolan) writes:
>lphillips@lpami.wimsey.bc.ca (Larry Phillips) writes:
>
>>There is no guarantee that the last operation to affect the condition codes is
>>the one you are interested in (the move of the result to D0). 
>
>WHAT? How can you do multitasking at  all, ...

Picture the end of an OS call.

     MOVE.L   RESULT,D0
     MOVE.L   SOMETHINGELSE,D1
     RTS
 
------------------------

lphillips@lpami.wimsey.bc.ca (Larry Phillips) (11/02/90)

In <ggk.657327711@tirith.UUCP>, ggk@tirith.UUCP (Gregory Kritsch) writes:
>>>>There is no guarantee that the last operation to affect the condition codes is
>>>>the one you are interested in (the move of the result to D0). In other words,
>>>>the result might be moved to D0, then something else moved to or from another
>>>>data reg, before control is returned to your program.
>>>
>>>WHAT? How can you do multitasking at  all,  if  whatever's  the  68000's
>>>version of the program status register's set of condition  flags,  isn't
>>>restored after a context switch? I guess my ignorance  is  showing,  but
>>>this sure isn't how the world used to look the last time I worked at the
>>>assembly  level.  What  did  I  miss?
>>>
>>	Multitasking has nothing to do with it.  The problem is that there is no
>>guarantee that the last executed that affects the condition codes in the library
>>call consists of loading the return value.  It is quite concievable that there
>>is other internal maintenance code that has the side-effect of changing the CCR.
>>It is also possible that someone has SetFunction()'ed that particular routine or
>>has installed some code to monitor all system calls.  If there is an enveloping
>>routine installed, it almost certainly does not load the return code as the last
>>intruction before the function return.  It is always better to be safe than to
>>visit the Guru.
>
>Define "Mainenance code"?  As far as I know, there is none.  

Maintenance code, in this case, is anything the system routine wants to do to
perform its function.

>Unless I'm mistaken (if I am, someone correct me please), but CCR is
>part of the return value definition of a function.  Therefore, if the
>SetFunction() code didn't appropriately set the CCR, it would be
>considered broken.

You are decidedly mistaken. The CCR is not defined as part of the return
conditions in any of the Amiga's system calls. If a routine is intercepted with
SetFunction(), it is up to the programmer as to whether he wishes to set the
CCR according to the returned value in D0 or not. If he does, no problem.
If he doesn't, it won't matter, since properly written proograms calling the
function will explicitly test for the contents of D0 if applicable.

>From the "Amiga ROM Kernel Reference Manual; Includes and Autodocs; Revised and
Updated" (the blue RKM), page 'Introduction-5':

o Except as noted, system library functions use registers D0, D1, A0, and A1 as
  scratch registers and you must consider their former contents to be lost
  after a system library call.  The contents of all other registers will be
  preserved.  System functions which provide a result will return the result in
  D0.

o System functions that return a result may not necessarily affect the
  processor condition codes.  The caller must test the returned value before
  acting on a condition code.  This is usually done with a TST or MOVE
  instruction.

>I actually think many of the functions do end in something which will
>set the CCR, or they end with a tst.l d0.

Doesn't matter if they do or not. If they do now, under 1.3, they may not under
2.0, or 2.1, or 8.9, at which time, code depending on the CCR will break, with
nobody to blame but the application programmer.

>>	If you really don't like adding an additional compare instruction, you
>>can store the result to memory and branch on the result of that.  Since you will
>>need to move the return value anyway, it does not create any additional
>>overhead.
>
>Useless point: Perhaps I don't want to store a failure code, and
>besides, that store would not be done otherwise, and it does take
>processor time to do the store.

Maybe so, but if you want your programs to work, release after release, you
will follow the rules and test the returned value. It is no different than any
of the other system library interface rules. Basically, that's the way it
works, and that's the way it is guaranteed to work.

-larry

--
It is not possible to both understand and appreciate Intel CPUs.
    -D.Wolfskill
+-----------------------------------------------------------------------+ 
|   //   Larry Phillips                                                 |
| \X/    lphillips@lpami.wimsey.bc.ca -or- uunet!van-bc!lpami!lphillips |
|        COMPUSERVE: 76703,4322  -or-  76703.4322@compuserve.com        |
+-----------------------------------------------------------------------+

ggk@tirith.UUCP (Gregory Kritsch) (10/31/20)

eeh@public.BTR.COM (Eduardo E. Horvath  eeh@btr.com) writes:
>>>There is no guarantee that the last operation to affect the condition codes is
>>>the one you are interested in (the move of the result to D0). In other words,
>>>the result might be moved to D0, then something else moved to or from another
>>>data reg, before control is returned to your program.
>>
>>WHAT? How can you do multitasking at  all,  if  whatever's  the  68000's
>>version of the program status register's set of condition  flags,  isn't
>>restored after a context switch? I guess my ignorance  is  showing,  but
>>this sure isn't how the world used to look the last time I worked at the
>>assembly  level.  What  did  I  miss?

My definition of "context switch" includes ALL the 68xxx registers, for
all the 68xxx processors in the system (ie 68030 + 68882).  This is, to
the best of my knowledge, what Exec does for the 68000 alone.  I've
checked this in Markus Wandel's Exec 1.2 disassembly.  I believe the
other processors are handled appropriately.

>	Multitasking has nothing to do with it.  The problem is that there is no
>guarantee that the last executed that affects the condition codes in the library
>call consists of loading the return value.  It is quite concievable that there
>is other internal maintenance code that has the side-effect of changing the CCR.
>It is also possible that someone has SetFunction()'ed that particular routine or
>has installed some code to monitor all system calls.  If there is an enveloping
>routine installed, it almost certainly does not load the return code as the last
>intruction before the function return.  It is always better to be safe than to
>visit the Guru.

Define "Mainenance code"?  As far as I know, there is none.  

Unless I'm mistaken (if I am, someone correct me please), but CCR is
part of the return value definition of a function.  Therefore, if the
SetFunction() code didn't appropriately set the CCR, it would be
considered broken.

I actually think many of the functions do end in something which will
set the CCR, or they end with a tst.l d0.

>	If you really don't like adding an additional compare instruction, you
>can store the result to memory and branch on the result of that.  Since you will
>need to move the return value anyway, it does not create any additional
>overhead.

Useless point: Perhaps I don't want to store a failure code, and
besides, that store would not be done otherwise, and it does take
processor time to do the store.

>=========================================================================
>Eduardo Horvath				eeh@btr.com
>					..!{decwrl,mips,fernwood}!btr!eeh
>	"Trust me, I know what I'm doing." - Sledge Hammer
>=========================================================================
--
  Gregory Kritsch                          | University of Waterloo
    Fido:  1:221/208.11110  [1:163/109.30] | 1A Computer Engineering
    UUCP:  ggk@tirith.UUCP                 |--------------------------
           ...!watmath!xenitec!tirith!ggk  | Amiga Fanatic