[comp.sys.amiga] asdf

451061%UOTTAWA.BITNET@cornellc.cit.cornell.edu (Valentin Pepelea) (06/14/89)

Date:         Sun, 11 Jun 89 19:34:03 EDT
From:         Valentin Pepelea <451061@UOTTAWA>
Subject:      Re: Use of SuperState() call
To:           comp-sys-amiga-tech@ucbvax.berkeley.edu
In-Reply-To:  Your message of 6 Jun 89 23:36:55 GMT
========================================================================
Mark Huth <mph@behemoth.phx.mcd.mot.com> writes in
Message-ID: <11022@behemoth.phx.mcd.mot.com>

> Thanks to Dave and Valentin for replies.  Specifically, the UserState call
> does not work.  It dummies up a stack frame by using the same code that
> SuperState uses.  However, SuperState, in the instance in question, would
> return with an RTE, UserState returns by poping the SR and then doing an
> RTS - leaving the dummied format/vector word on the stack for the next rts
> to stumble over.

Nice work, but now that you have identified the problem, why don't you fix it?
Heh, I'm gonna do it for you. Here is the SuperState() source code:

_UserState:                             ; void UserState(systack)(d0)

           move.l     a5,a0             ; Save this register
           lea        0$(pc),a5         ; Where to go in supervisor mode
           CALLSYS    Supervisor        ; Enter supervisor mode (just in case)
0$
           move.l     a0,a5             ; Restore a5
           move.w     (sp)+,d1          ; Get status register from stack
           move.l     sp,usp            ; Copy supervisor sp to user sp
           bclr       #$0D,d1           ; Clear supervisor bit
           move.l     d1,sr             ; Make it the current status register
           rts

When the execution is about to proceed to local label 0$, the current stack
contains the following:

!                !               !                !
! old status reg !               ! old status reg !
!----------------!               !----------------!
! return address !               ! return address !
!----------------!               !----------------!
! return address !               !   frame type   !
!----------------!               !----------------!
                                 ! return address !
      68000                      !----------------!

                                       68010+


The problem is that the call to Supervisor() places a (dummy) stack frame on
the supervisor stack, and this stack frame is slightly different for the
68010+ processors. They also place the frame type identifier on the stack.
So all we have to do is to ckech what processor we have before performing
an rts. Simply replace the rts above by:

           btst       #0,$0129(a6)      ; Running on a 68000?
           beq        1$                ; Branch if yes
           rtd        #2                ; Discard frame type and return
1$
           rts

I did not test this, but it certainly should work.

> Nice Job. 8-)   Actually, both routines are needlessly complex.  I stepped
> through them with the ROM-wack this weekend.

I disagree with that. There really is no simpler method to do this. Note that
there still is a bug in these calls; you can not asdfsadf them.

Hey, Commodore, now that I fixed UserState(), what do I get in return?

Valentin
_________________________________________________________________________
"An  operating  system  without         Name:   Valentin Pepelea
 virtual memory is an operating         Phonet: (613) 231-7476 (New!)
 system without virtue."                Bitnet: 451061@Uottawa.bitnet
                                        Usenet: Use cunyvm.cuny.edu gate
         - Ancient Inca Proverb         Planet: 451061@acadvm1.UOttawa.CA