6502 Stack

Discuss all aspects of programming here. From 8-bit through to modern architectures.
User avatar
FourthStone
Posts: 397
Joined: Thu Nov 17, 2016 2:29 am
Location: Melbourne, Australia

6502 Stack

Postby FourthStone » Tue Nov 14, 2017 5:02 am

I have a question regarding the 6502 stack, I'm wondering if executing a PLA is destructive or if the data remains on the stack?

For instance, say push a series of data to the stack (PHA) then I store the stack pointer (TSX) then pull the data from the stack and use it for something (PLA) then update the stack pointer with TXS, will the previously stored data still be present and accessible with PLA?

Will do some playing around but just wanted others experience of how the stack operates and maybe a few pointers or tricks to do :-)

User avatar
BigEd
Posts: 1444
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: 6502 Stack

Postby BigEd » Tue Nov 14, 2017 5:23 am

The data will remain, but possibly only for a short time, because if an interrupt happens it will push three values onto the stack.

If you need to pick a value from the stack without pulling it, you generally use the stack pointer value to index into page one:

Code: Select all

TSX
LDA &0101,X

Hope this helps!

Code: Select all

Address  Hexdump   Dissassembly
-------------------------------
$0600    a9 01     LDA #$01
$0602    48        PHA
$0603    a9 ff     LDA #$ff
$0605    ba        TSX
$0606    bd 01 01  LDA $0101,X
$0609    a8        TAY
$060a    ea        NOP
$060b    ea        NOP
$060c    a9 ff     LDA #$ff
$060e    68        PLA
$060f    ea        NOP
$0610    ea        NOP

User avatar
kieranhj
Posts: 511
Joined: Sat Sep 19, 2015 10:11 pm
Location: Farnham, Surrey, UK

Re: 6502 Stack

Postby kieranhj » Tue Nov 14, 2017 1:42 pm

As BigEd said. If you PLA stuff off the stack then you are at the mercy of interupts before the data is corrupted. You can, however, use the data freely & directly within the stack after it has been PHA'd before you PLA or reset the stack pointer.

This is what the Exile (and PoP) sprite routine does - push data onto the stack, TSX to locate where the stack pointer is, then read data directly out of it using LDA &1ZZ, X (where ZZ is modified at runtime to enable the index to start from 0.)

To save having to pull all the data back off, you can just remember the stack pointer before you start and reset it at the end using TXS.
Bitshifters Collective | Retro Code & Demos for BBC Micro & Acorn computers | https://bitshifters.github.io/

crj
Posts: 237
Joined: Thu May 02, 2013 4:58 pm

Re: 6502 Stack

Postby crj » Tue Nov 14, 2017 4:05 pm

Curiously, I was independently thinking similar thoughts just the other day.

It occurred to me that if you wrote a fragment that stored PLA:TAX:PLA:TAY:PHA:TXA:PHA:RTS somewhere in memory then JSRed to it, on return you would have the address of your code in X,Y. It would be faff, but with care that would let you write position-independent code on the 6502.

Unfortunately, that still requires a tiny bit of safe memory at an absolute address somewhere to poke those eight bytes of code. You could push that code fragment itself onto the stack, but then there'd be no way to JSR to it. )-8

User avatar
tricky
Posts: 1882
Joined: Tue Jun 21, 2011 8:25 am
Contact:

Re: 6502 Stack

Postby tricky » Tue Nov 14, 2017 5:21 pm

I wrote a similar version of that last night, as I am making ROM versions of my games, but wanted them to be *RUNable too and the decompression code needs to know where to decompress from. I picked &70..74 :) for my decompression workspace, and put the tax etc there too.

crj
Posts: 237
Joined: Thu May 02, 2013 4:58 pm

Re: 6502 Stack

Postby crj » Tue Nov 14, 2017 8:42 pm

In that case, you'll have two different entry points, one for the ROM and one for the executable. Can't the entry point just pass the origin to the decompressor in a register?

User avatar
FourthStone
Posts: 397
Joined: Thu Nov 17, 2016 2:29 am
Location: Melbourne, Australia

Re: 6502 Stack

Postby FourthStone » Tue Nov 14, 2017 10:38 pm

Thanks all for the responses, I think I'm getting a clearer idea for my use.
kieranhj wrote:As BigEd said. If you PLA stuff off the stack then you are at the mercy of interupts before the data is corrupted. You can, however, use the data freely & directly within the stack after it has been PHA'd before you PLA or reset the stack pointer.

This is what the Exile (and PoP) sprite routine does - push data onto the stack, TSX to locate where the stack pointer is, then read data directly out of it using LDA &1ZZ, X (where ZZ is modified at runtime to enable the index to start from 0.)

To save having to pull all the data back off, you can just remember the stack pointer before you start and reset it at the end using TXS.

I guess I was trying to save a few cycles per loop which can all add up, would an absolute or indirect read from the stack memory space be any different from somewhere else in ram?

User avatar
tricky
Posts: 1882
Joined: Tue Jun 21, 2011 8:25 am
Contact:

Re: 6502 Stack

Postby tricky » Tue Nov 14, 2017 11:35 pm

lda &101,x 4 cycles 3 bytes
lda (&70),y 5 cycles 2 bytee
lda (&70,x) 6 cycles 2 bytee

In the end I didn't need the address as I did know whether I was running from ROM or *RUNning.
Last edited by tricky on Wed Nov 15, 2017 7:53 am, edited 1 time in total.

crj
Posts: 237
Joined: Thu May 02, 2013 4:58 pm

Re: 6502 Stack

Postby crj » Wed Nov 15, 2017 12:39 am

However, what goes on the stack must come off, and each PLA takes 4 cycles. (Using TSX,TXA,ADC#,TAX,TXS to discard any number of items at once takes 10 cycles.)

You need to be using the data on the stack enough times that saving one cycle each time you LDA &101,X instead of LDA (&70),X is a useful tradeoff.


Return to “programming”

Who is online

Users browsing this forum: No registered users and 3 guests