Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Chuck's words @+ !+

289 views
Skip to first unread message

empty-buffers

unread,
Jan 30, 2015, 9:56:46 AM1/30/15
to
Maybe someone knows the meaning of Mr. Moore's word proposals @+ and !+ ?
No idea about their meaning ("fetch then increment"? Maybe, but the other
one: "store, then increment"? What should be incremented?).

Somehow I can't find their definitions.
--
"Yes, this is the bad end you've come to, and two and two is - as it always
was..." - began Trurl, but just then the machine made a faint, barely audible
croaking noise and said, for the last time: "SEVEN".

fort...@gmail.com

unread,
Jan 30, 2015, 10:08:37 AM1/30/15
to
Bernd has a @+ primitive in his b16-small. It simply leaves the address on the
stack after using it to fetch the data. It could be handy if incrementing thru a
range of addresses, but I suspect it's mostly done so that the CPU doesn't have
to drop two locations from the stack in one clock cycle.

: @ @+ drop ;

http://bernd-paysan.de/b16.html

Coos Haak

unread,
Jan 30, 2015, 10:30:03 AM1/30/15
to
Op Fri, 30 Jan 2015 14:56:45 +0000 (UTC) schreef empty-buffers:

> Maybe someone knows the meaning of Mr. Moore's word proposals @+ and !+ ?
> No idea about their meaning ("fetch then increment"? Maybe, but the other
> one: "store, then increment"? What should be incremented?).
>
> Somehow I can't find their definitions.

: @+ ( addr1 -- addr2 x )
dup cell+ swap @ ;
I've used this for decades, you might call it OUNT as a cell-wide COUNT ;-)

An implementation of !+ you might encounter is
: !+ ( addr1 x -- addr2 )
over ! cell+ ;
Mark that contrary to ! the parameters are swapped.

--
Coos

CHForth, 16 bit DOS applications
http://home.hccnet.nl/j.j.haak/forth.html

Alexander Wegel

unread,
Jan 30, 2015, 12:30:30 PM1/30/15
to
empty-buffers <empty.buffersYO...@gmail.NEITHER-THIS.com>
wrote:

> Maybe someone knows the meaning of Mr. Moore's word proposals @+ and !+ ?
> No idea about their meaning ("fetch then increment"? Maybe, but the other
> one: "store, then increment"? What should be incremented?).
>
> Somehow I can't find their definitions.

They're defined in the docs for the F18A cpu (at greenarrays), and they
are using/incrementing the A register, rather than addresses on the
stack.

@+ ( -- x )
!+ ( x -- )

Personally i used different versions (due to absence of address register
from normal forths):

@+ ( addr1 -- x addr2 )
!+ ( x addr1 -- addr2 )

which allows usages as in

src @+ @+ @+ @ dst !+ !+ !+ !

empty-buffers

unread,
Jan 30, 2015, 3:16:06 PM1/30/15
to
In comp.lang.forth, Coos Haak wrote:

>: @+ ( addr1 -- addr2 x )
> dup cell+ swap @ ;
> I've used this for decades, you might call it OUNT as a cell-wide COUNT ;-)
>
> An implementation of !+ you might encounter is
>: !+ ( addr1 x -- addr2 )
> over ! cell+ ;
> Mark that contrary to ! the parameters are swapped.

From what I see, your definitions differ to Bernd's. And how was the
"original", Chuck's definition of both?

Elizabeth D. Rather

unread,
Jan 30, 2015, 3:43:07 PM1/30/15
to
On 1/30/15 10:16 AM, empty-buffers wrote:
> In comp.lang.forth, Coos Haak wrote:
>
>> : @+ ( addr1 -- addr2 x )
>> dup cell+ swap @ ;
>> I've used this for decades, you might call it OUNT as a cell-wide COUNT ;-)
>>
>> An implementation of !+ you might encounter is
>> : !+ ( addr1 x -- addr2 )
>> over ! cell+ ;
>> Mark that contrary to ! the parameters are swapped.
>
> From what I see, your definitions differ to Bernd's. And how was the
> "original", Chuck's definition of both?
>

