6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 12:51 am

All times are UTC




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: 6502, Eprom and RAM
PostPosted: Wed Oct 08, 2003 6:28 pm 
Offline

Joined: Wed Oct 08, 2003 6:13 pm
Posts: 1
I am trying to use a 6502 in an A-level electronics project, but i have hit a few problems. i have the 6502 connected to the Eprom and RAM's addresses, and a 3-8 decoder on the top 3 address lines for chip selection, i know the addresses the processor looks at when its reset and what to store in them. what i dont understand is how the stack will work.
what i want to do is rotate a stepper motor, so the user will input a bearing via a keypad, this will be stored in RAM and accesses by the processor, the program being on the Eprom. the processor will then do its calculation and output the result to RAM. what i need to sort out is the way return addresses are handled. i know that the processor stores the return address on the stack, but, where is the stack implemented and how?

any advice would be much appreaciated.

cheers


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Oct 08, 2003 7:19 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
The 6502's native stack is in page 1, ie, from $0100-01FF. I say "native" for lack of a better term since you can have loads of stacks, but the push and pull instructions work specifically on this stack and the 6502 has the stack pointer, S, as one of the processor registers. Every time a byte is pushed onto the stack, the stack pointer S is decremented. Every time a byte is pulled off the stack, S is incremented. If you get down to $100, meaning S contains 0, the next push takes it to $FF which is added to $100 so it wraps around to $1FF instead of going into zero page. This doesn't really hurt anything assuming you're not overwriting something you want to keep, but it's generally a good idea to initialize the stack pointer as part of the reset routine by doing LDX #$FF, TXS. This will make sure your stack starts at $1FF and grows downward. Then if you're really strapped for RAM and need all you can get, you can put variables in the lower part of page 1 since it's quite unlikely that you'll need even a third of the page for the stack.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Oct 10, 2003 1:53 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
GARTHWILSON wrote:
The 6502's native stack is in page 1, ie, from $0100-01FF. I say "native" for lack of a better term since you can have loads of stacks


The proper term for this is the hardware stack, since this is the stack implemented by the microprocessor's hardware itself. Other forms of stacks are implemented in software.

Also, sometimes it helps to know the order of operations. The S register is used the same way a text cursor on the display is used. The cursor tells where the next character to be typed will go. Note that the cursor is always to the immediate right of the last typed character; it never points at the last character, unless you type a cursor movement key to place it explicitly.

Likewise, S register works the exact same way. It always points just one byte beyond the last pushed byte -- in other words, it determines where the next byte to be pushed will go. Note that in most other microprocessors, the stack pointer registers are used somewhat differently: they always determine where the last pushed byte or word is located, depending on whether the CPU deals with bytes or whole words.

Thus, to push something onto the stack, the microprocessor executes the following steps (note: this is pseudocode -- many "instructions" that I'm using here do not physically exist on the 6502!):

Code:
how_PHA_works:   (analogous to typing a character on the screen)
   sta $0100,s
   dec s

how_PLA_works:   (analogous to backspacing over the last typed character)
   inc s
   lda $0100,s


Remember that S is an 8-bit register, just like X and Y are in the 6502; hence, after 256 pushes or pops, the stack pointer will automatically wrap around. The bad news is that you're limited to at most 128 levels of nesting for subroutines. The good news is you'll never have a stack over-run problem like you sometimes do with other CPUs. Realistically speaking, however, well designed software generally won't even approach 8 levels of subroutine nesting in practice -- this is good because there's usually more data you want to store on the stack, which eats into that theoretical limit pretty quickly. IIRC, Garth made a measurement of stack utilization once for one of his projects, and it came to something like only 48 bytes or so, including interrupt handling overhead. Therefore, the only time you have to worry about the stack in practice is when you're writing a recursive function. But even here, you can always use a software-implemented stack to overcome that limitation.

Note also that the stack grows downward in memory. This is done more to optimize the operation of the hardware -- it actually will take less transistors to implement a stack this way than it would for a stack growing upward in memory. Part of the reasons this is the case is because addresses stored in the stack match the layout of addresses stored everywhere else; hence, when computing an effective address from popping an address off the stack (which the CPU must do when executing an RTS instruction, for example), it can do it in the normal low-byte-first, high-byte-next format.

The mechanism for pushing and popping is the same for other registers.

Again, contrast this with how the x86 or 680x0 series works:

Code:
how_PUSH_AX_works: (8086; 16-bit code; 32-bit works the same way)
   sub sp,2
   mov [sp],ax

how_POP_AX_works: (8086; 16-bit code; 32-bit works the same way)
   mov ax,[sp]
   add sp,2

how_PUSH_AX_works_286:  ( for 80286 or later processors )
   mov [sp-2],ax
   sub sp,2

how_PUSH_AX_works_286:  ( for 80286 or later processors )
   add sp,2
   mov ax,[sp-2]

how_-(A7)_works:  (680x0)
   subq.l   #4,a7
   move.l   reg,(a7)

how_(a7+)_works: (680x0)
   move.l   (a7),reg
   addq.l   #4,a7


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 21 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: