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

Parallax Propeller

872 views
Skip to first unread message

Peter Jakacki

unread,
Jan 13, 2013, 1:37:05 AM1/13/13
to

For some reason I found myself reading these newsgroups which I haven't
really used for many years. It seems that although the Parallax Propeller
web forums are extremely active there never seems to be much discussion
elsewhere. Aren't you all curious as to what you are missing out on?

I have used just about every kind of micro and architecture over the
decades and while I might still use some small "one buck" micros for
certain tasks and some special ARM chips for higher end tasks I have
almost exclusively been using Propeller chips for everything else. The
reason is very simple, they are so simple to work with and there are no
"peripheral modules" to worry about other than the counters and video
hardware per cog. Every pin is general-purpose and any one of the eight
32-bit cores can use them, you don't have to worry about trying to route
a special pin or have the dilemma of using the special pin for one
function but not the other etc. The 32-bit CPUs or cogs are a breeze to
program and you can work with a variety of languages besides the easy to
use Spin compiler that comes with it.

For you Forth enthusiasts there has been a big flurry of Forth related
threads on the Propeller forums of late and there are several versions of
Forth including my own Tachyon Forth. IMHO this is the best way to get
into the Propeller and it's hardware. I just can't be bother trying to
cram functions and debug interrupts on other chips when I can set a cog
to work on a task and still have plenty of resources left over including
video on-chip.

If you are intrigued or just plain curious it won't kill you unless you
are a cat to have a look at my introduction page which has links to
projects and the forum etc.
http://goo.gl/VX7pc

There is the sup'ed up version of the Propeller, the Propeller II coming
out in the following months which has 96 I/O, 8 cogs, 128K RAM and
160MIPS/core.

BTW, I use Silabs C8051F chips as specialised peripherals (ADC etc) that
hang off the "I2C bus" from the Propeller and I can load new firmware
into each chip using just one extra line to program them in-circuit.

*peter*

MK

unread,
Jan 13, 2013, 5:26:31 AM1/13/13
to
Had a quick look (again) - it's not very fast and it's not very cheap
(compared with a CortexM4 clocked at 150MHz or more). Then there is all
the pain of programming and synching multiple cores which is (I think)
worse than the pain of managing DMA on a typical M4 based micro-controller.
For some applications I'm sure it's a really good fit but I haven't hit
one yet. It's similar in concept to XMOS and Greenchip offerings but
like them suffers from a less than first rank supplier which would worry
most of my customers.

MK


Peter Jakacki

unread,
Jan 13, 2013, 7:22:03 AM1/13/13
to
Since I've had a lot of experience with the Propeller and ARMs and I'm
familiar with M4s (still pushing out a design) then I can say that unless
you actually sit down with it for an hour or two that you will probably
continue to have this misconceptions. Is that the way that the Propeller
comes across? I've always wondered about that.

No, your idea of the Propeller is so off the mark, I'm saying that not to
offend, just setting the record straight although I appreciate the honest
opinion as this gives me something to work on in explaining what it is
and what it is not.

First off, don't try to compare this with an XMOS or GreenArrays (I think
you mean) as they are very different. No, the Propeller is more like 8
identical 32-bit CPUs + counter and video hardware and 512 longs of RAM
each sharing all 32 I/O in common and coupled to a multi-port 32kB RAM
(hub). Sounds strange? Okay, but the eight cogs are not really utilised
for "parallel processing" but think of each cog as either a CPU or a
virtual peripheral or both. The way it's used is that you might setup one
cog as an intelligent quad port UART, another as the VGA cog, another as
keyboard and mouse etc while maybe only one cog is processing the
application. When you see it in action it is very simple to program even
for a beginner.

Seeing that each cog only has 512 longs of RAM which it directly
addresses both source and destination in each 32-bit instruction, it
becomes necessary then to run a virtual machine for high level
application code. This is what Spin does as it compiles bytecode in hub
RAM while one or more cogs may have the Spin interpreter loaded. My
Tachyon Forth does something similar but has a much faster runtime speed
and of course the target hosts a Forth development and runtime system. So
I use bytecode that directly addresses the code in the first 256 longs of
the Tachyon VM. Each cog runs at a maximum of 2.5M Forth bytecode
instructions/second and since there are no interrupts!! nor any need for
them then each cog runs unencumbered. Realtime software development and
testing has never been easier.

Hopefully I've put it in some kind of nutshell. What do you think?
Weird? Yes, but it works really well :)

*peter*




Peter Jakacki

unread,
Jan 13, 2013, 7:44:03 AM1/13/13
to
On Sun, 13 Jan 2013 10:26:31 +0000, MK wrote:

Almost forgot, as for "first rank supplier" I can only say that all the
big companies are the ones that let you down because they upgrade and
suddenly the chip you are using is no longer current and may become hard
to get and of course expensive. Parallax have supported the little guy
just as well as the big and they have a track record of continuing to
support their product (in many ways) over the years with assurances as
well. How many companies these days are willing to make their chips
available in DIP as well as SMD simply for "that" market?

I have STM32F4 designs I'm working on mainly for Ethernet, as well as
other vendor's ARMs and while the chips are impressive you can't really
compare their raw speed with what the Propeller does and how it does it.

Price is relative too but 8 bucks for eight 32-bit fully utilisable cores
is very good value but the price goes down to under $4.50 in volume.

*peter*

Andrew Haley

unread,
Jan 13, 2013, 8:24:35 AM1/13/13
to
In comp.lang.forth Peter Jakacki <peterj...@gmail.com> wrote:

> I use bytecode that directly addresses the code in the first 256
> longs of the Tachyon VM. Each cog runs at a maximum of 2.5M Forth
> bytecode instructions/second and since there are no interrupts!! nor
> any need for them then each cog runs unencumbered. Realtime software
> development and testing has never been easier.
>
> Hopefully I've put it in some kind of nutshell. What do you think?
> Weird? Yes, but it works really well :)

I think this looks really good. Fast and simple multi-tasking with
even less overhead than the simplest Forth scheduler. Extremely low
latency. Cheap, simple. I'm sorry I didn't hear about this years
ago.

Andrew.

Peter Jakacki

unread,
Jan 13, 2013, 8:55:22 AM1/13/13
to
Yes, when you run a task in a cog then that is all it has to do. There is
no need for task switching or interrupts etc. Some of my biggest
headaches had to do with mysterious glitches which always end up being
traced back to the wrong interrupts at the wrong time, but only
sometimes, just to make it harder to find.

The P2 which is due to be released soon allows each cog to run up to 4
tasks with zero switching overhead, you can even set the switching
priority patterns in a 32-bit mask. But P2 runs 8 times faster than P1
just in terms of IPS alone without taking in account the many
enhancements. Although the P2 has not yet been released there are many of
us testing code for this on FPGA boards such as the DE2-115 or Nanos
because Parallax made the FPGA binary for the P2 openly available. Can
you beat that? Never ever heard of any chip company doing anything even
close to that.

*peter*

Marcel Hendrix

unread,
Jan 13, 2013, 10:13:19 AM1/13/13
to
Peter Jakacki <peterj...@gmail.com> writes Re: Parallax Propeller

> On Sun, 13 Jan 2013 07:24:35 -0600, Andrew Haley wrote:
[..]
>> I think this looks really good. Fast and simple multi-tasking with even
>> less overhead than the simplest Forth scheduler. Extremely low latency.
>> Cheap, simple. I'm sorry I didn't hear about this years ago.
[..]
> The P2 which is due to be released soon allows each cog to run up to 4
> tasks with zero switching overhead, you can even set the switching
> priority patterns in a 32-bit mask. But P2 runs 8 times faster than P1
> just in terms of IPS alone without taking in account the many
> enhancements. Although the P2 has not yet been released there are many of
> us testing code for this on FPGA boards such as the DE2-115 or Nanos
> because Parallax made the FPGA binary for the P2 openly available. Can
> you beat that? Never ever heard of any chip company doing anything even
> close to that.

Let me say that I too think this chip seems to be really nice! Indeed
strange it didn't get a larger following from the Forth crowd. The YouTube
videos show it's not a toy and that impressive things can be done.

I had not enough time to delve through your tuts and the forum in depth,
so maybe you are willing to answer a few quick questions?

The stack depth seems to be limited to a very low value (12?). Is this
the Forth implementation, or is a limitation of the chip? I saw in other
threads on the forum that people talk about a few hundredth stack
positions.

What is a "branch stack?". The loop stack also seems to do something I'm
not familiar with.

The memory (512 longs?) seems to be seriously limited. What is the idea
here? You have eight 32-bit high-speed processors but no RAM to match?
Is this the case for the P2 too? (Hardware details are certainly well
hidden :-)

-marcel


Albert van der Horst

unread,
Jan 13, 2013, 11:24:45 AM1/13/13
to
In article <LFxIs.2582$Ow3...@viwinnwfe02.internal.bigpond.com>,
Peter Jakacki <peterj...@gmail.com> wrote:
>On Sun, 13 Jan 2013 10:26:31 +0000, MK wrote:
>
>> On 13/01/2013 06:37, Peter Jakacki wrote:
<SNIP>

>
>
>Seeing that each cog only has 512 longs of RAM which it directly
>addresses both source and destination in each 32-bit instruction, it
>becomes necessary then to run a virtual machine for high level
>application code. This is what Spin does as it compiles bytecode in hub
>RAM while one or more cogs may have the Spin interpreter loaded. My
>Tachyon Forth does something similar but has a much faster runtime speed
>and of course the target hosts a Forth development and runtime system. So
>I use bytecode that directly addresses the code in the first 256 longs of
>the Tachyon VM. Each cog runs at a maximum of 2.5M Forth bytecode
>instructions/second and since there are no interrupts!! nor any need for
>them then each cog runs unencumbered. Realtime software development and
>testing has never been easier.
>
>Hopefully I've put it in some kind of nutshell. What do you think?
>Weird? Yes, but it works really well :)

It sounds like GA144 done properly.

>
>*peter*
>
>
>
>
--
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

David Brown

unread,
Jan 14, 2013, 4:51:39 AM1/14/13
to
I don't know about GreenArrays, but this sounds very much like XMOS
devices. There are differences in the details, and the main languages
for the XMOS are C, C++ and XC (sort of C with a few bits removed, and
some parallel processing and XMOS features added) rather than Forth.
But it's the same idea - you have multiple CPUs so that you can make
your peripherals in software in a CPU rather than as dedicated hardware.

And I'd imagine it is similarly "easy" to work with - some things /will/
be easy, but other things will be a lot harder in practice. In
particular, 8 cores/threads sounds great when you start, and you can
write very elegant UARTs, flashing lights, etc. But in the real
application you need more than 8 cores, and you start having to combine
tasks within a single core/thread and the elegance, clarity, and ease of
development go out the window. The other big problem is the small
memories - you start off thinking how cool these devices are that are so
fast you can make USB or Ethernet peripherals in software cores, using
ready-made "software components" from the company's website. But then
you discover that to actually /use/ them for something more than a
flashing lights demo takes more ram than the chips have.


So it's a nice idea for some types of problem - but it is not unique,
and it is only really good for a small number of applications.

Rafael Deliano

unread,
Jan 15, 2013, 3:10:08 PM1/15/13
to
> you will probably
> continue to have this misconceptions. Is that the way that the Propeller
> comes across? I've always wondered about that.

Un unusal/non-mainstream architecture will always be
initally misjudged.

But some of the misconceptions are due to Parallax:
if it has a smallish videogenerator then its probably
a retro arcade game machine chip ?
While the spin language is usable, there
is nothing people like less then learning new weird
languages.
(
http://www.parallax.com/portals/0/propellerqna/Content/QnaTopics/QnaSpin.htm
"Spin was inspired by portions of C, Delphi, and Python,
and a host of problem/solution scenarios ..." )
It could have easily been an extended BASIC or FORTH.

There are issues in implementation:
The upper half of the 64k byte memorymap is a 32kbyte ROM
that contains the small 4k byte spin interpreter. That
ROM is rather underutilized with data tables.
This spin interpreter firmware is encrypted
http://propeller.wikispaces.com/Cracking+Open+the+Propeller+-+Original+Page
Which makes implementing other languages ontop
of it certainly much fun.
Not much copy protection for the user
as the chip boots the application from an external
serial EEPROM to its internal SRAM.

There are issues in the basic concept:
The round-robin access doesn´t scale very well.
If you go from 8 to 16 cores, the clock has to double
otherwise speed is down. So a 100 pin chip
can hardly have 64 cores.
One can think of COG-RAM to HUB-RAM as an analogy
to the zero-page of an old 6502. But the speed penalty
is much worse: 4 clocks for COG versus 8...23 for HUB.
Identical cores are one-size-fits-all. The propeller
may be flexible and fast concerning I/O, bit banging.
But an I/O core that interprets bytecode is probably no
match for even the smallest ARM in executing high level
language.

MfG JRD

Peter Jakacki

unread,
Jan 16, 2013, 1:06:00 AM1/16/13
to
On Mon, 14 Jan 2013 10:51:39 +0100, David Brown wrote:


> I don't know about GreenArrays, but this sounds very much like XMOS
> devices. There are differences in the details, and the main languages
> for the XMOS are C, C++ and XC (sort of C with a few bits removed, and
> some parallel processing and XMOS features added) rather than Forth. But
> it's the same idea - you have multiple CPUs so that you can make your
> peripherals in software in a CPU rather than as dedicated hardware.
>
> And I'd imagine it is similarly "easy" to work with - some things /will/
> be easy, but other things will be a lot harder in practice. In
> particular, 8 cores/threads sounds great when you start, and you can
> write very elegant UARTs, flashing lights, etc. But in the real
> application you need more than 8 cores, and you start having to combine
> tasks within a single core/thread and the elegance, clarity, and ease of
> development go out the window. The other big problem is the small
> memories - you start off thinking how cool these devices are that are so
> fast you can make USB or Ethernet peripherals in software cores, using
> ready-made "software components" from the company's website. But then
> you discover that to actually /use/ them for something more than a
> flashing lights demo takes more ram than the chips have.
>
>
> So it's a nice idea for some types of problem - but it is not unique,
> and it is only really good for a small number of applications.
>
>

Well it seems that unless you try it you can't really judge it, that's
for sure and in trying to judge it everyone is way off the mark. In terms
of critique of your critique I would have to give you a very poor mark
though. To mention flashing lights followed by "etc" is indicative of an
early negative response and a attempt at minimalizing, as if you were
Bill Gates talking about Linux. As for real applications I am always
producing real commercial products with this chip so I think I know
(actually, I do know) what goes into real apps having worked with a very
wide variety of small to large micros through the decades (and still do).

Having read the rest of your comments I can't see where your fascination
for flashing lights is coming from but I hope you are cured soon :)

BTW, the Propeller does very nice blinking lights along with simultaneous
VGA and graphics rendering along with audio and SD, HID etc while still
handling critical I/O in real deterministic time. The language and tools
were the easiest to learn and use of any processor I've worked with.

Can't you see I'm not trying to sell them, I just didn't want to keep on
being selfish keeping this good thing all to myself and the secret
Propeller "Illuminati".


*peter*


Peter Jakacki

unread,
Jan 16, 2013, 1:26:14 AM1/16/13
to
Round-robin access doesn't have to scale, it is what it is and trying to
judge it based on how it might operate as it is but with 64 cores is
weird!! Just judge it as it is. Besides, the successor chip still has 8
cores but allows 8 longs to be accessed in one "round-robin" cycle. The
fixed round-robin access provides a guaranteed access time for cogs which
might otherwise have been upset by some resource crazed object.

The smallest or largest ARM has to handle more than one task plus
interrupts etc so it never ever achieves it's full speed. If everything
fits in 512 longs of a very code efficient cog then it is very fast but
even more so because it's not bogged down like an ARM. I can't write any
ARM code that doesn't have to do everything including washing the dishes
but the ARM does have a large code space without a doubt. The high level
code rarely needs to run fast though, it's all the low-level stuff that
needs priority which on an ARM requires some complex interrupt processing
to hopefully service that special interrupt in time. No such problem ever
with the Propeller though.

