6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Nov 24, 2024 3:52 am

All times are UTC




Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Sun Jul 05, 2015 2:16 pm 
Offline

Joined: Fri Jan 17, 2014 6:39 pm
Posts: 47
Location: Poland
1. A stack uses a separate RAM.
2. It may be of any size, limited only by the size of memory used.
3. RAM $ 100- $ 1FF can be used for the program.
Here is a diagram of the first version.
What do you think, about this ? :mrgreen:


Attachments:
stos.pdf [31.01 KiB]
Downloaded 107 times
Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 05, 2015 3:46 pm 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
grzeg:

Your concept appears to redirect the stack push/pop instructions to a separate memory whose size is set by the number of counters used to generate the address. Several questions come to mind after reviewing your initial circuit diagram.

Since it appears that page 1 is to be allocated to program instructions and/or user data, what is not clear is how the non-instruction based usage of the stack will be accommodated? In other words, how will the pushes made to the stack during interrupt and BRK processing be redirected to your dedicated stack so page 1 can be used for program instructions and/or data?

In addition, it is not clear how normal memory access instructions may be used to access subroutine/function arguments passed on the stack?

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 05, 2015 5:52 pm 
Offline

Joined: Fri Jan 17, 2014 6:39 pm
Posts: 47
Location: Poland
MichaelM
As you can see, for the time being should work rokazy PHP / PLP and PHA / PLA.
I have yet to come up for JSR and interrupts.

I'm thinking...


Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 05, 2015 5:59 pm 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
Looking forward to further updates on your extended solution.

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 05, 2015 10:06 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
On a slightly related note, I always wondered if it would be possible to shadow code being executed and data being read and/or written, Harvard-style. For example, doing a JSR $F000 would trigger access to a different memory space than a LDA $F000 or ROL $F000. Does the 65xx provide sufficient external signals to allow this to be implemented with a minimum of fuss, like a few gates and latches?

Mike B.

