Stack Pointer A7

All 680x0 related coding posts in this section please.

Moderators: exxos, simonsunnyboy, Mug UK, Zorro 2, Moderator Team

joefish
Atari freak
Atari freak
Posts: 66
Joined: Thu Dec 05, 2013 4:15 pm

Stack Pointer A7

Postby joefish » Tue Apr 12, 2016 3:10 pm

I know that in 68000 assembly the stack pointer and register A7 are the same thing. I've also read that in Supervisor Mode, there's a separate A7 stack pointer.

So does this mean that if I'm in User mode I can modify and abuse the stack pointer, and interrupts will still work as they use the Supervisor stack pointer?

A question about OS calls though - since they work through the Trap #n instruction, do they use Supervisor Mode and the alternate stack pointer?

And to make a call to the OS you put numbers on the stack and call a particular Ttrap. But how does the function you're calling know whether you put your data on the User Stack or the Supervisor Stack?
Last edited by joefish on Tue Nov 01, 2016 5:32 pm, edited 1 time in total.

distantminds
Atari maniac
Atari maniac
Posts: 93
Joined: Thu Sep 29, 2005 5:03 pm

Re: Stack Pointer A7

Postby distantminds » Tue Apr 12, 2016 3:28 pm


joefish
Atari freak
Atari freak
Posts: 66
Joined: Thu Dec 05, 2013 4:15 pm

Re: Stack Pointer A7

Postby joefish » Tue Apr 12, 2016 3:45 pm

Thanks, yes, that's the sort of thing I want to do.

But that first call to TRAP #14 runs from USER mode (and sets things into SUPERVISOR mode), so its parameters had to be pushed onto the USER Stack. But the later call to Trap #1 to return to TOS is done from SUPERVISOR mode, so its parameters were pushed onto the SUPERVISOR stack. How does the operating system know which stack the parameters are on when it's called via a Trap #n instruction? The only thing I can think of is that it peeks into the stack to find the Status Register that was pushed at the time of the Trap and then decide whether to use the USP or the SSP to find its parameters. But is it that clever, or am I missing something?

joefish
Atari freak
Atari freak
Posts: 66
Joined: Thu Dec 05, 2013 4:15 pm

Re: Stack Pointer A7

Postby joefish » Tue Apr 12, 2016 4:01 pm

OK, answering my own question, from the ROM disassembly:
viewtopic.php?f=68&t=27704

Code: Select all

trp14h:     lea       trp14tab(pc),a0           ; a0 -> trap14 jump table
            bra.s     traph
trp13h:     lea       trp13tab(pc),a0           ; a0 -> trap13 jump table
traph:      movea.l   (savptr).l,a1             ; a1 - registers save area
            move.w    (sp)+,d0                  ; pop SR and save it
            move.w    d0,-(a1)                  ; (need in D0 for user-mode test)
            move.l    (sp)+,-(a1)               ; save return addr
            tst.w     (_longframe).w
            beq.s     traph2
            tst.w     (sp)+
traph2:     movem.l   d3-d7/a3-a7,-(a1)         ; save C registers + super stack
            move.l    a1,(savptr).l             ; update save-area pointer

Code: Select all

* make sure we have the right stack, call function:
            btst      #13,d0            ; was in user mode?
            bne.s     b_supr            ; (was in super: use super stack)
            move      usp,sp            ; use user stack

Code: Select all

b_supr:     move.w    (sp)+,d0                  ; get function#
            cmp.w     (a0)+,d0                  ; out of range?
            bge.s     b_exit                    ; (yes, so punt)
            move.w    d0,d1
            lsl.w     #2,d1                     ; turn D0 into longword index
            move.l    (a0,d1.w),d1              ; get pointer to function handler
            movea.l   d1,a0                     ; (quick and dirty test-for-negative)
            bpl.s     b_1                       ; points to code
            movea.l   (a0),a0                   ; indirect through RAM...