When I first developed code for the ARM it was on the LPC2148 which I
ended up entering into the Philips/NXP 2005 ARM design contest as the
"noPC" with which I was bit-banging VGA graphics under interrupts along
with SD access, audio generation, PS/2 keyboard & mouse as well as serial
etc. That was a lot of hard work on the ARM and left very little
processing time left for the application but doing the same thing on a
Propeller chip is better, easier, and faster.

Perhaps you have been Googling and clicking on some very old links but
the Spin interpreter source code etc is openly available and has been for
years although I don't know why whether it's encrypted or not should have
been worthy of any kind of mention.

Higher-end CPU users and those who require secured firmware should take a
look at the forthcoming Propeller 2 due out sometime in the next few
months or so.

*peter*

Andrew Haley

unread,
Jan 16, 2013, 7:23:58 AM1/16/13
to
Marcel Hendrix <m...@iae.nl> wrote:
> Let me say that I too think this chip seems to be really nice! Indeed
> strange it didn't get a larger following from the Forth crowd. The YouTube
> videos show it's not a toy and that impressive things can be done.
>
> I had not enough time to delve through your tuts and the forum in depth,
> so maybe you are willing to answer a few quick questions?
>
> The stack depth seems to be limited to a very low value (12?). Is this
> the Forth implementation, or is a limitation of the chip? I saw in other
> threads on the forum that people talk about a few hundredth stack
> positions.
>
> What is a "branch stack?". The loop stack also seems to do something I'm
> not familiar with.

There is no real indirect addressing into cog memory. So, to push
onto the stack, you do this:

_PUSHACC mov X,ACC ' Accumulator operation used for fast constants
_PUSHX mov ACC,#0 ' clear it for next operation
_PUSHX1 mov tos+11,tos+10
mov tos+10,tos+9
mov tos+9,tos+8
mov tos+8,tos+7
mov tos+7,tos+6
mov tos+6,tos+5
mov tos+5,tos+4
mov tos+4,tos+3
mov tos+3,tos+2
mov tos+2,tos+1
mov tos+1,tos
mov tos,X ' replace tos with X (DEFAULT)
_PUSHACC_ret
_PUSHX_ret ret

... which sucks mightily, but rejoice! Propeller 2 has IND registers
that allow indirect register access. The manual is a bit vague about
how they work, but I have high hopes they'll allow a stack to be
created.

> The memory (512 longs?) seems to be seriously limited. What is the idea
> here? You have eight 32-bit high-speed processors but no RAM to match?

512 longs *per cog* plus 32k at the hub.

Andrew.

David Brown

unread,
Jan 16, 2013, 7:43:10 AM1/16/13
to
I have worked with XMOS chips - but I never claimed to have used the
Parallax (or GreenArray). I have just read some of the information from
the web site, and considered possible applications and problems based on
my XMOS experience - since the XMOS and the Parallax have a similar
philosophy.

I have no doubt that you can do lots of fun things with a Parallax - and
I have no doubt that you can do commercial projects with it. But I also
have no doubt that 8 cores/threads is far too few to be able to dedicate
a core to each task in non-trivial real world applications. And when
you have to multiplex tasks within each core/thread, you have lost much
of the elegance that you had by using the multi-core system.

>
> Having read the rest of your comments I can't see where your fascination
> for flashing lights is coming from but I hope you are cured soon :)
>

Did you not know that every electronics card needs a flashing light, so
that customers will know that it is working?

Seriously, it was obviously just a reference to test or demo software
rather than fully functional software.

> BTW, the Propeller does very nice blinking lights along with simultaneous
> VGA and graphics rendering along with audio and SD, HID etc while still
> handling critical I/O in real deterministic time. The language and tools
> were the easiest to learn and use of any processor I've worked with.
>
> Can't you see I'm not trying to sell them, I just didn't want to keep on
> being selfish keeping this good thing all to myself and the secret
> Propeller "Illuminati".

That's fine - and I am not trying to be critical to the devices (or your
work). I am just pointing out a few realities about the devices, such
as their similarities to the XMOS and limitations that I think users
will quickly encounter. They look like an interesting architecture -
and I am always a fan of considering new architectures and languages -
but I am not convinced that they are a great idea for general use.

>
>
> *peter*
>
>

Peter Jakacki

unread,
Jan 16, 2013, 10:01:03 AM1/16/13
to
The brute force move looks slow but when you realise that operations on
the stack are greatly simplified, that is they are fast and compact, then
the benefits of this approach start to make sense. You may see elsewhere
that the return stack uses a different method with self-modifying code to
keep track of next position but none of the elements are directly
addressable as they are on the parameter stack.

There is no reason why we can't have more than two stacks in Forth
especially considering that the return stack normally gets loop
parameters and other stuff shoved onto it when this could lead to crashes
if this stack has "junk" on it when Forth exits from a word. So I tend to
use a LOOP stack to hold the stack index and limits plus in Tachyon I
introduced the BRANCH stack which holds the backward branch address of
loops rather than having to read these from slow hub RAM each time and
calculating the branch.

Normally DO and LOOP etc are immediate words which compile the runtime
primitives and branch address but in Tachyon these words are not
immediate and are compiled as is. At runtime DO pushes the loop
parameters onto the LOOP stack and also the next program address onto the
BRANCH stack. When LOOP is executed it runs as normal but instead of
reading the following program location for a branch back to the start of
the loop it instead loads the top of the BRANCH stack into the IP. Since
it's all in cog RAM it is very fast.

My Introduction to Tachyon Forth explains a lot of this kind of stuff
and along with short tutorials also shows you how you can create a WAV
player that reads directly from the SD card without requiring any buffers
or variables and only takes up 65 bytes of program RAM.

However the P2 has many enhancements including a 256 long stack per cog.
Here's a link to the unofficial document I started up for this chip.
http://goo.gl/SEi9h

*peter*

Andrew Haley

unread,
Jan 16, 2013, 10:12:24 AM1/16/13
to
Peter Jakacki <peterj...@gmail.com> wrote:
> The brute force move looks slow but when you realise that operations
> on the stack are greatly simplified, that is they are fast and
> compact, then the benefits of this approach start to make sense. You
> may see elsewhere that the return stack uses a different method with
> self-modifying code to keep track of next position but none of the
> elements are directly addressable as they are on the parameter
> stack.
>
> There is no reason why we can't have more than two stacks in Forth
> especially considering that the return stack normally gets loop
> parameters and other stuff shoved onto it when this could lead to crashes
> if this stack has "junk" on it when Forth exits from a word.

Yeah, but you must realize that many of us in c.l.f. have been using
Forth for a long time and stopped worrying about that a week or two
after we started. It really isn't a problem.

> However the P2 has many enhancements including a 256 long stack per cog.

Much better.

Andrew.

Peter Jakacki

unread,
Jan 16, 2013, 10:27:06 AM1/16/13
to
On Wed, 16 Jan 2013 13:43:10 +0100, David Brown wrote:
>
> I have worked with XMOS chips - but I never claimed to have used the
> Parallax (or GreenArray). I have just read some of the information from
> the web site, and considered possible applications and problems based on
> my XMOS experience - since the XMOS and the Parallax have a similar
> philosophy.
>
> I have no doubt that you can do lots of fun things with a Parallax - and
> I have no doubt that you can do commercial projects with it. But I also
> have no doubt that 8 cores/threads is far too few to be able to dedicate
> a core to each task in non-trivial real world applications. And when
> you have to multiplex tasks within each core/thread, you have lost much
> of the elegance that you had by using the multi-core system.
>
> Did you not know that every electronics card needs a flashing light, so
> that customers will know that it is working?
>
> Seriously, it was obviously just a reference to test or demo software
> rather than fully functional software.
>
>
> That's fine - and I am not trying to be critical to the devices (or your
> work). I am just pointing out a few realities about the devices, such
> as their similarities to the XMOS and limitations that I think users
> will quickly encounter. They look like an interesting architecture -
> and I am always a fan of considering new architectures and languages -
> but I am not convinced that they are a great idea for general use.

From what I know about XMOS and also from those who work with the chip it
is quite a different beast from the Propeller. The Propeller appears to
be a simpler and easier to use chip and it's eight cogs are eight CPUs,
not tasks.

Indeed I know that every pcb needs a flashing light!! How is it that
there are so many designs out there that do not have such a rudimentary
indicator just to tell you that there is power and activity/status. But
indicators do not require the resources of a whole CPU and normally I run
these directly from code positions or even from a more general-purpose
timer "task" which looks after multiple timeouts and actions including
low priority polling.

Not sure what you are getting at by referring to "non-trivial" real world
applications :) How non-trivial is this? Are all the real-time industrial
control functions, communications and network protocols (wired, RF, and SM
fibre), H-bridge motor and microstepping control, graphic display and
input processing, SD file systems etc trivial? Okay, if so then I think
you might be thinking that just because the Propeller has eight cores
that it is some kind of parallel processing "beastie" but it's actually
classed as a "microcontroller", not a PC killer.

*peter*





Peter Jakacki

unread,
Jan 16, 2013, 10:36:51 AM1/16/13
to
On Wed, 16 Jan 2013 09:12:24 -0600, Andrew Haley wrote:

>
> Yeah, but you must realize that many of us in c.l.f. have been using
> Forth for a long time and stopped worrying about that a week or two
> after we started. It really isn't a problem.
>
> Andrew.

So you have no need to index I,J,K etc from a outside the loop? I have
applications where it makes a lot of sense to refer to loop parameters
from outside but there is no easy way to do so when you have return
addresses and loop parameters plus whatever else intermixed. There is no
good reason to leave Forth this way just because it was that way many
decades ago. Anyway, this loop stack permits direct addressing of the
multiple levels of loop parameters and in the case of the Propeller 1 is
conducive to faster loop execution speed and more compact kernel assembly
code.

*peter*


Andrew Haley

unread,
Jan 16, 2013, 11:59:05 AM1/16/13
to
Peter Jakacki <peterj...@gmail.com> wrote:
> On Wed, 16 Jan 2013 09:12:24 -0600, Andrew Haley wrote:
>
>>
>> Yeah, but you must realize that many of us in c.l.f. have been using
>> Forth for a long time and stopped worrying about that a week or two
>> after we started. It really isn't a problem.
>
> So you have no need to index I,J,K etc from a outside the loop?

No, that's poor Forth style. It tends to indicate unfactored code:
Forth isn't about multiply-nested conditionals. This thing tends to
happen to people who have come to Forth from other programming
languages and don't yet quite Get It.

> I have applications where it makes a lot of sense to refer to loop
> parameters from outside but there is no easy way to do so when you
> have return addresses and loop parameters plus whatever else
> intermixed.

I doubt it, to be honest. Conventionally, all arguments to a word are
passed on the data stack, so that word can be executed from anywhere.
It doesn't have to be executed from a word that just happens to have
loops in the right place. It can be tested from the interpreter.
This is the essence of Forth reuse: each word is a factor, and all
arguments are on the stack.

> There is no good reason to leave Forth this way just because it was
> that way many decades ago.

IMO, as you see from my response above, it's that way because it's the
right way to do it.

> Anyway, this loop stack permits direct addressing of the multiple
> levels of loop parameters and in the case of the Propeller 1 is
> conducive to faster loop execution speed and more compact kernel
> assembly code.

Fair enough.

Andrew.

rickman

unread,
Jan 16, 2013, 6:09:20 PM1/16/13
to
On 1/16/2013 10:01 AM, Peter Jakacki wrote:
>
> There is no reason why we can't have more than two stacks in Forth
> especially considering that the return stack normally gets loop
> parameters and other stuff shoved onto it when this could lead to crashes
> if this stack has "junk" on it when Forth exits from a word. So I tend to
> use a LOOP stack to hold the stack index and limits plus in Tachyon I
> introduced the BRANCH stack which holds the backward branch address of
> loops rather than having to read these from slow hub RAM each time and
> calculating the branch.

Using a separate stack for the loop parameters won't prevent bugs in
your programs. If you mismanage any of the stacks you will have a bug.
It may not cause a "crash", but what's the difference? Loops out of
control aren't a lot different from a crash.

I haven't looked at your forth. Just not enough hours in the day...

Rick

Peter Jakacki

unread,
Jan 16, 2013, 6:38:12 PM1/16/13
to
On Wed, 16 Jan 2013 10:59:05 -0600, Andrew Haley wrote:

> Peter Jakacki <peterj...@gmail.com> wrote:
>> On Wed, 16 Jan 2013 09:12:24 -0600, Andrew Haley wrote:
>>
>>
>>> Yeah, but you must realize that many of us in c.l.f. have been using
>>> Forth for a long time and stopped worrying about that a week or two
>>> after we started. It really isn't a problem.
>>
>> So you have no need to index I,J,K etc from a outside the loop?
>
> No, that's poor Forth style. It tends to indicate unfactored code:
> Forth isn't about multiply-nested conditionals. This thing tends to
> happen to people who have come to Forth from other programming languages
> and don't yet quite Get It.
>

I know I don't have a problem with getting it but there seem to be a lot
that don't get any more once they've "got it". Stuck in a loop perhaps?


>> I have applications where it makes a lot of sense to refer to loop
>> parameters from outside but there is no easy way to do so when you have
>> return addresses and loop parameters plus whatever else intermixed.
>
> I doubt it, to be honest. Conventionally, all arguments to a word are
> passed on the data stack, so that word can be executed from anywhere. It
> doesn't have to be executed from a word that just happens to have loops
> in the right place. It can be tested from the interpreter. This is the
> essence of Forth reuse: each word is a factor, and all arguments are on
> the stack.
>


>> There is no good reason to leave Forth this way just because it was
>> that way many decades ago.
>
> IMO, as you see from my response above, it's that way because it's the
> right way to do it.
>
>> Anyway, this loop stack permits direct addressing of the multiple
>> levels of loop parameters and in the case of the Propeller 1 is
>> conducive to faster loop execution speed and more compact kernel
>> assembly code.
>
> Fair enough.
>
> Andrew.

This last reason should be reason enough. Rather than trying to be "the
expert" and beat down someone's rationale for deviations from "pure"
Forth you should look at the end result, does it work and how well does
it do it. As they say "the proof of the pudding is in the eating".

Even Chuck's Forth chips use optimisations such as address registers and
shallow circular stacks etc. For different reasons but in similar ways
the architecture of Tachyon Forth is designed around both the features
and limitations of the Propeller chip. The separate loop stack though is
one I have used in other Forths and allows clear unimpeded access to
return addresses and loop parameters.

*peter*

Andrew Haley

unread,
Jan 17, 2013, 5:04:01 AM1/17/13
to
Peter Jakacki <peterj...@gmail.com> wrote:
> On Wed, 16 Jan 2013 10:59:05 -0600, Andrew Haley wrote:
>
>> Peter Jakacki <peterj...@gmail.com> wrote:
>>> There is no good reason to leave Forth this way just because it was
>>> that way many decades ago.
>>
>> IMO, as you see from my response above, it's that way because it's the
>> right way to do it.
>>
>>> Anyway, this loop stack permits direct addressing of the multiple
>>> levels of loop parameters and in the case of the Propeller 1 is
>>> conducive to faster loop execution speed and more compact kernel
>>> assembly code.
>>
>> Fair enough.
>
> This last reason should be reason enough. Rather than trying to be "the
> expert"

You asked "So you have no need to index I,J,K etc from a outside the
loop?" and I answered "No." I don't really have to try to be "the
expert" because in this case I can justify my opinions. As I did.

> and beat down someone's rationale for deviations from "pure"
> Forth you should look at the end result, does it work and how well does
> it do it. As they say "the proof of the pudding is in the eating".

Well, yes. On really odd targets you sometimes have to do really odd
things. Sometimes it's necessary to cut corners to get the job done
because of a shortage of time or resources. That's engineering.

> Even Chuck's Forth chips use optimisations such as address registers
> and shallow circular stacks etc. For different reasons but in
> similar ways the architecture of Tachyon Forth is designed around
> both the features and limitations of the Propeller chip. The
> separate loop stack though is one I have used in other Forths and
> allows clear unimpeded access to return addresses and loop
> parameters.

I can see that, but the problem here is that stack access is expensive
relative to simple cog memory access: for every push there are a dozen
reads and a dozen writes. From any reasonable engineering viewpoint
this is not good. That you are forced to do so because of the odd
architecture of the propeller Mark 1 is a good enough reason, but this
seems to be fixed with Mark 2.