[Edit: "Shadow" probably isn't the correct word, but I'm at temporary loss to come up with something better. My idea would prevent self-modifying code and data tables in the code space, but that's not a deal-breaker ... not being able to easily do it would be, though.]


Last edited by barrym95838 on Sun Jul 05, 2015 11:29 pm, edited 2 times in total.

Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 05, 2015 10:36 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
Continuing on what MichaelM said: It would be extremely limiting to not be able to have other access to the stack area, like to handle parameters passed via the stack either implicitly or explicitly, handling them like this for example:
Code:
         TSX
         LSR  $107,X
         ROR  $106,X

where you're accessing bytes at varying depths in the stack without first taking everything off from above them first.

Even in interrupts, if you handle BRK, you'd want to be able to do something like:
Code:
ISR:    PHA          ; (Later you may need to push Y also, with PHY, if the
        PHX          ; ISR uses Y anywhere. NMOS will have to go through A.)

        TSX
        LDA  103,X   ; Get the stacked staus, and
        AND  #$10    ; see if the B bit is set (meaning a BRK instruction
        BNE  break   ; caused the interrupt.  If B bit is set, branch.

        <service hardware interrupt>


        PLX
        PLA
        RTI
 ;-------------

break:  LDA  104,X   ; The return addr is at 104,X and 105,X, and the
        SEC          ; signature byte is at the addr they point to, minus 1.
        SBC  #1      ; Use SBC here, not DEA, because we want the C flag.
        STA  temp    ; Do low byte first (temp is in ZP),

        LDA  105,X   ; then high byte.
        BCS  brk1    ; If decrementing the low byte did a borrow,
        DEA          ; then decrement the high byte too.
 brk1:  STA  temp+1

        LDA  (temp)  ; Read the signature byte
         .           ; which will determine the next actions.
         .
         .



The stack is also used for finding inlined data the handle, and then return with the program counter incremented past the data, as in:
Code:
        JSR   PRIMM
        .BYTE "This will be printed!", $00


or in synthesizing instructions, having local variables (including for recursion), etc..

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 06, 2015 1:12 am 
Offline

Joined: Sun Jul 28, 2013 12:59 am
Posts: 235
barrym95838 wrote:
On a slightly related note, I always wondered if it would be possible to shadow code being executed and data being read and/or written, Harvard-style. For example, doing a JSR $F000 would trigger access to a different memory space than a LDA $F000 or ROL $F000. Does the 65xx provide sufficient external signals to allow this to be implemented with a minimum of fuss, like a few gates and latches?

Mike B.

[Edit: "Shadow" probably isn't the correct word, but I'm at temporary loss to come up with something better. My idea would prevent self-modifying code and data tables in the code space, but that's not a deal-breaker ... not being able to easily do it would be, though.]

You're basically looking to have the instruction stream read from a separate memory space than the data stream? I think that this may be doable with a stock 'c02, but you'll need a small amount of extra memory in order to make it happen. When an instruction-fetch occurs, the SYNC line gets triggered. Based on this and the actual opcode fetched, you know how many more bytes will be read from the instruction stream before a non-instruction reference occurs, and then all references are essentially data references until the next SYNC. A latch, a 4-bit parallel-load counter, and a 256x4 memory element, and you should be off to a good start.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 06, 2015 1:40 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
You completely understood what I was awkwardly trying to say, nyef! Thanks for the insight.

I was thinking that in some cases it would be neat to have a bunch of executable code in ROM under the I/O and display buffers in the memory map. With a qualifying signal from A15 or something, you could still mark off some space to store executable code in RAM at run-time. You could also overlap two ROMs, and have one contain executable code and the other contain tables and other constants. It would make the 64K address space that much less crowded, wouldn't it?

Mike B.

[Edit: in light of Jeff's recent post, I suppose that page-crossing cycles might be difficult to anticipate, and that could be the deal-breaker, because it might require the index register values to be known (and tracked) by the address translator at all times. Not impossible, as long as they are initialized before use, but still a bit cumbersome. The accumulator and stack pointer would have to be tracked as well, because of the possibility of a TAX, TSX or TAY, so you would basically have to include an entire 65xx ALU in the translator hardware, at least in that strategy.]

[Edit #2: Oh, I had cycles on the brain, not instruction lengths, which are, of course, constant. Duh!]


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 06, 2015 4:12 am 
Offline

Joined: Sun Jul 28, 2013 12:59 am
Posts: 235
barrym95838 wrote:
You completely understood what I was awkwardly trying to say, nyef! Thanks for the insight.

You're welcome. I've been thinking about some of this (tracking what the CPU is doing externally to provide additional functionality) for a while, and this seems like one of the simpler (and more doable) applications.

Quote:
[Edit: in light of Jeff's recent post, I suppose that page-crossing cycles might be difficult to anticipate, and that could be the deal-breaker, because it might require the index register values to be known (and tracked) by the address translator at all times. Not impossible, as long as they are initialized before use, but still a bit cumbersome. The accumulator and stack pointer would have to be tracked as well, because of the possibility of a TAX, TSX or TAY, so you would basically have to include an entire 65xx ALU in the translator hardware, at least in that strategy.]

[Edit #2: Oh, I had cycles on the brain, not instruction lengths, which are, of course, constant. Duh!]

No, for this it's still cycles. Here's the trick: You only care about the cycles that are fetching from the instruction stream, not the cycles that are used for data and I/O. With the exception of branch instructions, none of the instructions have a variable number of cycles spent fetching the instruction stream. They all fetch so many instruction bytes (in as many cycles), then pay cycle penalties on the data accesses. And for the branch instructions, all of the cycles are spent on the instruction stream, so you just have to max out the counter and let it get reset with the next SYNC pulse.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 06, 2015 7:01 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
Got it. Nice. You should start a new thread with what you've already worked out. Or are you still too early in the design stage?

Mike B.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 06, 2015 11:01 am 
Offline

Joined: Sun Jul 28, 2013 12:59 am
Posts: 235
barrym95838 wrote:
Got it. Nice. You should start a new thread with what you've already worked out. Or are you still too early in the design stage?

Still in the "crazy idea" stage, really. I don't know if it's even possible to do what I want with a reasonable amount of hardware.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 06, 2015 3:49 pm 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
Rather than extending the stack why not just have a mechanism that allows zero page and/or the stack to be mapped to another area so you can multiple of each?

Being able to switch out $0000-$01ff would make task switching a lot easier. You could extend the stack for a given task by periodically giving it a new stack page and keeping page zero as is. Or you could allocate new zero pages for fast scratch work space.

In some of my designs I use 128K RAM chips to minimise chip count but that wastes 64K. I would be nice to be able to use that as 256 swapable pages.

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 06, 2015 6:42 pm 
Offline
User avatar

Joined: Mon May 12, 2014 6:18 pm
Posts: 365
Quote:
Rather than extending the stack why not just have a mechanism that allows zero page and/or the stack to be mapped to another area so you can multiple of each?
I was thinking about this myself. Why not give every function its own 256 byte stack to work with? You would just need one counter. 4-bit would do unless you plan to call more than 16 levels of subroutines. You could have a macro that pushes S to the stack before JSR then increases the external counter by 1 one and resets S. Actually, you might not necessarily need S since you could hardcode 256 bytes of local variables as absolute addresses (in that case you could put it in another part of memory though). Like most of these ideas, it might be better to use a 65C816 but this solution seems plausible with a lot of RAM and a CPLD, which you probably have already anyway.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 06, 2015 10:00 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
More ideas here
-- J. :)

Radar Controller hacks 6502 illegal instructions

Quote:
We used illegal opcodes and a piggy-back board to add instructions to the 6502 processor. When we decoded an illegal opcode, we floated a no-op onto the instruction bus (for a defined number of cycles) and then let our custom PAL decode what really should happen. Doing this, we added a “paging register” for the zero-page and 1xx page (which you know are special). For the 1xx page, we detected when stack overflows and underflows happened and auto-adjusted the 1xx page register. Doing this gave us a 256-byte window into a (essentially) 64K stack.

_________________
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: Sun Jul 12, 2015 12:59 pm 
Offline

Joined: Mon Apr 16, 2012 8:45 pm
Posts: 60
The instruction TSX is a clear indication that you are about to access the stack directly. So why not use TSX as a mode switch to map the stack temporarily into $100 - $1ff? You could then use TXS to return to the mode where stack lives in its own separate area. Using a separate area for stack should allow for much faster instructions that use the stack.

Two issues remain. First of all how do you handle interrupts? Secondly how do you handle a stack pointer that is much wider than 8 bit and thus cannot fit into the X-register? I am sure some thinking can overcome these issues and mu hunch is that this can be worthwhile too.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 53 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: