Split stack vs. other approaches

Topics relating to various Forth models on the 6502, 65816, and related microprocessors and microcontrollers.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Split stack vs. other approaches

Post by barrym95838 »

You never published your source code, Dr. Brad? I would love to see it sometime, as a non-trivial example of proper technique for a novice like myself.

Mike B.
Brad R
Posts: 93
Joined: 07 Jan 2014
Contact:

Re: Split stack vs. other approaches

Post by Brad R »

The oversight has now been rectified. Source code is here. Be warned that it was originally written in Forth 'screens' using 'shadow screens' for documentation; when converted to an ASCII text file, all the shadow screens got put at the end. Someday I should reformat it into 128-character lines with the comments alongside the text, or perhaps interleave the shadow screens with the source screens. There's also a lot of white space from empty screens.

You will probably find the glossary useful, as well. And a lot of it was written in assembly-language CODE words (for the 80x86).
Because there are never enough Forth implementations: http://www.camelforth.com
dwight
Posts: 213
Joined: 08 Jun 2004

Re: Split stack vs. other approaches

Post by dwight »

Dragging out an older post.
On TOS optimizing.
I wrote a optimizing compiler for a DSP chip. Words that used value on
top of the stack had two entries. One that assumed the TOS was
in the TOS location and the other that it was not.
The compiler kept track of the state of TOS. If it was empty the
consuming word would be compiled at the earlier address that
popped the value.
This was only for low level words. Most high level words kept the stack
balanced.
Dwight
chitselb
Posts: 232
Joined: 21 Aug 2010
Location: Ontonagon MI
Contact:

Re: Split stack vs. other approaches

Post by chitselb »

barrym95838 wrote:
That's Charlie's deal with his Pettil implementation. It involves some trade-offs. A favorable example: NIP becomes INX. There are pros and cons to any decision like that. For my 65m32 DTC Forth, I keep TOS in the accumulator, but that would be impossible for a 6502, and a dubious optimization for an '802/'816. Perhaps Charlie did some benchmarks that led to his design decision, and would be able to share them briefly with us, here or in a fresh thread?
Looking at this again, another advantage of split stack with separate TOS is that all Forth words referencing TOS will save a few clock cycles by virtue of zp (and not zp,X) addressing mode, e.g. `+`

Code: Select all

plus    ; split stack with separate tos
    clc             ;[2]
    lda tos         ;[3]
    adc stackl,x    ;[4]
    sta tos         ;[3]
    lda tos+1       ;[3]
    adc stackh,x    ;[4]
    sta tos+1       ;[3]
    inx             ;[2]
    jmp next        ;[3] =27 clocks

vs.

plus    ; split stack only
    clc               ;[2]
    lda stackl,x      ;[4]
    adc stackl+1,x    ;[4]
    sta stackl+1,x    ;[4]
    lda stackh+1,x    ;[4]
    adc stackh,x      ;[4]
    sta stackh+1,x    ;[4]
    inx               ;[2]
    jmp next          ;[3] =31 clocks
dwight
Posts: 213
Joined: 08 Jun 2004

Re: Split stack vs. other approaches

Post by dwight »

Arrays also benefit from LSB/MSB splittng.
In the programming section I use this a bunch, in my
distribution sort code, but it does chew up page zero pointers faster.
Dwight
Martin_H
Posts: 837
Joined: 08 Jan 2014

Re: Split stack vs. other approaches

Post by Martin_H »

Brad R wrote:
_________________
Because there are never enough Forth implementations: http://www.camelforth.com
@Brad, any idea when Camelforth will be ported to the 6502? They have a 6809 port and that chip isn't in production! Plus an 1802 port!?
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Split stack vs. other approaches

Post by JimBoyd »

chitselb wrote:
Garth has gently suggested that the split stack might not be very good.
GARTHWILSON wrote:
It would take some convincing for me to believe that splitting the stack and having to keep moving things in and out of a fixed-address TOS pair of ZP bytes would be more efficient than keeping byte pairs together in every cell and doing indexing and doing the INX or DEX twice to add or drop stack cells.
There are two 48-byte regions of zero page called 'stackl' and 'stackh', with 'tos' being stored in a separate 2-bytes contiguous region of zero page. The X register is the stack pointer
I agree with Garth on this. I'm implementing multitasking on my Forth. The best way I can find to use the stacks is for each task to have a portion of each stack. Each task would have a different location for empty stack. Using the data stack as an example, in the main task, when the stack pointer is at hexadecimal 7E the stack would be empty. with the first background task it might be 5E. For the next background task it might be 3E. It all depends on how much data stack each task needs and how many tasks there are.
It just seems that PETTIL's split stack approach with TOS in a dedicated zero page location would make implementing multitasking more difficult.
Post Reply