Andrew.

Mark Wills

unread,
Jan 17, 2013, 7:52:43 AM1/17/13
to
On Jan 16, 3:36 pm, Peter Jakacki <peterjaka...@gmail.com> wrote:
> So you have no need to index I,J,K etc from a outside the loop?

It's quite possible that that need may arise, but if it does, you
don't need to access the loop index outside of the loop as "I" (i.e.
using the word I). Access it inside the loop as I, and pass it to your
out-of-loop word via the stack. That's what the stack is for.

If your architecture is sufficiently different however, such that the
system overall benefits from the extra stack (and it sounds like it
does in your particular case) then overall your decision is probably
justified, though being able to access I,J & K by name outside of a
loop isn't (IMHO) reason enough alone for justifying the extra stack.

I suspect that there is a preference for more stacks among in-
experienced implementers. I've only implemented one Forth system, and
I remember very distinctly being in favour of more stacks, because the
implementation of things like loops, locals etc is perceived to be
simpler. It possibly is. However, I persevered and got the job done
with just the two stacks, and now I kind of wonder what the fuss was
all about! :-)

Ben Bradley

unread,
Jan 18, 2013, 9:07:58 PM1/18/13
to
U=In comp.lang.forth,comp.arch.embedded On Sun, 13 Jan 2013 13:55:22
GMT, Peter Jakacki <peterj...@gmail.com> wrote:


>Yes, when you run a task in a cog then that is all it has to do. There is
>no need for task switching or interrupts etc. Some of my biggest
>headaches had to do with mysterious glitches which always end up being
>traced back to the wrong interrupts at the wrong time, but only
>sometimes, just to make it harder to find.

So you're PREVENTED from using interrupts to make programming
easier.

>
>The P2 which is due to be released soon

... still has zero interrupts.

Yes, I first saw the propellor mentioned years ago, the 8 32-bit cores
thing sounds nice, but no interrupts was a deal killer for me. A year
or two back (with maybe earlier mention of the P2) I looked on the
"official" support/discussion forums for the Propellor and saw this
longish thread on "why doesn't it have interrupts" and there were
posts there that covered every objection I've had or seen to a
microcontroller not having interrupts, even "why not add interrupts?
It would take very little silicon and you don't have to use 'em if you
don't want to." It's against that designer guru guy's religion or
something.

As far as I know there's no other microcontroller that doesn't have
interrupts, and I can't recall one that didn't. The Apple ][ didn't
use interrupts even though the 6502 had them. Maybe there were some
4-bit microprocessors that didn't have any interrupts.

Paul E. Bennett

unread,
Jan 19, 2013, 5:06:24 AM1/19/13
to
Ben Bradley wrote:

> U=In comp.lang.forth,comp.arch.embedded On Sun, 13 Jan 2013 13:55:22
> GMT, Peter Jakacki <peterj...@gmail.com> wrote:

[%X]

>>The P2 which is due to be released soon
>
> ... still has zero interrupts.
>
> Yes, I first saw the propellor mentioned years ago, the 8 32-bit cores
> thing sounds nice, but no interrupts was a deal killer for me. A year
> or two back (with maybe earlier mention of the P2) I looked on the
> "official" support/discussion forums for the Propellor and saw this
> longish thread on "why doesn't it have interrupts" and there were
> posts there that covered every objection I've had or seen to a
> microcontroller not having interrupts, even "why not add interrupts?
> It would take very little silicon and you don't have to use 'em if you
> don't want to." It's against that designer guru guy's religion or
> something.
>
> As far as I know there's no other microcontroller that doesn't have
> interrupts, and I can't recall one that didn't. The Apple ][ didn't
> use interrupts even though the 6502 had them. Maybe there were some
> 4-bit microprocessors that didn't have any interrupts.

One question you should ask yourself is why you think a parallel processor
(particularly the mesh organised ones) really need to include interrupts.
You have many processors, all the same, simple, no frills. You can afford to
dedicate a processor to deal with inputs that need to be responded to
rapidly without the need for interrupts. I know that, to some, it might seem
a waste of a processor, but with heavily parallel chips you could afford to
think about how you allocate I/O around the processor array.

Check back in the history of processors and you will see why the interrupt
was thought to be necessary in the first place. With the world heading to
the much more use of multi-parallel processor I suspect the need for
interrupts will wane.

--
********************************************************************
Paul E. Bennett...............<email://Paul_E....@topmail.co.uk>
Forth based HIDECS Consultancy
Mob: +44 (0)7811-639972
Tel: +44 (0)1235-510979
Going Forth Safely ..... EBA. www.electric-boat-association.org.uk..
********************************************************************

Arlet Ottens

unread,
Jan 19, 2013, 7:04:46 AM1/19/13
to
On 01/19/2013 11:06 AM, Paul E. Bennett wrote:

>> As far as I know there's no other microcontroller that doesn't have
>> interrupts, and I can't recall one that didn't. The Apple ][ didn't
>> use interrupts even though the 6502 had them. Maybe there were some
>> 4-bit microprocessors that didn't have any interrupts.
>
> One question you should ask yourself is why you think a parallel processor
> (particularly the mesh organised ones) really need to include interrupts.
> You have many processors, all the same, simple, no frills. You can afford to
> dedicate a processor to deal with inputs that need to be responded to
> rapidly without the need for interrupts. I know that, to some, it might seem
> a waste of a processor, but with heavily parallel chips you could afford to
> think about how you allocate I/O around the processor array.
>
> Check back in the history of processors and you will see why the interrupt
> was thought to be necessary in the first place. With the world heading to
> the much more use of multi-parallel processor I suspect the need for
> interrupts will wane.

Why not let the end user decide whether interrupts are useful ? Adding
the support is not that complicated, and allows you to have a single
processor performing multiple tasks, and still achieve low latency
response to external events.

If I need a fast and predictable (but very simple) response to an
external event, it is a waste to dedicate an entire processor to the
job. If you don't care about wasting silicon, why not waste some on some
interrupt logic, and offer the best of both worlds ?

A. K.

unread,
Jan 19, 2013, 7:22:21 AM1/19/13
to
On 19.01.2013 11:06, Paul E. Bennett wrote:
> You can afford to
> dedicate a processor to deal with inputs that need to be responded to
> rapidly without the need for interrupts. I know that, to some, it might seem
> a waste of a processor, but with heavily parallel chips you could afford to
> think about how you allocate I/O around the processor array.

While this is true, polling produces heat.
BTW can unused cogs be sent to sleep to reduce power consumption?

Bernd Paysan

unread,
Jan 19, 2013, 7:38:24 AM1/19/13
to
Yes, it's called "waiting". You can wait for one event (counter, IO
port changing polarity):

http://www.parallax.com/portals/0/help/P8X32A/QnaMobile/Advanced/Content/QnaTopics/QnaCogs.htm

About interrupts or not: I've written an interrupt controller for the
b16, but never actually used it. The thing I used was derived from the
interrupt controller, but did only provide a generic wait functionality
- you can wait for whatever set of events you like to, read out the
event mask and decide what to do. That's, because typical
microcontroller programs don't have a "main task", they have several
event-related tasks, which, in an interrupt based system, would all be
interrupt handler code. You don't want nested interrupts, so
essentially, all these short programs would run with interrupts
disabled.

The wait+dispatch in software functionality does the same thing with
less amount of hardware.

--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://bernd-paysan.de/

David Brown

unread,
Jan 19, 2013, 11:12:50 AM1/19/13
to
(Please do not snip newsgroups by using "followup to", unless the post
really is off-topic in a group.)


