Splitting Datastack in ZP

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: Splitting Datastack in ZP

Post by barrym95838 »

However, if you switch it up and keep the high byte in zp,x and the low byte in abs,x you can cheat a little if you're dealing with an address like in C@ and move the low byte to zp-1,x and whip out a lda (zp-1,x), right?

Code: Select all

cfetch:
    lda dl,x
    sta dh-1,x
    lda (dh-1,x)
    sta dl,x
    sty dh,x    ; y assumed to be zero
    jmp next
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
BruceRMcF
Posts: 388
Joined: 21 Aug 2019

Re: Splitting Datastack in ZP

Post by BruceRMcF »

barrym95838 wrote:
However, if you switch it up and keep the high byte in zp,x and the low byte in abs,x you can cheat a little if you're dealing with an address like in C@ and move the low byte to zp-1,x and whip out a lda (zp-1,x), right?

Code: Select all

cfetch:
    lda dl,x
    sta dh-1,x
    lda (dh-1,x)
    sta dl,x
    sty dh,x    ; y assumed to be zero
    jmp next
Yes. Also, this is for a 65C02 system, so "stz dh,x" would work.

There are always trade-offs ... low byte in zero page saves a clock in the majority of cases with 1+:

Code: Select all

 ONEPL: ; 1+
        INC DL,X
        BNE +
        INC DH,X
+       JMP NEXT 
Now, the trick could hypothetically overflow into the working space below, but the space immediately below is workspace for UM/MOD so it wouldn't be problematic for C@.

But, before implementing alternatives to see how the trade-offs work out, first I have to get one up and working properly.
:D
resman
Posts: 154
Joined: 12 Dec 2015
Location: Lake Tahoe
Contact:

Re: Splitting Datastack in ZP

Post by resman »

To follow up with Bruce's NEXT in ZP and the importance of a quick DROP, I actually put DROP right in front of NEXT in ZP. Since I use a split stack, this consists of 'INX'.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Splitting Datastack in ZP

Post by barrym95838 »

My UM/MOD takes a couple hundred cycles more worst case because of all the indexing but is quite small and transforms everything in-place instead of needing any additional "workspace". Did someone mention something about tradeoffs? :)

[My browser's grammar checker thinks I try to use too many commas, so I've been heeding its advice. Should I?]
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Splitting Datastack in ZP

Post by barrym95838 »

resman wrote:
To follow up with Bruce's NEXT in ZP and the importance of a quick DROP, I actually put DROP right in front of NEXT in ZP. Since I use a split stack, this consists of 'INX'.
In PETTIL INX is NIP and DROP requires copying to TOS, but Charlie is very clever in his primitives to use NIP instead of DROP whenever possible.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
BruceRMcF
Posts: 388
Joined: 21 Aug 2019

Re: Splitting Datastack in ZP

Post by BruceRMcF »

resman wrote:
To follow up with Bruce's NEXT in ZP and the importance of a quick DROP, I actually put DROP right in front of NEXT in ZP. Since I use a split stack, this consists of 'INX'.
Talk about a coincidence, I just organized by DROP in a similar way yesterday afternoon ... my NEXT is in the dictionary except when it calls the single indirect jump in zero page, but DROP is the first header and the DROP primitive is just the INX before the NEXT code.

____________
barrym95838 wrote:
My UM/MOD takes a couple hundred cycles more worst case because of all the indexing but is quite small and transforms everything in-place instead of needing any additional "workspace". Did someone mention something about tradeoffs? :)

[My browser's grammar checker thinks I try to use too many commas, so I've been heeding its advice. Should I?]
One of the things I did Saturday afternoon was to copy your UM/MOD and convert it to my assembly terms ... and I don't recall off the top of my head, but is the UM* written in a similar style yours as well? ... to knock off the code multiple/divide in the Z80 Camel Forth port.

I think the broken version of xForth that I have sitting on a hard drive waiting to be attached to a working computer used the non-indexed version, which of course meant more copying of operands from the stack to my W and V vectors and N space, but for the target for this time around, working mostly on the stack to avoid the code footprint of moving all that stuff off the stack and back again. I did copy the divisor to my V zp vector, since it wouldn't have to be copied back, but I left the dividend->quotient on the stack.

One of the very slightly ungainly aspects of the "mongrel" split stack is that STY a,X doesn't exist, so the high byte part of SWAP is not 4 clocks more than a pure ZP split stack, but 6 clocks:

Code: Select all

SWAP:
        LDA DL,X
        LDY DL+1,X
        STA DL+1,X
        STY DL,X
        LDA DH,X
        LDY DH+1,X
        STA DH+1,X
        TYA
        STA DH,X
        JMP NEXT
