SSP on sega.s
Moderator: BigEvilCorporation
SSP on sega.s
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
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
-
- Very interested
- Posts: 3131
- Joined: Thu Nov 30, 2006 9:46 pm
- Location: France - Sevres
- Contact:
Re: SSP on sega.s
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.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
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
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
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.
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.
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 ).
And as Chilly Willy said, setting the ISP to 0 is ok as SP is pre-decremented.
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 ).
And as Chilly Willy said, setting the ISP to 0 is ok as SP is pre-decremented.
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?
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?
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 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.
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.
Code is very simple, what could I do wrong? Make your own tests.
Something like this:
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....
Something like this:
Code: Select all
MOVE x, A7
MOVE y, A0
MOVE A0, USP
MOVE #$0700, SR ; (user mode)
MOVE A7, A1
To return to Supervisor Mode we must get any exception, change value of SR in stack frame and then RTE. Afair....
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
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
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
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 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.
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.