SSP on sega.s

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Post Reply
KanedaFr
Administrateur
Posts: 1139
Joined: Tue Aug 29, 2006 10:56 am
Contact:

SSP on sega.s

Post by KanedaFr » Tue Jan 11, 2011 9:10 am

Hi,
I'm trying to fully understand what is exactly the Initial Stack Pointer at 0x0.
I'm actually using 0x0, while a lot of games use 0x00FFF??? so I would like to know why ;)

From what I understood, after some (web) reading, ISP is in fact the ISSP: initial Supervisor Stack Pointer.
It is so used only on supervisor mode.
Since we are mainly in User mode, I first didn't understand it's useage.

Then, I read the 68000 switches to Supervisor mode when an exception occurs.
It uses the ISSP as the address where to store the current PC and User Stack Pointer. Then restore them back after exception processing.

So, ISSP must be an address where the 68000 must be able to save 2 long whithout overwriting some vars, right ?
and so, I'm making a big mistake using 0x0...
but, in this case, why my games are running with this 0x0 value ? Vint must fail, no ?

thanks for any light on this subject ;)

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: SSP on sega.s

Post by Stef » Tue Jan 11, 2011 9:37 am

KanedaFr wrote:Hi,
I'm trying to fully understand what is exactly the Initial Stack Pointer at 0x0.
I'm actually using 0x0, while a lot of games use 0x00FFF??? so I would like to know why ;)

From what I understood, after some (web) reading, ISP is in fact the ISSP: initial Supervisor Stack Pointer.
It is so used only on supervisor mode.
Since we are mainly in User mode, I first didn't understand it's useage.

Then, I read the 68000 switches to Supervisor mode when an exception occurs.
It uses the ISSP as the address where to store the current PC and User Stack Pointer. Then restore them back after exception processing.

So, ISSP must be an address where the 68000 must be able to save 2 long whithout overwriting some vars, right ?
and so, I'm making a big mistake using 0x0...
but, in this case, why my games are running with this 0x0 value ? Vint must fail, no ?

thanks for any light on this subject ;)
You said we are mainly in User Mode but i think we're almost always in Supervisor Mode when we're speaking about Sega Genesis software.
User Mode (UM) is useful on a OS where applications would use it and the system (OS Kernel) would use Supervisor Mode (SM).
On Sega Genesis we only run games which need all system resource so there is no point to be in UM. Initializing SP to 0 is probably the easiest and best way to not waste any memory bytes, we simply doesn't care about USP ;)

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Tue Jan 11, 2011 10:29 am

The ISP is loaded on a reset, which also puts you in supervisor mode. 0 is fine because the sp is pre-decremented when storing to the stack. So the first long would wind up being stored at 0 - 4, or 0xFFFFFFFC. Then remember that only 24 bits are output as the address, so the address is essentially 0xFFFFFC, or the top of ram.

In fact, using negative addresses is used by a LOT of software for accessing the top 32KB or ram. You can use short absolute addressing to access the top 32KB of ram, from 0xFFFFFFFF to 0xFFFF8000. Notice how the top word is always 0xFFFF? So short addresses from 0x8000 to 0xFFFF are sign extended and then the top byte becomes truncated when output on the address bus, so the ram at 0x00FF8000 is the same as 0x8000.

If you want to make heavy use of short addressing, it would be wise to make the initial SP 0x00FF8000 (or 0xFFFF8000) so that all 32KB of short addressable ram can be used by the program.

ElBarto
Very interested
Posts: 160
Joined: Wed Dec 13, 2006 10:29 am
Contact:

Post by ElBarto » Tue Jan 11, 2011 10:42 am

I personnaly set SR to 0x2300 (i've not seen anyone settings it to another value, except me when I was looking how TRACE mode works).
So it means that we set the S bit to 1 and M bit to 0.
From the 68k programmer's reference manual at page 22, figure 1.8 it said that we use ISP (not USP or MSP).
So yes I think we are all in supervisor mode (seems more logic that user mode),
I should change the comment in my code next to move.w #0x2300, sr, (it said setting to user mode :P).

And as Chilly Willy said, setting the ISP to 0 is ok as SP is pre-decremented.

GManiac
Very interested
Posts: 92
Joined: Thu Jan 29, 2009 2:05 am
Location: Russia

Post by GManiac » Tue Jan 11, 2011 1:15 pm

68k has no MSP and ISP and strange SPs, only USP and A7. I'll explain. I made tests on real HW. Initial value of SR is 2700. I did MOVE #$FFFF to SR and find out that SR has only one trace bit. Its value was A71F or something like this. I don't remember certain values, later I'll read my notes.
Also, initially we are in supervisor mode, that's why we can MOVE to SR.
Strange thing with USP. I did next:
MOVE x, A7
MOVE y, A0
MOVE A0, USP ( usp := y )
then I changed mode to user mode and read A7. And get old value of A7 (x), but not y, as it could be! Docs say A7 is indeed link to SSP or USP, but tests showed that A7 is independent register, and USP is too. And in user mode we cannot read USP, we'll get exception.

Any thoughts?

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Tue Jan 11, 2011 7:14 pm

My thought is you did the test wrong. If USP is not A7 in user mode then you would walk on ISP. We know that's not the case, so there's a bug in your test code.

The MSP was added in the 68020 (IIRC) so you don't have to worry about the difference between Supervisor and Master levels - you're either in supervisor state where A7 is ISP or you're in user state where A7 is USP.

GManiac
Very interested
Posts: 92
Joined: Thu Jan 29, 2009 2:05 am
Location: Russia

Post by GManiac » Tue Jan 11, 2011 8:34 pm

Code is very simple, what could I do wrong? Make your own tests.
Something like this:

Code: Select all

MOVE x, A7
MOVE y, A0
MOVE A0, USP
MOVE #$0700, SR      ; (user mode)
MOVE A7, A1
Then we monitor their values.

To return to Supervisor Mode we must get any exception, change value of SR in stack frame and then RTE. Afair....

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Tue Jan 11, 2011 10:29 pm

I don't want to make my own code, I want to see your test code so we can identify the bug. Making my own code won't debug YOUR code. :D

KanedaFr
Administrateur
Posts: 1139
Joined: Tue Aug 29, 2006 10:56 am
Contact:

Post by KanedaFr » Wed Jan 12, 2011 9:28 am

Ok, I clearly understood we are on Supervisor mode and so the address defined at 0x0 is the (SP+4) address.
But I don't understand how the vars are handled then...
When dev in C, I assume GCC define the global vars at RAM-start, so no problem of var colide.
But in ASM ? you define the address of a var, no ?
If it's true, I assume it's why I see ISP not at 0 on legacy games : they defined their vars from RAM-end, they 'counted' how many bytes then need and so defined their ISP from this...
I am right ?

I know I could simply not care about this, I'm only curious and I'm sure it could help me while disasming ;)

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Wed Jan 12, 2011 8:42 pm

You can always start with ISP = 0. Just before you clear the BSS and copy the DATA to the variables at the top of ram (assuming a game uses the top of ram for data), change a7 to point below those variables.

When you make a linker script (.ld file) for the Genesis, the ram should defined as 0xFFFF8000 instead of 0x00FF8000 if you want gcc to automatically generate short addressed data.

Post Reply