But, again, since I'm not sweating an extra clock here or there in this implementation, it's not "nail on a chalkboard" irritating.

I also try to save a modest amount space (compared to my space spendthrift habits) by refraining from coding ROT and -ROT, but instead to code the shorter FLIP ( u1 u2 u3 -- u3 u2 u1 ) so that ROT and -ROT are:

Code: Select all

: ROT ( x1 x2 x3 -- x2 x3 x1 ) SWAP FLIP ;
: -ROT ( x1 x2 x3 -- x3 x1 x2 ) FLIP SWAP ;
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Splitting Datastack in ZP

Post by barrym95838 »

BruceRMcF wrote:
... and I don't recall off the top of my head, but is the UM* written in a similar style yours as well? ...
Nah, that's probably from Garth or Jeff or the other Bruce (dclxvi), but I wouldn't be able to tell you without more info.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Splitting Datastack in ZP

Post by barrym95838 »

BruceRMcF wrote:

Code: Select all

: ROT ( x1 x2 x3 -- x2 x3 x1 ) SWAP FLIP ;
: -ROT ( x1 x2 x3 -- x3 x1 x2 ) FLIP SWAP ;

Code: Select all

...
                 `  279 `---------------------------------------------------------------- -ROT
                 `  280 _dashrot: ` ( x1 x2 x3 -- x3 x1 x2 ) per stack diagram
00000073:da054001`  281     exa 1,s         ` ( x3 x2 x1 )
                 `  282 ` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SWAP
                 `  283 _swap: ` ( x1 x2 -- x2 x1 ) per stack diagram
00000074:da054000`  284     exa ,s
00000075:ae018000`  285     lde ,y+         ` aka jmp (,y+) aka NEXT
...
                 `  435 `----------------------------------------------------------------- ROT
                 `  436 _rot: ` ( x1 x2 x3 -- x2 x3 x1 ) per stack diagram
000000b9:da054000`  437     exa ,s          ` ( x1 x3 x2 )
000000ba:da054001`  438     exa 1,s         ` ( x2 x3 x1 )
000000bb:ae018000`  439     lde ,y+         ` aka jmp (,y+) aka NEXT
For my home-grown 65m32a ... too bad it's fallen off the back of my stove unfinished ... perfection is the enemy of progress :roll:
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
BruceRMcF
Posts: 388
Joined: 21 Aug 2019

Re: Splitting Datastack in ZP

Post by BruceRMcF »

barrym95838 wrote:
... For my home-grown 65m32a ... too bad it's fallen off the back of my stove unfinished ... perfection is the enemy of progress :roll:
That it can be ... but the pithy saying I am hoping on is "write twice, commit once".

If I get a working 65C02 more-or-less Camel Forth for the X16 that can load INCLUDE scripts written in the built in ROM-based Editor, I'll declare it "done enough" and focus on finding Forth programs to port as demos.
BruceRMcF
Posts: 388
Joined: 21 Aug 2019

Re: Splitting Datastack in ZP

Post by BruceRMcF »

barrym95838 wrote:
BruceRMcF wrote:
... and I don't recall off the top of my head, but is the UM* written in a similar style yours as well? ...
Nah, that's probably from Garth or Jeff or the other Bruce (dclxvi), but I wouldn't be able to tell you without more info.
I have yet to find where I borrowed my UM* routine, but I'm spreading around the routines I'm adapting, since I've just settled on one from Computer's ML Routines for the C64 for my (ANS Forth) ACCEPT routine for keyboard line input.
User avatar
Dr Jefyll
Posts: 3525
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Splitting Datastack in ZP

Post by Dr Jefyll »

BruceRMcF wrote:
I have yet to find where I borrowed my UM* routine
There's a good chance you'll find it here.
TobyLobster wrote:
I have exhaustively tested and compared the performance and memory use of over 60 integer multiplication routines from the internet. (EDIT: Now over 120 routines)
-- Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
BruceRMcF
Posts: 388
Joined: 21 Aug 2019

Re: Splitting Datastack in ZP

Post by BruceRMcF »

Dr Jefyll wrote:
BruceRMcF wrote:
I have yet to find where I borrowed my UM* routine
There's a good chance you'll find it here.
TobyLobster wrote:
I have exhaustively tested and compared the performance and memory use of over 60 integer multiplication routines from the internet. (EDIT: Now over 120 routines)
-- Jeff
Thanks, though I found it a couple of days ago ... I got it from Garth. I'm pretty sure that it's the same one I borrowed for my first version of xForth, and the multiply in that one worked, so I'm not going to mess with it until this version of xForth is up and running and, hopefully, with a working CREATE DOES>
Post Reply