On 19/01/13 11:06, Paul E. Bennett wrote:
> Ben Bradley wrote:
>
>> U=In comp.lang.forth,comp.arch.embedded On Sun, 13 Jan 2013 13:55:22
>> GMT, Peter Jakacki <peterj...@gmail.com> wrote:
>
> [%X]
>
>>> The P2 which is due to be released soon
>>
>> ... still has zero interrupts.
>>
>> Yes, I first saw the propellor mentioned years ago, the 8 32-bit cores
>> thing sounds nice, but no interrupts was a deal killer for me. A year
>> or two back (with maybe earlier mention of the P2) I looked on the
>> "official" support/discussion forums for the Propellor and saw this
>> longish thread on "why doesn't it have interrupts" and there were
>> posts there that covered every objection I've had or seen to a
>> microcontroller not having interrupts, even "why not add interrupts?
>> It would take very little silicon and you don't have to use 'em if you
>> don't want to." It's against that designer guru guy's religion or
>> something.
>>
>> As far as I know there's no other microcontroller that doesn't have
>> interrupts, and I can't recall one that didn't. The Apple ][ didn't
>> use interrupts even though the 6502 had them. Maybe there were some
>> 4-bit microprocessors that didn't have any interrupts.

Were there not small Microchip PIC devices without interrupts? The
PIC12 series, or something like that (I didn't use them myself).

>
> One question you should ask yourself is why you think a parallel processor
> (particularly the mesh organised ones) really need to include interrupts.
> You have many processors, all the same, simple, no frills. You can afford to
> dedicate a processor to deal with inputs that need to be responded to
> rapidly without the need for interrupts. I know that, to some, it might seem
> a waste of a processor, but with heavily parallel chips you could afford to
> think about how you allocate I/O around the processor array.
>

That argument might have merit /if/ this chip had many processors. It
only has 8. I think the idea of splitting a design into multiple
simple, semi-independent tasks that all work on their own
cpu/core/thread, in their own little worlds, is very elegant. It can
give great modularisation, re-use of software-components, and easy
testing. But you need /many/ more than 8 threads for such a system with
real-world programs - otherwise you have to combine tasks within the
same thread, and you have lost all the elegance.

So then you might have a system with lots more cores - say 64 cores.
Then you have enough to do quite a number of tasks. But to get that
with a realistic price, power and size, these cores will be very simple
and slow - which means that you can't do tasks that require a single
core running quickly.

What makes a lot more sense is to have a cpu that has hardware support
for a RTOS, and is able to switch rapidly between different tasks. That
way demanding tasks can get the cpu time they need, while you can also
have lots of very simple tasks that give you the modularisation in code
without having to dedicate lots of silicon. The XMOS does a bit of
this, in that it has 8 threads per cpu that can run up to 100 MIPS each
(IIRC), but with a total of 500 MIPS per cpu, and it also has
inter-process communication in hardware.


> Check back in the history of processors and you will see why the interrupt
> was thought to be necessary in the first place. With the world heading to
> the much more use of multi-parallel processor I suspect the need for
> interrupts will wane.
>

Look how many interrupts a modern PC or large embedded system has - they
outnumber the number of cores by 50 to 1 at least. Interrupts are not
going away.

Albert van der Horst

unread,
Jan 19, 2013, 11:45:21 AM1/19/13
to
In article <tZidnZg9_bafW2fN...@lyse.net>,
David Brown <david...@removethis.hesbynett.no> wrote:
>
>Look how many interrupts a modern PC or large embedded system has - they
>outnumber the number of cores by 50 to 1 at least. Interrupts are not
>going away.

A modern CPU has 10 cores. So you say that they have far more than
500 interrupts. An Intel with an interrupt vector table of 500?
The largest IRQ I have seen fiddling in the BIOS startup screen is
12. I may look at this the wrong way, but 500+ seems excessive.

Groetjes Albert

George Neuner

unread,
Jan 19, 2013, 12:29:17 PM1/19/13
to
On Fri, 18 Jan 2013 21:07:58 -0500, Ben Bradley
<ben_u_...@etcmail.com> wrote:

>... I first saw the propellor mentioned years ago, the 8 32-bit cores
>thing sounds nice, but no interrupts was a deal killer for me. A year
>or two back (with maybe earlier mention of the P2) I looked on the
>"official" support/discussion forums for the Propellor and saw this
>longish thread on "why doesn't it have interrupts" and there were
>posts there that covered every objection I've had or seen to a
>microcontroller not having interrupts, even "why not add interrupts?
>It would take very little silicon and you don't have to use 'em if you
>don't want to." It's against that designer guru guy's religion or
>something.

There has been much discussions in comp.arch re: this very question.
The consensus has been that interrupts are extremely difficult to
implement properly (in the hardware and/or microcode), and most chips
don't do it right, leading to the occasional unavoidable glitch even
when handler code is written correctly per the CPU documentation.

There also has been much discussion of non-interrupting systems where
cores can be devoted to device handling. The consensus there is that
interrupts per se are not necessary, but such systems still require
inter-processor signaling. There has been considerable debate about
the form(s) such signaling should take.

George

Paul Rubin

unread,
Jan 19, 2013, 1:42:36 PM1/19/13
to
Ben Bradley <ben_u_...@etcmail.com> writes:
> As far as I know there's no other microcontroller that doesn't have
> interrupts, and I can't recall one that didn't.

The GA144 has no interrupts since you just dedicate a processor to
the event you want to listen for. The processors have i/o ports
(to external pins or to adjacent processors on the chip) that block
on read, so the processor doesn't burn power while waiting for data.

upsid...@downunder.com

unread,
Jan 19, 2013, 1:54:22 PM1/19/13
to
On Sat, 19 Jan 2013 17:12:50 +0100, David Brown
<david...@removethis.hesbynett.no> wrote:

>
>> Check back in the history of processors and you will see why the interrupt
>> was thought to be necessary in the first place. With the world heading to
>> the much more use of multi-parallel processor I suspect the need for
>> interrupts will wane.
>>
>
>Look how many interrupts a modern PC or large embedded system has - they
>outnumber the number of cores by 50 to 1 at least. Interrupts are not
>going away.

With only 10-50 cores, you still would have to put multiple threads on
each core. I wonder for you could make a pre-emptive kernel without
interrupts ? You would end up into some ugly Win 3.x style
co-operative kernel. At least you would need to have some kind of
timer interrupt to handle runaway threads.

Paul Rubin

unread,
Jan 19, 2013, 2:04:36 PM1/19/13
to
upsid...@downunder.com writes:
> With only 10-50 cores, you still would have to put multiple threads on
> each core. I wonder for you could make a pre-emptive kernel without
> interrupts?

I think we are talking about an embedded microcontroller connected to
a few sensors and pushbuttons or something like that. Not a workstation
or internet server. 8 tasks are probably plenty for many things.

Les Cargill

unread,
Jan 19, 2013, 3:18:44 PM1/19/13
to
You can still design them as if they were in their own thread and
run them in "series". The now-old CASE tool ObjecTime had a separate
set of screen widgets for organizing separate "executables" into
threads.

In non-case-tool systems, you simply run them one after the other.
This can be round-robin or through a more sophisticated arrangement.

> So then you might have a system with lots more cores - say 64 cores.
> Then you have enough to do quite a number of tasks. But to get that
> with a realistic price, power and size, these cores will be very simple
> and slow - which means that you can't do tasks that require a single
> core running quickly.
>
> What makes a lot more sense is to have a cpu that has hardware support
> for a RTOS, and is able to switch rapidly between different tasks.

An RTOS can also be a purely software object. Do mean essentially
register bank switching?

> That
> way demanding tasks can get the cpu time they need, while you can also
> have lots of very simple tasks that give you the modularisation in code
> without having to dedicate lots of silicon. The XMOS does a bit of
> this, in that it has 8 threads per cpu that can run up to 100 MIPS each
> (IIRC), but with a total of 500 MIPS per cpu, and it also has
> inter-process communication in hardware.
>
>

Shared memory has been around since System V, so...

>> Check back in the history of processors and you will see why the
>> interrupt
>> was thought to be necessary in the first place. With the world heading to
>> the much more use of multi-parallel processor I suspect the need for
>> interrupts will wane.
>>
>
> Look how many interrupts a modern PC or large embedded system has - they
> outnumber the number of cores by 50 to 1 at least. Interrupts are not
> going away.
>

--
Les Cargill

Les Cargill

unread,
Jan 19, 2013, 3:23:06 PM1/19/13
to
upsid...@downunder.com wrote:
> On Sat, 19 Jan 2013 17:12:50 +0100, David Brown
> <david...@removethis.hesbynett.no> wrote:
>
>>
>>> Check back in the history of processors and you will see why the interrupt
>>> was thought to be necessary in the first place. With the world heading to
>>> the much more use of multi-parallel processor I suspect the need for
>>> interrupts will wane.
>>>
>>
>> Look how many interrupts a modern PC or large embedded system has - they
>> outnumber the number of cores by 50 to 1 at least. Interrupts are not
>> going away.
>
> With only 10-50 cores, you still would have to put multiple threads on
> each core. I wonder for you could make a pre-emptive kernel without
> interrupts ?


Does it really need to be preemptive?

> You would end up into some ugly Win 3.x style
> co-operative kernel.

There is nothing particularly wrong with cooperative multitasking,
especially for embedded systems.

> At least you would need to have some kind of
> timer interrupt to handle runaway threads.
>

Or you could consider runaway threads to be defects.

--
Les Cargill


upsid...@downunder.com

unread,
Jan 19, 2013, 4:05:48 PM1/19/13
to
When considering that each external connection will need a dedicated
task, there is not many tasks left for the actual application.

Anyway, the I/O task needs to inform the main application that the I/O
operation (such as reading a complete frame from the serial port) has
ended. Of course, the main task could poll some shared memory
location(s) and burning a lot of power doing that.

Some low power "wait for interrupt" style instruction would help
reduce the power consumption, in order to avoid the busy polling
(especially if multiple signal sources needs to be polled).

Alternatively, the main task requesting a service (such as receiving a
frame) needs to send the request to the I/O task and then go to a low
power halt state. Upon completing the I/O task would have to power up
the halted task (hopefully from the same location it was halted and
not from the restart point :-). Things get ugly, if two or more
waiting tasks need to be informed.

b...@bob.com

unread,
Jan 19, 2013, 8:56:01 PM1/19/13
to
I use timer interrupts mainly to have many nice accurate timers.

It makes it so easy. I could use polled timers in main() but really
prefer the ease of an interrupt and if it doesn't require any context
switching, what could be easier ?

boB

Waldek Hebisch

unread,
Jan 19, 2013, 9:03:50 PM1/19/13
to
In comp.arch.embedded Paul E. Bennett <Paul_E....@topmail.co.uk> wrote:
>
> One question you should ask yourself is why you think a parallel processor
> (particularly the mesh organised ones) really need to include interrupts.
> You have many processors, all the same, simple, no frills. You can afford to
> dedicate a processor to deal with inputs that need to be responded to
> rapidly without the need for interrupts. I know that, to some, it might seem
> a waste of a processor, but with heavily parallel chips you could afford to
> think about how you allocate I/O around the processor array.
>

Forget about I/O -- in modern systems I/O devices frequantly
are like a specialized processors. Think about coordination
between different processors -- you need to get some info
from one processor to another ASAP and the info is nonatomic
so just writing it to shared RAM will not do. And you
need intrrupt even in case of atomic info it the target
processor is doing something else at would not look at
the info otherwise.



--
Waldek Hebisch
heb...@math.uni.wroc.pl

Mark Wills

unread,
Jan 20, 2013, 4:05:27 AM1/20/13
to
On Jan 19, 9:05 pm, upsided...@downunder.com wrote:
> Alternatively, the main task requesting a service (such as receiving a
> frame) needs to send the request to the I/O task and then go to a low
> power halt state. Upon completing the I/O task would have to power up
> the halted task (hopefully from the same location it was halted and
> not from the restart point :-). Things get ugly, if two or more
> waiting tasks need to be informed.

I don't 100% agree with that description! If you wrote your code like
that then you end up with code written in a parallel style, but that
executes in a serial (i.e. sequential) way!

It's far better if the task that is waiting for a response from the
serial I/O task goes off and does some other work while it is waiting.
Otherwise what you have in reality is a sequential process written in
a parallel style; in other words, it's far more complicated than it
needs to be.

If there's no other work to do, and you put the main task to sleep,
then it's possible that the overall software 'solution' didn't need to
be parallel in the first place - time to re-think the design and
simplify.

Or, to put it another way, if the 'main-task' has to go to sleep while
the serial task is running, then I would say the software has been
designed "the wrong way around" - the *serial task* is the main task,
and the programmer needs to rotate his perception of the problem he is
trying to solve by 180 degrees! He has it backwards.

Okay, enough pedantry from me!

Arlet Ottens

unread,
Jan 20, 2013, 6:11:46 AM1/20/13
to
On 01/20/2013 10:05 AM, Mark Wills wrote:
> On Jan 19, 9:05 pm, upsided...@downunder.com wrote:
>> Alternatively, the main task requesting a service (such as receiving a
>> frame) needs to send the request to the I/O task and then go to a low
>> power halt state. Upon completing the I/O task would have to power up
>> the halted task (hopefully from the same location it was halted and
>> not from the restart point :-). Things get ugly, if two or more
>> waiting tasks need to be informed.
>
> I don't 100% agree with that description! If you wrote your code like
> that then you end up with code written in a parallel style, but that
> executes in a serial (i.e. sequential) way!
>
> It's far better if the task that is waiting for a response from the
> serial I/O task goes off and does some other work while it is waiting.
> Otherwise what you have in reality is a sequential process written in
> a parallel style; in other words, it's far more complicated than it
> needs to be.

Of course it would be preferable if the tasks could do other work, but
that requires an interrupt mechanism if you want to handle external
events with low and predictable latency.

upsid...@downunder.com

unread,
Jan 20, 2013, 6:26:27 AM1/20/13
to
On Sun, 20 Jan 2013 01:05:27 -0800 (PST), Mark Wills
<markrob...@yahoo.co.uk> wrote:

>On Jan 19, 9:05�pm, upsided...@downunder.com wrote:
>> Alternatively, the main task requesting a service (such as receiving a
>> frame) needs to send the request to the I/O task and then go to a low
>> power halt state. Upon completing the I/O task would have to power up
>> the halted task (hopefully from the same location it was halted and
>> not from the restart point :-). Things get ugly, if two or more
>> waiting tasks need to be informed.
>
>I don't 100% agree with that description! If you wrote your code like
>that then you end up with code written in a parallel style, but that
>executes in a serial (i.e. sequential) way!
>
>It's far better if the task that is waiting for a response from the
>serial I/O task goes off and does some other work while it is waiting.
>Otherwise what you have in reality is a sequential process written in
>a parallel style; in other words, it's far more complicated than it
>needs to be.

While this is true, quite a lot of protocols are essentially
half-duplex request/response protocols (such as Modbus). While for
instance TCP/IP is capable of full-duplex communication, many
protocols built on TCP/IP are essentially half duplex request/response
(such as http). Of course, the I/O core should be programmed to handle
sending the request and assembling the response in true IBM mainframe
I/O processor SNA style :-)

>If there's no other work to do, and you put the main task to sleep,
>then it's possible that the overall software 'solution' didn't need to
>be parallel in the first place - time to re-think the design and
>simplify.

If the main task is doing something useful between issuing the request
and before processing the result, then is the question, _how_ or
_when_ the main task is going to process the I/O response without
interrupts. Of course, the main task could poll the I/O status say
every few hundred microseconds, this would force you to insert those
polls all around your application code, making it hard to maintain.

However, if the I/O-task (core) is polled at some slow application
convenient rate (say 10 ms), the buffering requirements would be quite
large. For a half duplex protocol, any latencies due to polling will
kill the throughput due to the extra latencies (especially at high
signaling rates).

might be a solution in some cases, I have

>Okay, enough pedantry from me!

The original question was about how to use multiple cores (=tasks in
traditional RTOS speak) without interrupts.

While I understand the problem of implementing proper interrupt
processing in current processors with long pipelines and large caches,
I still think that at least some kind of "wait for interrupt"
mechanism (i.e. flushing the pipeline, cache invalidation and going to
low power sleep mode) and some mechanism to reactivate the code by an
external pin or by writing a value to the power up register by some
other core is needed. If you do not want to call this "interrupt",
then it is an other story.

upsid...@downunder.com

unread,
Jan 20, 2013, 6:53:45 AM1/20/13
to
On Sun, 20 Jan 2013 12:11:46 +0100, Arlet Ottens <usen...@c-scape.nl>
wrote:
A system can be implemented in various ways. If the intertask
synchronization and communication is very primitive (e.g. implemented
in hardware only), you easily end up with dozens or even hundreds of
very simple tasks doing a huge number of random communications with
each other, making it hard to manage.

On the other hand, if you are forced to a single task (old style
Unix), you easily end up building some huge select() calls, including
file descriptors from actual files, sockets and serial lines. This
also makes it hard to maintain the system.

There should be some sweet spot between these two extremes. A
sufficiently usable intertask communication systems (typically using
interrupts) should be able to handle this. I prefer 5-10 different
tasks, so my fingers are sufficient to keep track of these, without
having to take my socks off to use my toes for counting the rest :-).

David Brown

unread,
Jan 20, 2013, 11:49:25 AM1/20/13
to
On 19/01/13 17:45, Albert van der Horst wrote:
> In article <tZidnZg9_bafW2fN...@lyse.net>,
> David Brown <david...@removethis.hesbynett.no> wrote:
>>
>> Look how many interrupts a modern PC or large embedded system has - they
>> outnumber the number of cores by 50 to 1 at least. Interrupts are not
>> going away.
>
> A modern CPU has 10 cores. So you say that they have far more than
> 500 interrupts. An Intel with an interrupt vector table of 500?
> The largest IRQ I have seen fiddling in the BIOS startup screen is
> 12. I may look at this the wrong way, but 500+ seems excessive.
>
> Groetjes Albert
>>
>>

The BIOS only shows the IRQ lines available to the original PC, not
those on the "extended" interrupt controller or multiplexed interrupt
sources.

A quick check on my PC shows 36 interrupts in use, with four cores. So
my first guess was a bit of an exaggeration - though I don't know how
many interrupt sources are available. But it is also not hard to find
large microcontrollers with hundreds of interrupt sources and only 1 or
two cores, giving much more than 50 to 1 ratio.

Of course, any given system is unlikely to use more than a small
fraction of the interrupt sources - but even something as simple as a
UART can use three interrupts plus some sort of timer. But it will
still be a lot more than the number of cores.

David Schultz

unread,
Jan 20, 2013, 12:21:31 PM1/20/13
to
On 01/18/2013 08:07 PM, Ben Bradley wrote:
> It's against that designer guru guy's religion or something.

I remember reading an article in Nuts & Volts on the propeller which
discussed the interrupt thing. Digging into the archives...

"There were only a few rules: it had to be fast, it had to be relatively
easy to program, and it had to be able to do multiple tasks without
using interrupts -- the bane of all but the heartiest programmers."
April 2006, page 16.

In other words, interrupts are too hard.

By this standard, I am a hearty programmer.

--
David W. Schultz
http://home.earthlink.net/~david.schultz
Returned for Regrooving


David Brown

unread,
Jan 20, 2013, 2:32:27 PM1/20/13
to
You can certainly do that - but then you don't get the dedication of a
core that lets you get low-latency reactions.

>> So then you might have a system with lots more cores - say 64 cores.
>> Then you have enough to do quite a number of tasks. But to get that
>> with a realistic price, power and size, these cores will be very simple
>> and slow - which means that you can't do tasks that require a single
>> core running quickly.
>>
>> What makes a lot more sense is to have a cpu that has hardware support
>> for a RTOS, and is able to switch rapidly between different tasks.
>
> An RTOS can also be a purely software object. Do mean essentially
> register bank switching?

Bank switching is part of it, but to make a "hardware RTOS" you need a
system to switch tasks (register banks) automatically by task.

>
>> That
>> way demanding tasks can get the cpu time they need, while you can also
>> have lots of very simple tasks that give you the modularisation in code
>> without having to dedicate lots of silicon. The XMOS does a bit of
>> this, in that it has 8 threads per cpu that can run up to 100 MIPS each
>> (IIRC), but with a total of 500 MIPS per cpu, and it also has
>> inter-process communication in hardware.
>>
>>
>
> Shared memory has been around since System V, so...

There is a lot more to inter-process communication than shared memory.
The XMOS implements a message passing system with CSP-style synchronisation.

Walter Banks

unread,
Jan 20, 2013, 5:12:17 PM1/20/13
to
Interrupts are not going away anytime soon.

There are event riven processors that are essentially all interrupts.

Add run to completion (to eliminate preemption overhead) and multiple
cores for interrupts to use the next available execution unit and a lot of
processing overheads go away with comparable reduction in software
complexity.

w..


Les Cargill

unread,
Jan 20, 2013, 7:08:11 PM1/20/13
to
To be sure.

>>> So then you might have a system with lots more cores - say 64 cores.
>>> Then you have enough to do quite a number of tasks. But to get that
>>> with a realistic price, power and size, these cores will be very simple
>>> and slow - which means that you can't do tasks that require a single
>>> core running quickly.
>>>
>>> What makes a lot more sense is to have a cpu that has hardware support
>>> for a RTOS, and is able to switch rapidly between different tasks.
>>
>> An RTOS can also be a purely software object. Do mean essentially
>> register bank switching?
>
> Bank switching is part of it, but to make a "hardware RTOS" you need a
> system to switch tasks (register banks) automatically by task.
>

I presume the code store is shared, so it's matter
of assigning the "task" represented by entry point <x> to
core <y>.

>>
>>> That
>>> way demanding tasks can get the cpu time they need, while you can also
>>> have lots of very simple tasks that give you the modularisation in code
>>> without having to dedicate lots of silicon. The XMOS does a bit of
>>> this, in that it has 8 threads per cpu that can run up to 100 MIPS each
>>> (IIRC), but with a total of 500 MIPS per cpu, and it also has
>>> inter-process communication in hardware.
>>>
>>>
>>
>> Shared memory has been around since System V, so...
>
> There is a lot more to inter-process communication than shared memory.
> The XMOS implements a message passing system with CSP-style
> synchronisation.
>

Very nice indeed, then. CSP is the right abstraction.

>>
>>>> Check back in the history of processors and you will see why the
>>>> interrupt
>>>> was thought to be necessary in the first place. With the world
>>>> heading to
>>>> the much more use of multi-parallel processor I suspect the need for
>>>> interrupts will wane.
>>>>
>>>
>>> Look how many interrupts a modern PC or large embedded system has - they
>>> outnumber the number of cores by 50 to 1 at least. Interrupts are not
>>> going away.
>>>
>>
>

--
Les Cargill

Mel Wilson

unread,
Jan 20, 2013, 7:19:45 PM1/20/13
to
Walter Banks wrote:

> There are event riven processors that are essentially all interrupts.

There are no spelling mistakes. Only unexpected meanings. Not even
unexpected, sometimes.

Mel.

Walter Banks

unread,
Jan 20, 2013, 9:12:49 PM1/20/13
to
:)

w..


David Brown

unread,
Jan 21, 2013, 3:01:17 AM1/21/13
to
On 20/01/13 23:12, Walter Banks wrote:
> Interrupts are not going away anytime soon.
>
> There are event riven processors that are essentially all interrupts.

I have often written programs where the main loop contains nothing but a
"sleep until next interrupt" instruction - it is not uncommon for
low-power systems.

>
> Add run to completion (to eliminate preemption overhead) and multiple
> cores for interrupts to use the next available execution unit and a lot of
> processing overheads go away with comparable reduction in software
> complexity.
>

If you can eliminate all forms of pre-emption, you can keep many things
simpler - there is no need to worry about how you share data or
resources amongst threads, for example. But of course you can no longer
have low-latency reactions to events - you need to make sure these are
handled in hardware.


Walter Banks

unread,
Jan 21, 2013, 9:11:49 PM1/21/13
to
Latency in these systems is reduced in two ways, pre computing responses
delivered on an event (your comment) and multiple execution units so
code is not pre-empted but is immediately executed if there is an available
execution unit.

Hardware arbitrated execution priority levels is also a feature of these
processors

The rest is software design to make sure the response time meets
the application requirements. The resulting code has better average
response time and that can be important as well.


w..



upsid...@downunder.com

unread,
Jan 22, 2013, 2:39:49 AM1/22/13
to
On Sun, 20 Jan 2013 17:12:17 -0500, Walter Banks
<wal...@bytecraft.com> wrote:

