6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Sep 22, 2024 6:32 am

All times are UTC




Post new topic Reply to topic  [ 9 posts ] 
Author Message
PostPosted: Fri Aug 28, 2015 4:27 pm 
Offline

Joined: Sun Feb 23, 2014 2:43 am
Posts: 78
I need to do negative indexing into the stack on the 65816, but am unsure of the correct way to do this?


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 28, 2015 5:02 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8390
Location: Midwestern USA
joe7 wrote:
I need to do negative indexing into the stack on the 65816, but am unsure of the correct way to do this?

What do you mean by negative indexing? Could you give a code example?

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 28, 2015 6:05 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
You mean accessing memory at or below (at a lower address) than that indicated by the stack pointer? There's arguably no "correct" way to do that, because of the risk an interrupt will stomp on the memory you're accessing. But if you can rule out interrupts -- including NMI, BRK, RST and ABORT -- then begin with a TSX and the forbidden thing can be accomplished!

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 28, 2015 6:18 pm 
Offline

Joined: Sun Feb 23, 2014 2:43 am
Posts: 78
I was basically doing something like that. Didn't think about the interrupts.. maybe it would be better to make a separate stack instead of using the processor stack.


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 28, 2015 6:55 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8390
Location: Midwestern USA
joe7 wrote:
I was basically doing something like that. Didn't think about the interrupts.. maybe it would be better to make a separate stack instead of using the processor stack.

As Jeff pointed out, writing to the stack at or below the stack pointer is risky. However, you can make it work by adjusting the stack pointer downward to reserve some workspace. For example, to reserve 10 bytes, do the following:

Code:
         tsx                   ;get current stack pointer
         txa                   ;give it to accumulator
         sec
         sbc #10               ;adjust by size of workspace
         tax
         txs                   ;set new stack pointer

The above will work on any 8 bit 65xx MPU, as well as on the 65C816 in emulation mode. If you are running the 65C816 in native mode, the procedure is slightly different and a bit simpler:

Code:
         rep #%00100000        ;16 bit accumulator
         tsc                   ;copy stack pointer to accumulator
         sec
         sbc #10               ;adjust by size of workspace
         tcs                   ;set new stack pointer

In the 65C816 example, 10 is treated as a 16 bit value, since the accumulator size is 16 bits to accommodate the MPU's 16 bit stack pointer.

Once the adjustment has been made, any stack accesses caused by interrupts or subroutine calls will not disturb your reserved space until you relinquish it. When you are done with the workspace just reverse the above processes.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 28, 2015 7:28 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
BigDumbDinosaur wrote:
However, you can make it work by adjusting the stack pointer downward to reserve some workspace.
Right -- and BDD has shown the general technique for reserving and releasing an arbitrary amount of space.

More specifically, in a case where only a handful of bytes are needed, it's faster to adjust the stack pointer simply by coding some dummy pushes or pulls. By "dummy" I mean the data transferred to or from memory is "don't care" and will be discarded -- the actual goal is merely to increment or decrement S.

It's only appropriate in certain cases. Dummy pulls can be awkward, since the data transfer can't be avoided and may destroy a register you'd prefer to keep. (But the general technique destroys a register, too, so it's a wash.)

A dummy push only destroys some memory space that's undefined anyway. And, if you're clever, the value pushed will be not garbage to be overwritten but instead something the following code can actually use. If you haven't already, check out the PEA PEI and PER instructions. :)

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Sat Aug 29, 2015 3:48 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8390
Location: Midwestern USA
Dr Jefyll wrote:
More specifically, in a case where only a handful of bytes are needed, it's faster to adjust the stack pointer simply by coding some dummy pushes or pulls. By "dummy" I mean the data transferred to or from memory is "don't care" and will be discarded -- the actual goal is merely to increment or decrement S.

Right. I think I once figured out that the "break even" point on the '816 for where arithmetic adjustment of the stack pointer was faster than dummy pushes was at 5 bytes.

Quote:
It's only appropriate in certain cases. Dummy pulls can be awkward, since the data transfer can't be avoided and may destroy a register you'd prefer to keep. (But the general technique destroys a register, too, so it's a wash.)

A dummy push only destroys some memory space that's undefined anyway. And, if you're clever, the value pushed will be not garbage to be overwritten but instead something the following code can actually use. If you haven't already, check out the PEA PEI and PER instructions. :)

I often use PEA #0 to generate and initialize stack space, even if I need an odd number of bytes. It also allows me the leave the registers untouched. PEI is useful if an initial 16 bit value needed on the stack is already sitting on direct page. PER's only real value is to set up an address relative to PC. It's slower than the other two, so I don't see it as a particularly good way to reserve and initialize stack space.

As you note, there's no way to avoid clobbering a register to release stack space. Either it will be done via pulls or arithmetically. Fortunately. with the '816 only the accumulator is needed to arithmetically adjust SP.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Tue Sep 01, 2015 4:06 pm 
Offline

Joined: Sun Feb 23, 2014 2:43 am
Posts: 78
Ended up just making a separate stack, but it's nice to know that method of reserving stack space. Still pretty rusty on the 65816, it's a very "different" processor.


Top
 Profile  
Reply with quote  
PostPosted: Tue Sep 01, 2015 10:01 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8390
Location: Midwestern USA
joe7 wrote:
Still pretty rusty on the 65816, it's a very "different" processor.

Not really different, just more flexible. The basic 65C02 instruction set is there, just with more features. You don't have to use them.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 14 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: