diff --git a/blk/046 b/blk/046 index efc468f..aa50826 100644 --- a/blk/046 +++ b/blk/046 @@ -11,6 +11,6 @@ SWAP a b -- b a 2SWAP a b c d -- c d a b PICK Pick nth item from stack. "0 PICK" = DUP, "1 PICK" = OVER. - - +ROLL Rotate PSP over n items. "1 ROLL" = SWAP, + "2 ROLL" = ROT. 0 is noop. diff --git a/emul/forth/z80c.bin b/emul/forth/z80c.bin index 6cd8124..e260c9c 100644 Binary files a/emul/forth/z80c.bin and b/emul/forth/z80c.bin differ diff --git a/forth/boot.z80 b/forth/boot.z80 index 7b8b6d3..60df6c5 100644 --- a/forth/boot.z80 +++ b/forth/boot.z80 @@ -403,6 +403,27 @@ CODE PICK BC PUSHqq, ;CODE +( this is only a part of ROLL, the other part is performed in + high level Forth. This receives from PSP the number of bytes + to copy and then performs A move-by-2 operation from SP. + This copies SP's TOS and overwrites the last item involved. + + For example, if stack is "1 2 3 4", calling with "4" would + result in the stack "1 3 4 4". Never call with 0, there is + no sanity check. +) +CODE (roll) + HL POPqq, + B H LDrr, + C L LDrr, + SP ADDHLss, + D H LDrr, + E L LDrr, + HL DECss, + HL DECss, + LDDR, +;CODE + ( a b -- a b a b ) CODE 2DUP HL POPqq, ( B ) diff --git a/forth/core.fs b/forth/core.fs index 1b4c7d5..584ea2cd 100644 --- a/forth/core.fs +++ b/forth/core.fs @@ -55,6 +55,13 @@ H@ 2- ( push a. -2 for allot offset ) ; IMMEDIATE +: ROLL + DUP NOT IF EXIT THEN + 1+ DUP PICK ( n val ) + SWAP 2 * (roll) ( val ) + SWAP DROP +; + ( During a CASE, the stack grows by 1 at each ENDOF so that we can fill all those ENDOF branching addrs. So that we know when to stop, we put a 0 on PSP. That's our stopgap. )