>> Look how many interrupts a modern PC or large embedded system has - they
>> outnumber the number of cores by 50 to 1 at least. Interrupts are not
>> going away.
>
>Interrupts are not going away anytime soon.
>
>There are event riven processors that are essentially all interrupts.
>
>Add run to completion (to eliminate preemption overhead) and multiple
>cores for interrupts to use the next available execution unit and a lot of
>processing overheads go away with comparable reduction in software
>complexity.

Of course you could design a core which restarts every time an
external or internal interrupt occurs (such as a request packet sent
by an other core), run to completion and pot core in low power halt
state.

Of course, this works for some problems, but sooner or later you end
up with a hellish state machine, which remembers, where you were when
the previous interrupt occurred.

gavino_himself

unread,
Jan 22, 2013, 9:26:19 AM1/22/13
to
On Sunday, January 13, 2013 4:22:03 AM UTC-8, Peter Jakacki wrote:
> On Sun, 13 Jan 2013 10:26:31 +0000, MK wrote:
>
>
>
> > On 13/01/2013 06:37, Peter Jakacki wrote:
>
> >>
>
> >> For some reason I found myself reading these newsgroups which I haven't
>
> >> really used for many years. It seems that although the Parallax
>
> >> Propeller web forums are extremely active there never seems to be much
>
> >> discussion elsewhere. Aren't you all curious as to what you are missing
>
> >> out on?
>
> >>
>
> >> I have used just about every kind of micro and architecture over the
>
> >> decades and while I might still use some small "one buck" micros for
>
> >> certain tasks and some special ARM chips for higher end tasks I have
>
> >> almost exclusively been using Propeller chips for everything else. The
>
> >> reason is very simple, they are so simple to work with and there are no
>
> >> "peripheral modules" to worry about other than the counters and video
>
> >> hardware per cog. Every pin is general-purpose and any one of the eight
>
> >> 32-bit cores can use them, you don't have to worry about trying to
>
> >> route a special pin or have the dilemma of using the special pin for
>
> >> one function but not the other etc. The 32-bit CPUs or cogs are a
>
> >> breeze to program and you can work with a variety of languages besides
>
> >> the easy to use Spin compiler that comes with it.
>
> >>
>
> >> For you Forth enthusiasts there has been a big flurry of Forth related
>
> >> threads on the Propeller forums of late and there are several versions
>
> >> of Forth including my own Tachyon Forth. IMHO this is the best way to
>
> >> get into the Propeller and it's hardware. I just can't be bother trying
>
> >> to cram functions and debug interrupts on other chips when I can set a
>
> >> cog to work on a task and still have plenty of resources left over
>
> >> including video on-chip.
>
> >>
>
> >> If you are intrigued or just plain curious it won't kill you unless you
>
> >> are a cat to have a look at my introduction page which has links to
>
> >> projects and the forum etc.
>
> >> http://goo.gl/VX7pc
>
> >>
>
> >> There is the sup'ed up version of the Propeller, the Propeller II
>
> >> coming out in the following months which has 96 I/O, 8 cogs, 128K RAM
>
> >> and 160MIPS/core.
>
> >>
>
> >> BTW, I use Silabs C8051F chips as specialised peripherals (ADC etc)
>
> >> that hang off the "I2C bus" from the Propeller and I can load new
>
> >> firmware into each chip using just one extra line to program them
>
> >> in-circuit.
>
> >>
>
> >> *peter*
>
> >>
>
> >>
>
> > Had a quick look (again) - it's not very fast and it's not very cheap
>
> > (compared with a CortexM4 clocked at 150MHz or more). Then there is all
>
> > the pain of programming and synching multiple cores which is (I think)
>
> > worse than the pain of managing DMA on a typical M4 based
>
> > micro-controller.
>
> > For some applications I'm sure it's a really good fit but I haven't hit
>
> > one yet. It's similar in concept to XMOS and Greenchip offerings but
>
> > like them suffers from a less than first rank supplier which would worry
>
> > most of my customers.
>
> >
>
> > MK
>
>
>
> Since I've had a lot of experience with the Propeller and ARMs and I'm
>
> familiar with M4s (still pushing out a design) then I can say that unless
>
> you actually sit down with it for an hour or two that you will probably
>
> continue to have this misconceptions. Is that the way that the Propeller
>
> comes across? I've always wondered about that.
>
>
>
> No, your idea of the Propeller is so off the mark, I'm saying that not to
>
> offend, just setting the record straight although I appreciate the honest
>
> opinion as this gives me something to work on in explaining what it is
>
> and what it is not.
>
>
>
> First off, don't try to compare this with an XMOS or GreenArrays (I think
>
> you mean) as they are very different. No, the Propeller is more like 8
>
> identical 32-bit CPUs + counter and video hardware and 512 longs of RAM
>
> each sharing all 32 I/O in common and coupled to a multi-port 32kB RAM
>
> (hub). Sounds strange? Okay, but the eight cogs are not really utilised
>
> for "parallel processing" but think of each cog as either a CPU or a
>
> virtual peripheral or both. The way it's used is that you might setup one
>
> cog as an intelligent quad port UART, another as the VGA cog, another as
>
> keyboard and mouse etc while maybe only one cog is processing the
>
> application. When you see it in action it is very simple to program even
>
> for a beginner.
>
>
>
> Seeing that each cog only has 512 longs of RAM which it directly
>
> addresses both source and destination in each 32-bit instruction, it
>
> becomes necessary then to run a virtual machine for high level
>
> application code. This is what Spin does as it compiles bytecode in hub
>
> RAM while one or more cogs may have the Spin interpreter loaded. My
>
> Tachyon Forth does something similar but has a much faster runtime speed
>
> and of course the target hosts a Forth development and runtime system. So
>
> I use bytecode that directly addresses the code in the first 256 longs of
>
> the Tachyon VM. Each cog runs at a maximum of 2.5M Forth bytecode
>
> instructions/second and since there are no interrupts!! nor any need for
>
> them then each cog runs unencumbered. Realtime software development and
>
> testing has never been easier.
>
>
>
> Hopefully I've put it in some kind of nutshell. What do you think?
>
> Weird? Yes, but it works really well :)
>
>
>
> *peter*

What kinds of apps have you created with this setup?

Mel Wilson

unread,
Jan 22, 2013, 10:14:06 AM1/22/13
to
upsid...@downunder.com wrote:

> Of course you could design a core which restarts every time an
> external or internal interrupt occurs (such as a request packet sent
> by an other core), run to completion and pot core in low power halt
> state.
>
> Of course, this works for some problems, but sooner or later you end
> up with a hellish state machine, which remembers, where you were when
> the previous interrupt occurred.

It does look as though the AVR TWI interface was designed to be controlled
just that way.

Mel.

rickman

unread,
Jan 23, 2013, 12:29:04 PM1/23/13
to
On 1/19/2013 12:29 PM, George Neuner wrote:
> On Fri, 18 Jan 2013 21:07:58 -0500, Ben Bradley
> <ben_u_...@etcmail.com> wrote:
>
>> ... I first saw the propellor mentioned years ago, the 8 32-bit cores
>> thing sounds nice, but no interrupts was a deal killer for me. A year
>> or two back (with maybe earlier mention of the P2) I looked on the
>> "official" support/discussion forums for the Propellor and saw this
>> longish thread on "why doesn't it have interrupts" and there were
>> posts there that covered every objection I've had or seen to a
>> microcontroller not having interrupts, even "why not add interrupts?
>> It would take very little silicon and you don't have to use 'em if you
>> don't want to." It's against that designer guru guy's religion or
>> something.
>
> There has been much discussions in comp.arch re: this very question.
> The consensus has been that interrupts are extremely difficult to
> implement properly (in the hardware and/or microcode), and most chips
> don't do it right, leading to the occasional unavoidable glitch even
> when handler code is written correctly per the CPU documentation.

How do you define "implement properly" for interrupts? Like most
things, if interrupts are kept simple, they work. It's the multiple
priority, many task processing that is hard to do right.


> There also has been much discussion of non-interrupting systems where
> cores can be devoted to device handling. The consensus there is that
> interrupts per se are not necessary, but such systems still require
> inter-processor signaling. There has been considerable debate about
> the form(s) such signaling should take.

There is always more than one way to skin a cat. I'm not convinced
interrupts are not necessary, well, maybe I should say "not useful"
instead, how's that?

Rick

rickman

unread,
Jan 23, 2013, 12:40:27 PM1/23/13
to
In my opinion, the lack of timers is one of a number of significant
shortcomings in the GA144. One of the claimed selling features of the
device is the low power possible. But if you need to wait for a
specific amount of time, not at all uncommon in real time systems which
many embedded systems are, you have to put a processor into a spin loop
to time it!

If you read Chuck Moore's blog he spent some time trying to implement a
video output without a clock. He only gave up that idea when he found
the pixels jittered on the screen because of the vagaries of async
processor timing loops. Had he implemented a simple timer on each
processor driven by... yes, a global chip clock (Oh! The horror!!!) many
timing events would be so much simpler and likely lower power. 5 mW per
core in a spin loop. It doesn't take many of those to add up to
significant power.

In a recent design I considered for the GA144 I found the CPU core
expended more than half it's power in the spin loop timing the ADC
converter and that was just a 6% duty cycle! This exceeded the power
budget. With an on chip clock the ADC could have been timed at very low
power possibly making the design practical.

Rick

Mark Wills

unread,
Jan 24, 2013, 5:03:32 PM1/24/13
to
On Jan 23, 5:29 pm, rickman <gnu...@gmail.com> wrote:
> On 1/19/2013 12:29 PM, George Neuner wrote:
>
>
>
>
>
>
>
>
>
> > On Fri, 18 Jan 2013 21:07:58 -0500, Ben Bradley
> > <ben_u_brad...@etcmail.com>  wrote:
I'm inclined to agree, though I've only had experience with 'classic'
micro-processors in this regard, so maybe my thoughts on the issue are
simply out of date. I can see that if you have a lot cores you can
effectively make your own interrupt controller by dedicating a core or
more to it. That idea seems to make sense on a simple device like the
GA devices, where each core is very primitive in its own right, so one
can argue that the 'cost' of assigning a core to the task of interrupt
detection is low. However, the idea does not sit well with me when
talking about complex devices such as the Propeller. Dedicating a cog
to interrupt control sounds bonkers to me, especially when a cog has
its own video controller - that's real overkill.

I get the impression that the Propeller is somewhat dumbed-down for
the hobbyist market. I cite its programming language, and the lack of
interrupts as two examples. Why they couldn't they add a 9th super-
simple core just for interrupts, that could pipe certain types of
interrupts to certain cogs? Best of both worlds.

The TMS99xx family of processors (very old) has 16 prioritised
cascading interrupts. Probably inherited from mini-computer
architecture. Very very powerful for its day. Since they were
prioritised, a lower level interrupt would not interrupt a higher
level interrupt until the higher level ISR terminated. Makes serving
multiple interrupts an absolute doddle. Not bad for 1976.

None

unread,
Jan 24, 2013, 6:26:05 PM1/24/13
to
rickman <gnu...@gmail.com> writes:
> If you read Chuck Moore's blog he spent some time trying to implement a
> video output without a clock. He only gave up that idea when he found
> the pixels jittered on the screen because of the vagaries of async
> processor timing loops.

I played with the PropTerm and found that the CPU-generated VGA bit stream (a
CPU got dedicated to the task) resulted in displays which always had a little
bit of fuzziness. It worked, and was quite readable, but the sharpness
of a regular PC display really made me aware of the limits of a pure software
approach to analog generation.

Andy

Hugh Aguilar

unread,
Jan 25, 2013, 1:48:22 AM1/25/13
to
On Jan 16, 8:36 am, Peter Jakacki <peterjaka...@gmail.com> wrote:
> On Wed, 16 Jan 2013 09:12:24 -0600, Andrew Haley wrote:
>
> > Yeah, but you must realize that many of us in c.l.f. have been using
> > Forth for a long time and stopped worrying about that a week or two
> > after we started.  It really isn't a problem.
>
> > Andrew.
>
> So you have no need to index I,J,K etc from a outside the loop? I have
> applications where it makes a lot of sense to refer to loop parameters
> from outside but there is no easy way to do so when you have return
> addresses and loop parameters plus whatever else intermixed. There is no
> good reason to leave Forth this way just because it was that way many
> decades ago. Anyway, this loop stack permits direct addressing of the
> multiple levels of loop parameters and in the case of the Propeller 1 is
> conducive to faster loop execution speed and more compact kernel assembly
> code.
>
> *peter*

I am getting rid of DO loops altogether in Straight Forth. I'm also
getting rid of >R R@ R> etc., or at least deprecating them. I use
BEGIN loops with local variables for iteration. DO loops were invented
in the 1970s, prior to Forth having local variables --- I and J are
just crude implementations of local variables. I think that DO loops
are overly complicated. It is weird to have I and J available only in
the loop and not outside. Also, if you have nested loops, I means one
thing in the outer loop and something else in the inner loop ---
that's confusing. Also, it is very confusing that >R R@ R> etc. can be
used in a colon word, but they can't carry values into the DO loop ---
so they can't really be used as local variables, which is their
intended purpose. DO loops are also anti-intuitive and confusing when
you are descending rather than ascending. All in all, DO loops are an
ugly kludge from the 1970s that can be discarded.

Also, I have separate stacks for single-precision and double-precision
data (and a third stack for floats) --- I don't jumble different types
of data together on the same stack as done in ANS-Forth, which is
another 1970s kludge (jumbling everything together was originally done
due to a shortage of registers and shortage of memory).

BTW --- On the subject of interrupts, the MiniForth didn't have
interrupts --- it just did polling. IIRC, that was in DOCOLON and
BRANCH. There was no branch instruction in the assembly language, so
it was impossible to iterate except in colon words, so it never
happened that any significant time went by without DOCOLON or BRANCH
executing. There may have been something similar to the x86's CMOVcc
instruction --- I can't remember now, as that was almost 20 years ago.
It didn't have conditional flags (sign, zero, carry, etc.) like most
processors do --- the comparison and what happened in response were
hardwired together in the same instruction. That was very low-level
programming!

Hugh Aguilar

unread,
Jan 25, 2013, 1:55:53 AM1/25/13
to
On Jan 24, 3:03 pm, Mark Wills <markrobertwi...@yahoo.co.uk> wrote:
> The TMS99xx family of processors (very old) has 16 prioritised
> cascading interrupts. Probably inherited from mini-computer
> architecture. Very very powerful for its day. Since they were
> prioritised, a lower level interrupt would not interrupt a higher
> level interrupt until the higher level ISR terminated. Makes serving
> multiple interrupts an absolute doddle. Not bad for 1976.

Doddle? I've never heard that word before. Is a doddle good or bad?

Mark Wills

unread,
Jan 25, 2013, 2:03:32 AM1/25/13
to
doddle = extremely simple/easy

"Did you manage to fix that bug?"
"Yeah, it was a doddle!"

:-)

Mark Wills

unread,
Jan 25, 2013, 2:10:53 AM1/25/13
to
On Jan 25, 6:48 am, Hugh Aguilar <hughaguila...@yahoo.com> wrote:
> I am getting rid of DO loops altogether in Straight Forth. I'm also
> getting rid of >R R@ R> etc., or at least deprecating them. I use
> BEGIN loops with local variables for iteration. DO loops were invented
> in the 1970s, prior to Forth having local variables --- I and J are
> just crude implementations of local variables. I think that DO loops
> are overly complicated. It is weird to have I and J available only in
> the loop and not outside. Also, if you have nested loops, I means one
> thing in the outer loop and something else in the inner loop ---
> that's confusing. Also, it is very confusing that >R R@ R> etc. can be
> used in a colon word, but they can't carry values into the DO loop ---
> so they can't really be used as local variables, which is their
> intended purpose. DO loops are also anti-intuitive and confusing when
> you are descending rather than ascending. All in all, DO loops are an
> ugly kludge from the 1970s that can be discarded.

A lot of the problems you cite, which are definately real gotcha's
(though one learns to live with them) evaporate when one uses a
dedicated stack for loop control. Worth considering.