b_1:        suba.l    a5,a5                     ; a5 -> zero page
            jsr       (a0)                      ; call BIOS function


Yes, it is that clever. So it's safe to drop into USER mode and abuse the A7 register, then pop back up into USER mode at will, and still call TOS from either (assuming the stack at the time is OK for putting parameters on). I also like the use of an unassigned Trap vector for a quick Supervisor Mode switch.

I do notice though that the Trap handler, if it needs to fetch parameters from the User SP, changes the SSP to the USP value for the duration of the call, so if the call needs the stack it will be using the User Stack space.

What I'm thinking of is prepared tables of data and jumps that I can point A7 at and just do an RTS to kick it off. The next address on the stack is a function to jump to, some parameters for it to pull off, and then it can tail-call the next stacked function with another RTS. The final address is a jump back to my main code.

The big risk of doing something like this is that an interrupt occurs and pushes some junk into your neatly prepared table, corrupting it for the next time around. But if you do this in User Mode then the only thing that can interrupt it is a Supervisor Mode event which will have its own Stack Pointer.

User avatar
Foxie
Atariator
Atariator
Posts: 24
Joined: Wed Feb 03, 2016 7:12 pm

Re: Stack Pointer A7

Postby Foxie » Tue Apr 12, 2016 5:48 pm

I'm not sure if it's relevant, but if you're in supervisor mode you can definitely abuse the user stack pointer for your own purposes. I'm using it as an extra general-purpose register in one of my programs with no ill effect. You probably want to save the old value of usp and restore it at program exit though.

User avatar
shoggoth
Nature
Nature
Posts: 854
Joined: Tue Aug 01, 2006 9:21 am
Location: Halmstad, Sweden
Contact:

Re: Stack Pointer A7

Postby shoggoth » Wed Apr 13, 2016 7:23 am

The user stack is per definition "abused"; things are pushed on it, it's changed between tasks (even in single-TOS; accessories, remember?).

In your trap handler, you'll have to check the Status Register in the stack frame. It will reveal the CPU state prior to the exception. Based on that, you decide where to fetch your parameters.

Example (this is for the 68030; you'll have to change it a bit for the 68000):

Code: Select all

_trap_handler:   move.l   sp,a0
         move.w   (a0)+,d0      /* sr */
         addq.l   #6,a0      /* +ret+formatcode (CHANGE to #4 for 68000 iirc) */
         btst   #0xd,d0
         jbne      1$
         move.l   usp,a0   

1$:         move.w   (a0)+,d0      // Fetch a 16-bit parameter.
         move.l   (a0)+,d1      // Fetch a 32-bit parameter.


(I'm using GAS, syntax will obviously be different on a real assembler).
Ain't no space like PeP-space.

User avatar
arcx
Retro freak
Retro freak
Posts: 16
Joined: Tue Jan 19, 2016 12:13 am

Re: Stack Pointer A7

Postby arcx » Sat Apr 16, 2016 10:44 am

I´m not sure I´m doing it correctly. By far the supervisor mode is in more creative dispel. Note the Supervisor Stack will align well without having used the User Stack. I will send a link to how I solve it , shortly.

User avatar
arcx
Retro freak
Retro freak
Posts: 16
Joined: Tue Jan 19, 2016 12:13 am

Re: Stack Pointer A7

Postby arcx » Sat Apr 16, 2016 11:10 am

[img][size=150]

Anyone got one of them to sell?
You do not have the required permissions to view the files attached to this post.
Last edited by arcx on Sat Apr 16, 2016 11:11 am, edited 1 time in total.

User avatar
arcx
Retro freak
Retro freak
Posts: 16
Joined: Tue Jan 19, 2016 12:13 am

Re: Stack Pointer A7

Postby arcx » Sat Apr 16, 2016 11:11 am

:roll:
arcx wrote:
Anyone got one of them to sell?


Social Media

     

Return to “680x0”

Who is online

Users browsing this forum: No registered users and 1 guest