These versions of @+ and !+ have been kicking around a long time.
They're useful for walking through arrays. However, Chuck is perfectly
comfortable with reusing names for completely different and incompatible
purposes, of which OR is the best recent example. So, these words in
colorForth are whatever he says they are, and don't worry if they
contradict his usage in the past or other people's usage currently.

Cheers,
Elizabeth

--
==================================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com

"Forth-based products and Services for real-time
applications since 1973."
==================================================

empty-buffers

unread,
Jan 30, 2015, 3:57:44 PM1/30/15
to
My guess is, they should look like this, most probably:

: !+ ( n addr -- addr' ) dup cell+ -rot ! ;
: @+ ( addr -- n addr' ) dup @ swap cell+ ;
: c!+ ( n addr -- addr' ) dup 1+ -rot c! ;
: c@+ ( addr -- n addr' ) dup c@ swap 1+ ;

Such way I can comfortably store a chain of numbers:

1 2 3 4 5 pad !+ !+ !+ !+ !+ drop

Result: .s <0> ok

...or scan (and fetch values from) several neighbouring cells (or bytes):

pad @+ @+ @+ @+ @+ drop

Result: .s <5> 5 4 3 2 1 ok

Coos Haak

unread,
Jan 30, 2015, 4:29:09 PM1/30/15
to
Op Fri, 30 Jan 2015 20:16:04 +0000 (UTC) schreef empty-buffers:

> In comp.lang.forth, Coos Haak wrote:
>
>>: @+ ( addr1 -- addr2 x )
>> dup cell+ swap @ ;
>> I've used this for decades, you might call it OUNT as a cell-wide COUNT ;-)
>>
>> An implementation of !+ you might encounter is
>>: !+ ( addr1 x -- addr2 )
>> over ! cell+ ;
>> Mark that contrary to ! the parameters are swapped.
>
> From what I see, your definitions differ to Bernd's. And how was the
> "original", Chuck's definition of both?

Chuck's @+ and !+ are for the F18 and are quite different, see the posting
of Alexander Wegel.

empty-buffers

unread,
Jan 30, 2015, 7:30:13 PM1/30/15
to
In comp.lang.forth, Coos Haak wrote:

> Chuck's @+ and !+ are for the F18 and are quite different, see the posting
> of Alexander Wegel.

Oh, I see - his post somehow didn't reach newsserver I use, but found it in
Google Groups.
--
"Yes..." [..]

Albert van der Horst

unread,
Jan 31, 2015, 5:02:15 AM1/31/15
to
In article <4bbd1451-fcb2-4e48...@googlegroups.com>,
That is not the prime use of @+
It is best known under its ALIAS $@.
$@ is the equivalent of COUNT, but for a string whose count
occupies a whole cell.

"AAP" PAD $!

PAD $@ TYPE

AAP OK

>
>http://bernd-paysan.de/b16.html

Groetjes Albert
--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

rickman

unread,
Jan 31, 2015, 6:38:39 AM1/31/15
to
On 1/31/2015 5:02 AM, Albert van der Horst wrote:
> In article <4bbd1451-fcb2-4e48...@googlegroups.com>,
> <fort...@gmail.com> wrote:
>> On Friday, January 30, 2015 at 8:56:46 AM UTC-6, empty-buffers wrote:
>>> Maybe someone knows the meaning of Mr. Moore's word proposals @+ and !+ ?
>>> No idea about their meaning ("fetch then increment"? Maybe, but the other
>>> one: "store, then increment"? What should be incremented?).
>>>
>>> Somehow I can't find their definitions.
>>> --
>>> "Yes, this is the bad end you've come to, and two and two is - as it always
>>> was..." - began Trurl, but just then the machine made a faint, barely audible
>>> croaking noise and said, for the last time: "SEVEN".
>>
>> Bernd has a @+ primitive in his b16-small. It simply leaves the address on the
>> stack after using it to fetch the data. It could be handy if incrementing thru a
>> range of addresses, but I suspect it's mostly done so that the CPU doesn't have
>> to drop two locations from the stack in one clock cycle.
>>
>> : @ @+ drop ;
>
> That is not the prime use of @+
> It is best known under its ALIAS $@.
> $@ is the equivalent of COUNT, but for a string whose count
> occupies a whole cell.
>
> "AAP" PAD $!
>
> PAD $@ TYPE
>
> AAP OK

I find it a bit odd to have a two stack machine (not terribly different
from a two register machine) and to only process info from the data
stack. In my two stack CPU I use the return stack as an address stack.
It also has auto increment modes which do not automatically drop the
address, but it doesn't drop the address from the return stack which
interferes less with data accesses on the data stack. This makes some
other instructions simpler since the address is always on the return
stack and the same mechanism can be used for things like return or jump
to an address on the stack (computed or otherwise). They are actually
the same thing, no?

I have different instructions for immediate mode address such as would
be used to implement control flow instructions like IF or WHILE. This
is because I used a one bit opcode to indicate the literal used for
immediate mode addressing when the value is more than the few bits that
fit in the basic instruction. Depending on the use of an 8 or 9 bit
instruction opcode, the jump/call instructions have 4/5 bits of signed
relative address. This is extended by preceding the jump/call by
literal instruction(s) prepending 7/8 bits to the address. The first
literal loads its value to the return stack with sign extension and each
subsequent literal shifts the current value left loading the additional
bits. The literal instruction sets a "literal" flag to distinguish this
condition. The jump/call instruction does the same shifting before
using the value on the return stack if the literal flag is set,
otherwise it uses the immediate value directly.

I don't know that this works out any better than other methods. The
little bit of comparison I did to RISC instruction sets showed the
instruction density was about the same since the instructions do a lot
less. At one point I was looking at an instruction format that allowed
for offsets in accessing data on the stack which seems to save a lot of
the stack juggling instructions. Think of it as a hybrid between a
stack machine and a register machine. I never followed through with
that to produce an implementation. I may return to that once I finish
the other tasks I have at hand.

--

Rick

HAA

unread,
Feb 1, 2015, 1:11:34 AM2/1/15
to
empty-buffers wrote:
> My guess is, they should look like this, most probably:
>
> : !+ ( n addr -- addr' ) dup cell+ -rot ! ;
> : @+ ( addr -- n addr' ) dup @ swap cell+ ;
> : c!+ ( n addr -- addr' ) dup 1+ -rot c! ;
> : c@+ ( addr -- n addr' ) dup c@ swap 1+ ;
>
> Such way I can comfortably store a chain of numbers:
>
> 1 2 3 4 5 pad !+ !+ !+ !+ !+ drop
>
> [...]
>
> ...or scan (and fetch values from) several neighbouring cells (or bytes):
>
> pad @+ @+ @+ @+ @+ drop

Systems which implement these functions as part of their kernel run into
the same problem.



Mark Wills

unread,
Feb 1, 2015, 7:42:08 AM2/1/15
to
My system has had @++ since 2009.

: @++ ( address -- address+2 value )
dup 1 cell + swap @ ;

Gary Bergstrom

unread,
Feb 12, 2015, 11:10:22 AM2/12/15
to
I find this sort of thing quite convenient.
I usually set two registers (on chips that have extras) that I call A and B.
Then I define >A, A@, A@+, A!, etc
Great for moving things around.
I find them so useful that I made them part of my multitasker, which now saves them across task swaps. A tiny extra overhead in the multitasker is usually acceptable for such convenience.
Before that I had to do something like A> >R ... R> >A around code that would call PAUSE. On the MSP430 the A> >R and R> >A are 2 and 1 instructions so this is low overhead too. But you have to remember to do it.

Regards,
Gary

rickman

unread,
Feb 12, 2015, 1:48:45 PM2/12/15
to
That is one of the advantages of using the return stack for A. It is
already on the stack for any context changes. The only issue is that
this can get in the way of using a loop counter which is where you often
use an operation like A@+. But if instead you use a limit on the
address the increment and compare don't conflict.

--

Rick

Mikael Nordman

unread,
Feb 12, 2015, 2:35:06 PM2/12/15
to
In my FlashForth I have a similar solution but the register is
called P for pointer.
It saved in the taskswitch and it is also re-entrant by the
!P>R R>P words which can be used when entering and exiting words.

BR Mike
0 new messages