The restrictions/gotcha's are certainly a problem for newbies. If one
has implemented their own Forth system, one knows why these
restriction exist, so they're never really bothered by them, but if
you've come to the languge from some other language, it's going to be
a real issue - the reasons why will not be clear. And of course, one
should not really have to be familiar with the internal workings of a
Forth system in order to use it.

Loops is one area where the 2012 standard could do with some more
work! Why not mandate a flow-control stack. Go on, take the plunge!
You'll be glad you did!

Walter Banks

unread,
Jan 25, 2013, 11:49:53 AM1/25/13
to
I have worked on a couple event driven ISA designs. Jitter is visible
on displays but it is equally problematic with control systems. The best solution

that I have seen/used is to have the hardware transfer out a precomputed
value or latch an input on the event interrupt trigger. Output values are
almost always known in advance.

This minor change has essentially little impact on the processor silicon
complexity.

A second important performance issue is to have an easily accesses data
area associated with each interrupt source. It means that a lot of common
code (pwm, ac phase control... ) can be a single executable. In some cases
preloading an index register with the start of data for that interrupt in some
hardware has significant performance improvements.

Walter Banks
Byte Craft Limited


Coos Haak

unread,
Jan 25, 2013, 2:02:51 PM1/25/13
to
Op Thu, 24 Jan 2013 23:03:32 -0800 (PST) schreef Mark Wills:
As we say: een fluitje van een cent.
A flute of a cent does cost nearly nothing and can be made for nearly
nothing. There is a herb (Anthriscus sylvestris) we call Fluitekruid. Due
to nearly French purism (hash-tag vs. mot-dièse) we must write
Fluitenkruid, as if it were plural.

--
Coos

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

rickman

unread,
Jan 25, 2013, 9:25:49 AM1/25/13
to
How do you know the display "fuzziness" was due to software timing? I
would expect software timing on a clocked processor to be on par with
other means of timing. There are other aspects of design that could
cause fuzziness or timing ambiguities in the signal.

Rick

None

unread,
Jan 25, 2013, 4:57:10 PM1/25/13
to
rickman <gnu...@gmail.com> writes:
> How do you know the display "fuzziness" was due to software timing? I
> would expect software timing on a clocked processor to be on par with
> other means of timing. There are other aspects of design that could
> cause fuzziness or timing ambiguities in the signal.

If you look at the inner loop driving the output pin, you can do a min/max
skew calculation which ends up with quite a bit of jitter on the table.
The product is the PockeTerm, you can pick one up at:

http://www.brielcomputers.com/wordpress/?cat=25

It's open source, VGA_HiRes_Text.spin is the low level driver for
VGA output. Note it actually uses *two* CPUs, and is some pretty darn
cool assembly code--written by the president of the Propeller company!

Andy Valencia
Home page: http://www.vsta.org/andy/
To contact me: http://www.vsta.org/contact/andy.html

rickman

unread,
Jan 26, 2013, 6:07:58 PM1/26/13
to
I don't follow what causes the skew you mention. Instruction timings
are deterministic, no? If not, trying to time using code is hopeless.
If the timings are deterministic, the skew should not be cumulative
since they are all based on the CPU clock. Is the CPU clock from an
accurate oscillator like a crystal? If it is using an internal RC
clock, again timing to sufficient accuracy is hopeless.

Rick

None

unread,
Jan 26, 2013, 10:09:58 PM1/26/13
to
rickman <gnu...@gmail.com> writes:
> I don't follow what causes the skew you mention. Instruction timings
> are deterministic, no?

The chip has a lower level bit stream engine which the higher level CPU
("cog") is feeding. Well, a pair of cogs. Each cog has local memory
and then a really expensive path through a central arbiter ("hub"). It
fills its image of the scanlines from the shared memory, then has to
feed it via waitvid into the lower level. Note that it's bit stream
engine *per cog*, so you also have to worry about their sync.

So yes, instruction timings are deterministic (although your shared
memory accesses will vary modulo the hub round-robin count). You
need to reach the waitvid before it's your turn to supply the next value.
But given that, this is much like the old wait state sync feeding bytes
to a floppy controller. PLL and waitvid sync are achieved with
magic incantations from Parallax, and it is not 100%.

> If the timings are deterministic, the skew should not be cumulative
> since they are all based on the CPU clock. Is the CPU clock from an
> accurate oscillator like a crystal? If it is using an internal RC
> clock, again timing to sufficient accuracy is hopeless.

The board has a CPU clock from which the PLL derives the video output
frequency. I recall the CPU clock being based on a crystal, but not one
with any consideration for video intervals. And the PLL's are per cog,
again my comment about (potential lack of) global sync.

Anyway, you should buy one and check it out. I'd be curious to hear
if (1) you also observe the same video quality, and (2) if you think it's
the waitvid mechanism, more the PLL->SVGA generation, or the sync issues
of the paired video generators. They even supply the schematic, FWIW.

Mark Wills

unread,
Jan 27, 2013, 3:50:59 AM1/27/13
to
The instruction times are deterministic (presumably; never written
code on the propeller), but when generating video in software, *per
scan line* all possible code-paths have to add up to the same number
of cycles in order to completely avoid jitter. That's very hard to do.

Consider a single scan line that contains text interspersed with
spaces. For the current horizontal position the software has to:

* Determine if background or foreground (i.e. a pixel of text colour)
should be drawn
* If background
* select background colour to video output register
* If foreground
* determine character under current horizontal position
* determine offset (in pixels) into the current line of the
character
* is a pixel to be drawn?
* If yes, load pixel colour
* otherwise, load background colour

The second code path is a lot more complex, containing many more
instructions, yet both code paths have to balance in terms of
execution time. This is just one example.

This is how video is done on the original Atari VCS console. 100%
software, with the hardware only providing horizontal interrupts (one
per scan line) and VBLNK interrupts, IIRC.

Caveat: The above assumes that there is no interrupt per horizontal
pixel. With interrupts, it's much easier. The Propeller doesn't have
any interrupts so software video generation would be non-trivial to
say the least. The easiest way would be to provide a pixel clock and
use an I/O pin to sync to, as Chuck found out for himself when
implementing video on the GA144.

Andrew Haley

unread,
Jan 27, 2013, 4:30:05 AM1/27/13
to
In comp.lang.forth Mark Wills <markrob...@yahoo.co.uk> wrote:
> Caveat: The above assumes that there is no interrupt per horizontal
> pixel. With interrupts, it's much easier.

I really don't understand why you say this. You need to be able to
sync to a timing pulse; whether this is done with interrupts doesn't
matter.

Andrew.

Dombo

unread,
Jan 27, 2013, 6:58:51 AM1/27/13
to
Op 27-Jan-13 9:50, Mark Wills schreef:
On the Atari VCS the software did not have to send out the individual
pixels. The TIA chip had memory for a single scan-line, which the TIA
chip converted to a video signal autonomously. The software just had to
make sure that the right data was loaded into the TIA chip in time for
each scan-line, it could finish doing that before the end of the
scan-line, but not after that. The TIA chip has also a function to stall
the CPU until the start of the next scan line. I.o.w. the software had
to be fast enough for each possible execution flow, but did not have to
complete in the exact same number of cycles.



Hugh Aguilar

unread,
Jan 28, 2013, 8:13:58 PM1/28/13
to
Maybe the reason why we don't have "doddle" or any similar word in
America, is because we never do anything the simple/easy way here! :-)

Hugh Aguilar

unread,
Jan 28, 2013, 8:42:05 PM1/28/13
to
That is somewhat of a Catch-22 --- that a person has to write a
compiler first, before knowing enough about the language to write a
simple program. In my experience, there are more people who have
written a Forth compiler, than have written a Forth program --- maybe
10 to 1.

Forth is seen as a science-fair project, and not a practical language.
The whole point of Straight Forth is to make a language that is easy
to learn and easy to use. I'm dropping all of that cruft from the
1970s that was originally introduced to work-around some limitation of
the processor, such as lack of registers and lack of memory. There is
no point in solving problems that haven't existed in 30 years --- that
is like wearing cowboy boots because they work well for horseback
riding, and suffering foot problems because they are uncomfortable as
heck for walking, and doing this in the city!

> Loops is one area where the 2012 standard could do with some more
> work! Why not mandate a flow-control stack. Go on, take the plunge!
> You'll be glad you did!

I think we are on the same page here. In Straight Forth I mandate that
the local-stack (which is also used by loops) and the stack used by >R
R@ R> are separate. Using the same stack creates incredible confusion
--- this was only done because those old 8-bit chips lacked enough
registers for each stack to have its own register dedicated as a stack
pointer. Actually, the ANS-Forth committee screwed up anyway, because
if they were to have only one register dedicated, they should have
made it a local stack and discarded >R R@ R> altogether. Those >R R@
R> words are ugly and confusing --- the primary reason they were
introduced was because locals were difficult to implement on the early
processors (for example, on the 65c02 there is no addressing mode
relative to the return-stack pointer S). The >R R@ R> words are mildly
useful, in that they facilitate variable numbers of parameters
(usually with a sentinel of some kind underneath the data), but that
isn't done very often, and it can be done with a linked-list instead
(as done in Lisp).

I have fond memories of the 65c02, as that was the processor I lost my
assembly-language virginity on. I think it is time for Forth to stop
supporting such limited processors though. Forth-200x won't stop
though, because it is all about supporting 20-year-old (1994) legacy
ANS-Forth code, and ANS-Forth was also all about supporting 20-year-
old (1974) legacy code. The Forth-200x committee is entirely focused
on the past, which is why they don't have a future. By comparison,
Straight Forth will be all about supporting modern concepts such as
closures --- considering how few Forth programmers there are (pretty
close to none), legacy Forth code isn't really something I need to
worry about, as it has all been ported over to C a long time ago.

David Brown

unread,
Jan 29, 2013, 3:15:19 AM1/29/13
to
I am not sure, but I think "doddle" is perhaps a Scottish term. As far
as I could tell from an online dictionary, the origins are from the
German word for bagpipe...

Another very useful term is "fangle", which is the Scottish word that
perfectly describes the organisation of cables on most embedded
developers' desks.

rickman

unread,
Jan 28, 2013, 9:38:05 PM1/28/13
to
I'm not getting it. I guess the software had to be done this way to
optimize the CPU utilization. The "proper" way to time in software is
to have the video data already calculated in a frame buffer and use spin
loops to time when pixels are shifted out. That way you don't have lots
of processing to figure out the timing for. But you spend most of your
processing time in spin loops. Why was it done this way? To save a few
bucks on video hardware? That's just not an issue now days... unless
you are really obsessive about not using hardware where hardware is
warranted.


> Caveat: The above assumes that there is no interrupt per horizontal
> pixel. With interrupts, it's much easier. The Propeller doesn't have
> any interrupts so software video generation would be non-trivial to
> say the least. The easiest way would be to provide a pixel clock and
> use an I/O pin to sync to, as Chuck found out for himself when
> implementing video on the GA144.

I would have to go back and reread the web pages, but I think Chuck's
original attempt was to time the *entire* frame timing in software with
NO hardware timing at all. He found the timings drifted too much from
temperature (that's what async processors do after all, they are timed
by the silicon delays which vary with temp) so that with the monitor he
was using it would stop working once the board warmed up. I'm surprised
he had to build it to find that out. But I guess he didn't have specs
on the monitor.

His "compromise" to hardware timing was to use a horizontal *line*
interrupt (with a casual use of the word "interrupt", it is really a
wait for a signal) which was driven from the 10 MHz oscillator node,
like you described the Atari VCS. He still did the pixel timing in a
software loop. With 144 processors it is no big deal to do that... *OR*
he could have sprinkled a few counters around the chip to be used for
*really* low power timing. Each CPU core uses 5 mW when it is running a
simple timing loop. One of the big goals of the chip is to be low power
and software timing is the antithesis of low power in my opinion. But
then you would need an oscillator and a clock tree...

I think there is an optimal compromise between a chip with fully async
CPUs, with teeny tiny memories, no clocks, no peripherals (including
nearly no real memory interface) and a chip with a very small number of
huge CPUs, major clock trees running at very high clock rates, massive
memories (multiple types), a plethora of hardware peripherals and a
maximal bandwidth memory interface. How about an array of many small
CPUs, much like the F18 (or an F32 which rumor has is under
development), each one with a few kB of memory, with a dedicated idle
timer connected to lower speed clock trees (is one or two small clock
trees a real power problem?), some real hardware peripherals for the
higher speed I/O standards like 100/1000 Mbps Ethernet, real USB
(including USB 3.0), some amount of on chip block RAM and some *real*
memory interface which works at 200 or 300 MHz clock rates?

I get where Chuck is coming from with the minimal CPU thing. I have
said before that I think it is a useful chip in many ways. But so far I
haven't been able to use it. One project faced the memory interface
limitation and another found the chip to be too hard to use in the low
power modes it is supposed to be capable of, just not when you need to
do real time stuff at real low power. It only needs a few small
improvements including *real* I/O that can work at a number of voltages
rather than just the core voltage.

Oh yeah, some real documentation on the development system would be
useful too. I think you have to read some three or more documents just
to get started with the tools. I know it was pretty hard to figure it
all out, not that I *actually* figured it out.

Rick

rickman

unread,
Jan 28, 2013, 9:51:04 PM1/28/13
to
Weird, your posts all show up in my reader as replies to your own
messages rather than replies to my posts. The trimming made it hard for
me to figure out just what we were talking about with the odd
connections in my reader.


On 1/26/2013 10:09 PM, None wrote:
> rickman<gnu...@gmail.com> writes:
>> I don't follow what causes the skew you mention. Instruction timings
>> are deterministic, no?
>
> The chip has a lower level bit stream engine which the higher level CPU
> ("cog") is feeding. Well, a pair of cogs. Each cog has local memory
> and then a really expensive path through a central arbiter ("hub"). It
> fills its image of the scanlines from the shared memory, then has to
> feed it via waitvid into the lower level. Note that it's bit stream
> engine *per cog*, so you also have to worry about their sync.

I can't picture the processing with this description. I don't know
about the higher level and lower level CPUs you describe. Are you
saying there is some sort of dedicated hardware in each CPU for video?
Or is this separate from the CPUs? Why a *pair* of COGs? I assume a
COG is the Propeller term for a CPU?


> So yes, instruction timings are deterministic (although your shared
> memory accesses will vary modulo the hub round-robin count). You
> need to reach the waitvid before it's your turn to supply the next value.
> But given that, this is much like the old wait state sync feeding bytes
> to a floppy controller. PLL and waitvid sync are achieved with
> magic incantations from Parallax, and it is not 100%.

Not 100%? What does that mean? Magic? I guess this is the magic smoke
you want to keep from getting out of the chip?


>> If the timings are deterministic, the skew should not be cumulative
>> since they are all based on the CPU clock. Is the CPU clock from an
>> accurate oscillator like a crystal? If it is using an internal RC
>> clock, again timing to sufficient accuracy is hopeless.
>
> The board has a CPU clock from which the PLL derives the video output
> frequency. I recall the CPU clock being based on a crystal, but not one
> with any consideration for video intervals. And the PLL's are per cog,
> again my comment about (potential lack of) global sync.

I still don't know enough about the architecture to know what this
means. I don't care if the CPUs are not coordinated closely. If you
have a video engine providing the clock timing, why would the CPU timing
matter?


> Anyway, you should buy one and check it out. I'd be curious to hear
> if (1) you also observe the same video quality, and (2) if you think it's
> the waitvid mechanism, more the PLL->SVGA generation, or the sync issues
> of the paired video generators. They even supply the schematic, FWIW.

I appreciate your enthusiasm, but I have my own goals and projects. I
am currently oriented towards absurdly low power levels in digital
designs and am working on a design that will require no explicit power
source, it will scavenge power from the environment. I don't think a
Propeller is suitable for such a task is it?

Rick

None

unread,
Jan 29, 2013, 9:10:40 PM1/29/13
to
rickman <gnu...@gmail.com> writes:
> Weird, your posts all show up in my reader as replies to your own
> messages rather than replies to my posts. The trimming made it hard for
> me to figure out just what we were talking about with the odd
> connections in my reader.

Sorry. I'm assuming your reader is threading via the "References" field?
It looks like my posting software is preserving that.

> > The chip has a lower level bit stream engine which the higher level CPU
> > ("cog") is feeding. Well, a pair of cogs. Each cog has local memory
> > and then a really expensive path through a central arbiter ("hub"). It
> > fills its image of the scanlines from the shared memory, then has to
> > feed it via waitvid into the lower level. Note that it's bit stream
> > engine *per cog*, so you also have to worry about their sync.
> I can't picture the processing with this description. I don't know
> about the higher level and lower level CPUs you describe. Are you
> saying there is some sort of dedicated hardware in each CPU for video?
> Or is this separate from the CPUs? Why a *pair* of COGs? I assume a
> COG is the Propeller term for a CPU?

Yes, each cog has its own PLL and "video" bit stream engine (quotes because
they claim it can be used for any sort of analog stream in general). They
needed to use a pair of cogs (CPU's) because of the time it takes to pull
from screen memory as conceived by the ANSI emulation and generate the
scan lines to represent the font plus underline plus cursor. So the idea
is one is doing all that while the other is painting scan lines. Double
buffering, basically.

> Not 100%? What does that mean? Magic? I guess this is the magic smoke
> you want to keep from getting out of the chip?

Yes, there is no formal/deterministic way to lock the PLL's of the two
cogs. Everybody uses the sample code Parallax provided, and it has
definitely been shown that their "lock" can be skewed.

> I still don't know enough about the architecture to know what this
> means. I don't care if the CPUs are not coordinated closely. If you
> have a video engine providing the clock timing, why would the CPU timing
> matter?

They have *two* video engines. Each is generated from its own PLL, so
the first global clock is a crystal oscillator.

> > Anyway, you should buy one and check it out. I'd be curious to hear
> > if (1) you also observe the same video quality, and (2) if you think it's
> > the waitvid mechanism, more the PLL->SVGA generation, or the sync issues
> > of the paired video generators. They even supply the schematic, FWIW.
> I appreciate your enthusiasm, but I have my own goals and projects. I
> am currently oriented towards absurdly low power levels in digital
> designs and am working on a design that will require no explicit power
> source, it will scavenge power from the environment. I don't think a
> Propeller is suitable for such a task is it?

Darn, because I'm pretty sure you are much better equipped to drill
down into this than I. :-> But, no way, a Propeller is definitely a
traditional CPU for your purposes.

Anders....@kapsi.spam.stop.fi.invalid

unread,
Jan 30, 2013, 7:19:18 AM1/30/13
to
In comp.arch.embedded David Brown <da...@westcontrol.removethisbit.com> wrote:

> Another very useful term is "fangle", which is the Scottish word that
> perfectly describes the organisation of cables on most embedded
> developers' desks.

Gives a whole new meaning to the phrase "new-fangled".

-a

David Brown

unread,
Jan 30, 2013, 3:18:23 PM1/30/13
to
This would make more sense if I could spell - normally I rely on
Thunderbird's spell checker, but of course that doesn't help here! I
meant to write "fankle" rather than "fangle", and I don't think the
terms are related.

rickman

unread,
Jan 30, 2013, 6:32:59 PM1/30/13
to
On 1/29/2013 9:10 PM, None wrote:
> rickman<gnu...@gmail.com> writes:
>
> Yes, each cog has its own PLL and "video" bit stream engine (quotes because
> they claim it can be used for any sort of analog stream in general). They
> needed to use a pair of cogs (CPU's) because of the time it takes to pull
> from screen memory as conceived by the ANSI emulation and generate the
> scan lines to represent the font plus underline plus cursor. So the idea
> is one is doing all that while the other is painting scan lines. Double
> buffering, basically.

More like splitting the work load between two processors. I did timing
analysis of this (back of the envelope type stuff) for the GA144 and it
would be pretty simple with 100's of MIPs per CPU. I wouldn't think it
would be that hard with any processor running at reasonable clock rates.
Not sure why they need two CPUs. It all depends on the pixel clock
rate. For a terminal (what you seem to be describing) the pixel rate
should be fairly low, 50-80 MHz. That gives a character rate of 10 MHz
max, so I guess that could tax a 100 MIPS processor.


>> Not 100%? What does that mean? Magic? I guess this is the magic smoke
>> you want to keep from getting out of the chip?
>
> Yes, there is no formal/deterministic way to lock the PLL's of the two
> cogs. Everybody uses the sample code Parallax provided, and it has
> definitely been shown that their "lock" can be skewed.

I don't know what the architecture of this design is. Ideally there
would be no need to lock the two processors.


>> I still don't know enough about the architecture to know what this
>> means. I don't care if the CPUs are not coordinated closely. If you
>> have a video engine providing the clock timing, why would the CPU timing
>> matter?
>
> They have *two* video engines. Each is generated from its own PLL, so
> the first global clock is a crystal oscillator.

I have no image of how or why you would want to use *two* video engines,
although two could be used with one for the char data and one for the
cursor overlay. I also don't know anything about these "video engines".
If they are indeed video engines, they should be doing all the
addressing and fetching from memory. One way a terminal saves memory
bandwidth is by not fetching the same chars again for each line. In an
old implementation I remember seeing they used a shift register to
recycle the same char data for each scan line.


>> I appreciate your enthusiasm, but I have my own goals and projects. I
>> am currently oriented towards absurdly low power levels in digital
>> designs and am working on a design that will require no explicit power
>> source, it will scavenge power from the environment. I don't think a
>> Propeller is suitable for such a task is it?
>
> Darn, because I'm pretty sure you are much better equipped to drill
> down into this than I. :-> But, no way, a Propeller is definitely a
> traditional CPU for your purposes.

I'm happy to discuss this with you.

Rick

Mark Wills

unread,
Jan 31, 2013, 1:57:25 AM1/31/13
to
On Jan 30, 8:18 pm, David Brown <david.br...@removethis.hesbynett.no>
wrote:
Fankle was our "Word of the week" here in the office just last week.
Every week a word is chosen, and it's printed out on A3 and put up on
the wall. It is every engineers moral obligation to use that word as
many times as he can in every conversation he engages in. It's
hilarious. Makes client meetings so much more entertaining.

Alex McDonald

unread,
Jan 31, 2013, 1:38:39 PM1/31/13
to

Mark Wills

unread,
Jan 31, 2013, 3:34:55 PM1/31/13
to
Fit like, min?

Its nae my shot at word of the week next week, but see when it's my
shot, Stramash it'll be. Ken?

Rod Pemberton

unread,
Feb 5, 2013, 6:04:34 AM2/5/13
to
"Hugh Aguilar" <hughag...@yahoo.com> wrote in message
news:2bb0e774-9b80-44ae...@t6g2000pba.googlegroups.com...
...

> I am getting rid of DO loops altogether in Straight Forth. I'm
> also getting rid of >R R@ R> etc., or at least deprecating them.

Sigh ... Hugh, Hugh, Hugh! How many _years_ have you been
saying this? Just do it already.

Years ago, a friend of a friend of mine always just happened to
come around at the same time that I'd be telling a story he'd
already heard to someone who hadn't already heard that story
before. Of course, this guy would interrupt and point out just
how many times he had heard the story previously. ... 2 ... 3 ...
8 ... He was really irritating. Of course, he probably thought I
was really irritating for telling the same story over and over.
He probably thought I was a bore too or perhaps forgetful. But, I
wasn't telling *him* the story over and over. I only told him the
story once. I was telling another person or people the story for
the first time. He consistently butted into or joined the telling
of the story to others. From my perspective, he had no tact or
was inconsiderate or rude. He wouldn't let me tell my stories to
someone new without aggravating me by pointing out that he'd heard
it already. Even though it was clear he was the only one present
uninterested hearing my story, he wouldn't leave the area. If he
had thought about who was present at the time each story was told,
he might've realized that *he* was the only person consistently
present.

So, from my perspective, you're the bore in this case ... I guess
that makes me the irritant. ;-) Of course, Mark or anyone else
here could be the irritant, since everyone here for more than a
year or two has heard you say you're going to eliminate >R R@ R>
from StraightForth over and over and over ... yet again. We're
waiting. We're hoping. Just do it already.

> I use BEGIN loops with local variables for iteration. DO loops
> were invented in the 1970s, prior to Forth having local
> variables --- I and J are just crude implementations of
> local variables.

I wouldn't know about that.

I and J do need to save and move around _two_ data items, at least
in my current implementation ...

> I think that DO loops are overly complicated.

I agree that the *implementation* of DO loops is overly
complicated. Their use seems simple enough, though.

> It is weird to have I and J available only in the loop
> and not outside.

Huh? Do you mean have I and J available only in the _inner_
loop of two loops, with the outer loop's I equivalent to the inner
loop's J, and not have either available outside both loops, or
somesuch ... ?

> Also, if you have nested loops, I means one
> thing in the outer loop and something else in the inner loop ---
> that's confusing.

That's simply because I and J are stacked and not in memory as
named variables. If you use variables, I will always be I and J
will always be J, yes? Then, Forth becomes more like the BASIC
that you desire in regards to I and J and likely K too. It's a
simple change. Do it, already. Of course, *NOT* using the a
stack for I and J, wouldn't be the "Forth way", i.e., "you can't
do that" ...

> Also, it is very confusing that >R R@ R> etc. can be
> used in a colon word, but they can't carry values into the DO
> loop --- so they can't really be used as local variables, which
> is their intended purpose.

Personally, I don't "see" use as "local variables" as the intended
purpose of >R R@ R> and/or RDROP etc. The purpose is to
effectively implement either 1) an "infinite" tape as it's known
for a Turing machine, or 2) the equivalent of stack frames for a
0-operand language. Basically, with >R R@ R> both the
data/parameter stack and the return/control stack, become a single
stack for manipulating data. >R R@ R> function similarly to a
stack pointer, e.g., ESP and EBP combination for 32-bit x86
assembly, allowing the coder to move up and down the stack to the
collection of data items they wish to manipulate. Each collection
of data items can be viewed as a stack frame.

(Recently, you said you finally learned something from me ... Did
you learn something from this last paragraph? If not, I have to
assume it's a fault on your part, not mine.)

> DO loops are also anti-intuitive and confusing when
> you are descending rather than ascending. All in all, DO
> loops are an ugly kludge from the 1970s that can be discarded.

Sigh, transparent, I'll feign that I'm not being baited ...

So, what type of looping construct do you recommend, Hugh? Have
you created a new one? Are you willing to share it with others
here or is it proprietary? I've not yet noticed you starting a
thread on a new loop method for Forth. If I have to, desire to,
or it results in better code, I can use a while(1) loop in C - the
simplest available for C - for any situation that requires a loop.
However, C provides a richer set of loop constructs, where less
coding is required. Are you stating that you'd like to eliminate
higher level loops in Forth?

> Also, I have separate stacks for single-precision and
> double-precision data (and a third stack for floats) ---

Massive overkill?

> I don't jumble different types of data together on the same
> stack as done in ANS-Forth, which is another 1970s kludge
> (jumbling everything together was originally done
> due to a shortage of registers and shortage of memory).

True, probably. Although, early Forths likely didn't have as many
different types of data either. I.e., they didn't need multiple
stacks, in the first place. So, why implement them? That begs
the question of what is the actually the cause and what is the
effect.


Rod Pemberton




Rod Pemberton

unread,
Feb 5, 2013, 6:05:01 AM2/5/13
to
"Hugh Aguilar" <hughag...@yahoo.com> wrote in message
news:a4032a5a-73c6-485e...@po6g2000pbb.googlegroups.com...
...

> By comparison, Straight Forth will be all about
> supporting modern concepts such as closures ---

People keep telling me C needs this closure concept also. I have
yet to run into some situation that can't be coded in C. I've
coded alot of simple stuff and well as some really complex stuff.
So, what do I need closures for? I suspect the same issue I have
with not needing them is true for Forth too. I.e., closures are
desired by you because it fits your coding style or perhaps your
way of thinking, but they're not _really_ needed. If they're not
*really* needed, should the be present in the language proper?
That's really a question for comp.lang.misc.

However, I think your goal actually requires more than just
eliminating all the ancient Forth cruft. I think you should start
by naming things what they should've be named, e.g., logical not
named NOT, etc. The names need to make sense. ANS and earlier
standards renamed a few things to prevent namespace collisions.
Unfortunately, that means that some names make no sense. That
alienates programmers. Also, I think you should adopt C style
symbol operators instead of using word names, e.g., AND, OR, XOR,
NOT, etc for logical and binary operations. Most currently
successful modern languages have adopted C's style of naming for
such operators. Forth needs some minimal syntax, like braces { },
needs some operators other than +! to manipulate variables
directly, etc. Non-use of variables, specifically, heavy
dependence on the stack, also leads to hard to comprehend code.
Once you get done fixing Forth's problems, is the language still
Forth? I know that question _seems_ silly to you right now, but
it comes directly from my experience with another language: C. In
attempting to create a minimal version of C, once I reduce C to
the minimal language subset of C that is required, fix the
remaining historical language problems, make parsing and compiling
easier, etc, then the language I have left is no longer C anymore.
It's still C looking. It's still C like. But, it's not C. Once
you start radically changing things on your own to "fix" Forth,
i.e., StraightForth, it's not really going to be Forth anymore, at
least not in the classic sense. That's something I think you
haven't truly accepted yet. If you did, we'd be seeing your
progress reports, your questions, your website, etc. I.e.,
StraightForth is a stalled idea since it seems apparent you're not
actually working on it. If you're attempting to inspire interest
in it to attract developers, perhaps you just need to ask.


Rod Pemberton




Andrew Haley

unread,
Feb 5, 2013, 9:41:36 AM2/5/13
to
Rod Pemberton <do_no...@notemailnotz.cnm> wrote:
> "Hugh Aguilar" <hughag...@yahoo.com> wrote in message
> news:a4032a5a-73c6-485e...@po6g2000pbb.googlegroups.com...
> ...
>
>> By comparison, Straight Forth will be all about
>> supporting modern concepts such as closures ---
>
> People keep telling me C needs this closure concept also. I have
> yet to run into some situation that can't be coded in C.

I think closures are more C++ than C. Closures are really just about
notational convenience and expressiveness. There is nothing that you
can't write in C, but it might be a lot of C.

> I've coded alot of simple stuff and well as some really complex
> stuff. So, what do I need closures for? I suspect the same issue I
> have with not needing them is true for Forth too. I.e., closures
> are desired by you because it fits your coding style or perhaps your
> way of thinking, but they're not _really_ needed.

And fitting into a coding style or a way of thinking isn't important,
apparently!

> If they're not *really* needed, should the be present in the
> language proper?

From that point of view, nobody *really* needs anything more than
assembler. But notation is important: it affects the way we think
about things and restricts what we can think about.

Andrew.

Paul Rubin

unread,
Feb 5, 2013, 1:21:10 PM2/5/13
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes:
> I think closures are more C++ than C. Closures are really just about
> notational convenience and expressiveness. There is nothing that you
> can't write in C, but it might be a lot of C.

C++11 has anonymous functions but they're not Scheme-like closures from
what I can tell. Closures seem much less useful without garbage
collection. Their point is that any variables that are bound in the
surrounding context but free in the nested function, have their values
copied into the closure when the closure is created, and the closure
(with those values) stays around after the surrounding function has
returned. Languages without first-class functions usually do this sort
of thing with OOP or similar.

Bernd Paysan

unread,
Feb 5, 2013, 3:37:57 PM2/5/13
to
C++11 "closures" are indeed that: OOP classes that have an overloaded
function call operator, which actually invokes a method.

I don't think that's too wrong. That's the way to do it in an OOP
language. The way I would implement this sort of pseudo-closures in
current Gforth (with OOP vtable for compile, and other stuff) is to
instantiate an object on the heap, which gets its first part filled with
a dodoes CFA and the apropriate vtable for compile, and the other
instance variables are filled with values from the stack. Call it, and
the xt bound to it can access these variables.

Freeing of no longer needed closures would be explicit. Syntax
something like

[:{ a b } ... use of a and b ... ;]

a and b would normal current-object ivars, and the setting of the
current object would be compiled into the quotation-like stuff. To free
it, you simply "dispose" the xt.

The difference from C++11's closures: This would be a real first class
function. It would just be implemented with some minor OOP technique
(instance variables). The ivars would live in the same temporary
dictionary region that's used for local variables, too. They would
actually be a variant of ivars which use TO for assignments...

The point of Forth design is not to exactly mimic something else, which
is overly complex or requires fundamental design changes to the
language, but build a tool, which solves the essence of the problem in a
way that is more natural to Forth.

Example: Let's have a Forth closure for a counter. We give it
initialization value and increment. With real closures, you would do
that as follows:

: counter { start inc -- xt }
[: ( -- value ) start inc + dup to start ;] ;

i.e. you create the locals outside the closure. The way as above would
be

: counter ( start inc -- xt )
[:{ start inc -- value } start inc + dup to start ;] ;

This makes it an extension to Forth, which require some carnal knowledge
(how to add words to the locals space), but otherwise fits into the
standard design decisions of a Forth system, i.e. no garbage collection,
and no non-trivial lexical scoping.

--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://bernd-paysan.de/

Elizabeth D. Rather

unread,
Feb 5, 2013, 3:44:53 PM2/5/13
to
On 2/5/13 10:37 AM, Bernd Paysan wrote:
...
> The point of Forth design is not to exactly mimic something else, which
> is overly complex or requires fundamental design changes to the
> language, but build a tool, which solves the essence of the problem in a
> way that is more natural to Forth.
>
> Example: Let's have a Forth closure for a counter. We give it
> initialization value and increment. With real closures, you would do
> that as follows:
>
> : counter { start inc -- xt }
> [: ( -- value ) start inc + dup to start ;] ;
>
> i.e. you create the locals outside the closure. The way as above would
> be
>
> : counter ( start inc -- xt )
> [:{ start inc -- value } start inc + dup to start ;] ;
>
> This makes it an extension to Forth, which require some carnal knowledge
> (how to add words to the locals space), but otherwise fits into the
> standard design decisions of a Forth system, i.e. no garbage collection,
> and no non-trivial lexical scoping.

Ok. But what is the advantage of doing this vs. simply writing the
definition in the conventional way?

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."
==================================================

Andrew Haley

unread,
Feb 5, 2013, 4:52:17 PM2/5/13
to
Paul Rubin <no.e...@nospam.invalid> wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>> I think closures are more C++ than C. Closures are really just about
>> notational convenience and expressiveness. There is nothing that you
>> can't write in C, but it might be a lot of C.
>
> C++11 has anonymous functions but they're not Scheme-like closures
> from what I can tell. Closures seem much less useful without
> garbage collection. Their point is that any variables that are
> bound in the surrounding context but free in the nested function,
> have their values copied into the closure when the closure is
> created, and the closure (with those values) stays around after the
> surrounding function has returned.

Sure, but what's your point? C++ does this, even though it's up to
you to free the closure.

Andrew.

Hugh Aguilar

unread,
Feb 5, 2013, 6:07:36 PM2/5/13
to
On Feb 5, 11:21 am, Paul Rubin <no.em...@nospam.invalid> wrote:
I think that GC is totally wrong for Forth. If people want GC, then
they should program in Scheme or one of the many Scheme-derived
languages, but not in Forth --- Forth is for micro-controllers, and
there is no way to distinguish between integers and pointers, so GC is
just not a good idea. I also think that OOP is totally wrong for
Forth, for the same reasons.

My closures are pretty simple. They do NOT "stay around after the
surrounding function has returned" --- if the creator function (what
you call surrounding function, or some call parent function) has gone
out of scope, executing the closure will abort the program with a
helpful error message. Also, my closures can't be nested, so they
can't be used for control-structures (IF, WHILE, etc.) and/or stack-
manipulation (DIP, etc.) as done in Factor (I didn't really like
Factor, as I thought that the quotations were overused). My closures
(or quotations, whatever you want to call them) are primarily only for
iterators. These are similar to EACH in my novice package. The
iterator typically iterates through a data structure (list, tree,
whatever), and applies the closure to every node --- the closure can
communicate with its creator function by way of the creator function's
local variables, which the closure has access to. The purpose of this
is to save the programmer from using cut-and-paste code to iterate
through data structures, which makes his source-code bloated,
difficult to read and error-prone. There are two kinds of factoring;
internal and external. External has always been used in Forth, and was
championed by Chuck Moore as a fundamental aspect of Forth
programming. Internal requires closures, and is largely unknown to
Forth programmers.

What I'm doing is pretty simple. I am keeping it simple so that it
will work on micro-controllers. That is a big part of why I'm
targeting the PIC24 first. The PIC24 is pretty small by modern
standards, so if I can get my language to work on it, then it should
work on anything. Getting a language to work on the ARM isn't going to
do me much good, as the ARM is a pretty big processor and it has
already been done to death. Slava told me that he is targeting the ARM
with Factor, and that he thinks the ColdFire is the smallest processor
that could support Factor. By comparison, the ColdFire and ARM are
gigantic processors from my perspective. My background is in writing
MFX for the MiniForth --- and the MiniForth is an extremely low-level
processor (it was built on a PLD), which makes the PIC24 look like a
giant.

Hugh Aguilar

unread,
Feb 5, 2013, 6:21:19 PM2/5/13
to
On Feb 5, 4:04 am, "Rod Pemberton" <do_not_h...@notemailnotz.cnm>
wrote:
> "Hugh Aguilar" <hughaguila...@yahoo.com> wrote in message
DO loops are not just complicated to implement, but they are also
complicated to learn, and they are error-prone to use. My loops are
much more similar to C's than Forth's.

> > Also, I have separate stacks for single-precision and
> > double-precision data (and a third stack for floats) ---
>
> Massive overkill?
>
> > I don't jumble different types of data together on the same
> > stack as done in ANS-Forth, which is another 1970s kludge
> > (jumbling everything together was originally done
> > due to a shortage of registers and shortage of memory).
>
> True, probably.  Although, early Forths likely didn't have as many
> different types of data either.  I.e., they didn't need multiple
> stacks, in the first place.  So, why implement them?  That begs
> the question of what is the actually the cause and what is the
> effect.

Using multiple stacks actually simplifies the user's source-code
considerably. Most of the stack-juggling that gives Forth a reputation
for unreadability, is due to having too much data on the stack, and
having double-width data mixed together with single-width data on the
same stack. By having one stack for single-width and another stack for
double-width, I eliminate a lot of stack-juggling --- this is a very
Forth-like solution, as it also eliminates the need for local
variables (which Forth purists don't like, and which are the sign of
the recalcitrant C programmer).

Hugh Aguilar

unread,
Feb 5, 2013, 6:49:39 PM2/5/13
to
On Feb 5, 4:05 am, "Rod Pemberton" <do_not_h...@notemailnotz.cnm>
wrote:
> "Hugh Aguilar" <hughaguila...@yahoo.com> wrote in message
>
> news:a4032a5a-73c6-485e...@po6g2000pbb.googlegroups.com...
> ...
>
> > By comparison, Straight Forth will be all about
> > supporting modern concepts such as closures ---
>
> People keep telling me C needs this closure concept also.  I have
> yet to run into some situation that can't be coded in C.  I've
> coded alot of simple stuff and well as some really complex stuff.
> So, what do I need closures for?  I suspect the same issue I have
> with not needing them is true for Forth too.  I.e., closures are
> desired by you because it fits your coding style or perhaps your
> way of thinking, but they're not _really_ needed.  If they're not
> *really* needed, should the be present in the language proper?
> That's really a question for comp.lang.misc.

Of course I'm implementing closures because they fit my programming
style. Who else would I care about other than myself?

> However, I think your goal actually requires more than just
> eliminating all the ancient Forth cruft.  I think you should start
> by naming things what they should've be named, e.g., logical not
> named NOT, etc.  The names need to make sense.  ANS and earlier
> standards renamed a few things to prevent namespace collisions.
> Unfortunately, that means that some names make no sense.  That
> alienates programmers.  Also, I think you should adopt C style
> symbol operators instead of using word names, e.g., AND, OR, XOR,
> NOT, etc for logical and binary operations.  Most currently
> successful modern languages have adopted C's style of naming for
> such operators.  Forth needs some minimal syntax, like braces { },
> needs some operators other than +! to manipulate variables
> directly, etc.  Non-use of variables, specifically, heavy
> dependence on the stack, also leads to hard to comprehend code.

I am renaming some words. For example, NOT will do what 0= currently
does in ANS-Forth. I will have FLIP for doing a logical not.

I don't think that symbolic tokens && || etc. are a good idea --- I
think that AND and OR etc. are more readable. I'm not firm on this
though --- maybe I will take your suggestion about using C-style names
rather than Pascal-style names.

I have no idea what { } braces are going to do for me. Can you
elaborate on this?

I have a lot of words similar to +! but for other kinds of operations
--- -! *! /! mod! and! or! xor! etc.. These not only improve the
readability, but they are make a VM simpler (that is actually why C
originally had += etc., because it was originally a VM similar to
Forth).

> Once
> you start radically changing things on your own to "fix" Forth,
> i.e., StraightForth, it's not really going to be Forth anymore, at
> least not in the classic sense.  That's something I think you
> haven't truly accepted yet.  If you did, we'd be seeing your
> progress reports, your questions, your website, etc.  I.e.,
> StraightForth is a stalled idea since it seems apparent you're not
> actually working on it.  If you're attempting to inspire interest
> in it to attract developers, perhaps you just need to ask.

Straight Forth won't be anything like ANS-Forth --- Straight Forth is
the future, and ANS-Forth is the past.

Straight Forth has been stalled several times. I get depressed, and I
stop working on it. Forth is really dead, and it has a very bad
reputation as being a haven for incompetents (it is difficult to fake
competence in C as almost everybody knows C, but a phony can fake
expertise in Forth and imagine that he's fooling everybody, as very
few people know enough about Forth to readily distinguish between
baloney and fact) --- because of this, the vast majority of
programmers will ignore anything related to Forth without looking at
it at all, and Straight Forth would be doomed just because of the word
Forth being part of the name.

Recently however, I have come up with several ideas that have gotten
me excited about the project again (not closures or getting rid of DO
loops, which are old ideas for me, and not all that innovative) ---
because of this, I am now working diligently on Straight Forth again.
I threw out everything that I wrote previously, and started over from
scratch. I've done that more than once already, but hopefully what
I've got going this time is the design that I ultimately want, and I
will carry it through to completion.

Anyway, what is the hurry? Nobody else is doing anything innovative at
all in Forth, so no matter how long I take I will still be the
firstust with the mostust. Well, Passaniti has written a Forth-like
interpreter in Perl --- that has really got me shaking in my boots
(from laughter!).

Paul Rubin

unread,
Feb 6, 2013, 3:29:31 AM2/6/13
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes:
> Sure, but what's your point? C++ does this, even though it's up to
> you to free the closure.

Here is an idiomatic use of a closure in Python, to make a simple
on-screen GUI keyboard:

import Tkinter as T
def press(key): print 'you pressed', key
T.Tk()
def make_keyboard():
for i,cs in enumerate(['qwertyuiop','asdfghjkl;','zxcvbnm,./']):
for j,c in enumerate(cs):
T.Button(text=c,command=lambda k=c: press(k)) \
.grid(row=i,column=j)
make_keyboard()
T.mainloop()

The closure is the callback expression

lambda k=k: press(k)

which is a bit ugly because of Python's weird scoping rules, but the
point is that it creates a callable object that wraps the value of k,
and passes that into the bowels of the GUI framework, which squirrels it
away and calls it through some inscrutable mechanism (maybe in another
thread, etc.) when the user presses buttons. It would be useless if
the closure didn't persist after the make_keyboard call returned.

Python style note: these days it's also possible and maybe nicer to use
functools.partial(press, k).

Paul Rubin

unread,
Feb 6, 2013, 3:31:18 AM2/6/13
to
Paul Rubin <no.e...@nospam.invalid> writes:
> lambda k=k: press(k)
Oops,
lambda k=c: press(k)

Bernd Paysan

unread,
Feb 6, 2013, 1:46:40 PM2/6/13
to
Well, currying is totally trivial in Forth, once you accept that you
can't reclaim the memory for the curried function:

: curry ( lit xt -- xt' ) >r >r
:noname r> postpone literal r> compile, postpone ; ;

Test it:

3 ' + curry alias 3+ ok
5 3+ . 8 ok

Hugh Aguilar

unread,
Feb 6, 2013, 9:26:09 PM2/6/13
to
On Feb 6, 1:29 am, Paul Rubin <no.em...@nospam.invalid> wrote:
> The closure is the callback expression

I like that term, "callback," as it is pretty self-descriptive ---
terms such as "closure," "quotation" and "lambda" don't really provide
any hint as to what they mean. "Closure" seems to indicate that
something is being closed, but what? "Quotation" seems to indicated a
text string containing prose, but that is not it. "Lambda" is just a
Greek letter, and it has no meaning whatsoever.

In my novice package I used the term "toucher" which was really dumb
sounding --- I'm going to drop that.

I have been thinking of using the term "operative" --- that is quite
descriptive, as the creator function is sending it out into the world,
but it maintains communication with the creator function by way of the
creator function's local variables which it has access to. Besides
that, it gives programming a cloak-and-dagger aspect! :-)

Does anybody other than the Python crowd use the term "callback"? If
it is popular, maybe I will go with it, as it is at least somewhat
self-descriptive.

> the
> point is that it creates a callable object that wraps the value of k,
> and passes that into the bowels of the GUI framework, which squirrels it
> away and calls it through some inscrutable mechanism (maybe in another
> thread, etc.) when the user presses buttons.  It would be useless if
> the closure didn't persist after the make_keyboard call returned.

I don't get at all what the point is of having a quotation, or
callback function, be executable after the creator has gone out of
scope. What is it calling back to? It is like E.T. trying to phone
home, but there is no planet there anymore.

I really don't get what the point of this is. Why not just use :NONAME
instead???

Allowing a quotation to be executable after the creator function has
gone out of scope, requires that the creator function's local
variables be in the heap rather than on a locals stack --- but
ALLOCATE is typically very slow compared to a stack, and GC is very
messy in Forth --- that is an incredibly complicated solution to a non-
problem.

Paul Rubin

unread,
Feb 9, 2013, 3:11:13 AM2/9/13
to
Bernd Paysan <bernd....@gmx.de> writes:
> : curry ( lit xt -- xt' ) >r >r
> :noname r> postpone literal r> compile, postpone ; ;

I can't really understand that without studying deep-down parts of Forth
compilation that I haven't had to use so far. One thing I'd wonder is
whether you can have a mutable cell in the closure. E.g. a classic
Scheme closure is:

(define (counter)
(let ((n 0))
(lambda ()
(set! n (1+ n))
n)))

This creates a variable n, then a function (the lambda) which, when you
call it, increments n and returns the new value, something like an
OOP method incrementing and returning an instance variable

guile> (define a (counter))
guile> (define b (counter))

That made two counters each with its own n. Now you can call them
independently of each other:

guile> (a)
1
guile> (a)
2
guile> (a)
3
guile> (b)
1
guile> (b)
2
guile> (a)
4

Anton Ertl

unread,
Feb 9, 2013, 5:25:27 AM2/9/13
to
Paul Rubin <no.e...@nospam.invalid> writes:
>Bernd Paysan <bernd....@gmx.de> writes:
>> : curry ( lit xt -- xt' ) >r >r
>> :noname r> postpone literal r> compile, postpone ; ;
>
>I can't really understand that without studying deep-down parts of Forth
>compilation that I haven't had to use so far.

Given your interests, I would highly recommend studying these features
soon. E.g., take a look at

http://www.complang.tuwien.ac.at/forth/gforth/Docs-html/POSTPONE-Tutorial.html
http://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Literal-Tutorial.html
http://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Advanced-macros-Tutorial.html
http://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Compiling-words.html

Deep down? Not really.

>One thing I'd wonder is
>whether you can have a mutable cell in the closure. E.g. a classic
>Scheme closure is:
>
> (define (counter)
> (let ((n 0))
> (lambda ()
> (set! n (1+ n))
> n)))
>

Sure:

: docounter ( addr -- n )
1 over +! @ ;

: counter ( -- )
here 0 , >r :noname r> postpone literal postpone docounter postpone ; ;

counter alias a
counter alias b
a . a . a . b . b . a .

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2013: http://www.euroforth.org/ef13/
0 new messages