Shop Learn
Catalina - ANSI C for the Propeller 1 & 2 - Page 2 — Parallax Forums

Catalina - ANSI C for the Propeller 1 & 2



  • RossHRossH Posts: 4,845

    A linux release of Catalina 5.0 has been added to SourceForge - see

  • RossHRossH Posts: 4,845

    I could have predicted this would happen as soon as I finished the release. It always seems to! :)

    I wondered why one of my Lua example programs (ex9.lua) seemed to need much more stack space than the other examples to execute reliably, even though it didn't really do much more. I never could figure out why, so I also used it as an example of how Lua's garbage collector can help when memory gets tight. But it turns out this example does not need the larger stack at all - it was apparently the result of an obscure bug in Lua itself, which I seem to have now fixed quite by chance while working on something else.

    There are no functional changes to either Lua or the new multi-threading module, and in any case I will probably leave the example intact (except for the stack size) as an example of managing Lua's garbage collector, but I'll wait to see if anything else crops up before I re-package release 5.0 (or release 5.1 if I find anything more serious).


  • RossHRossH Posts: 4,845

    Catalina 5.0.1 has been released here.

    This release adds no significant new functionality, but it fixes one major Lua issue and a couple of other minor issues.

    Here is the relevant part of the README.TXT:

    RELEASE 5.0.1
    New Functionality
    1. Modified various Catalyst commands to allow combined command-line 
       options - e.g. -dh now means the same as -d -h
    Other Changes
    1. Fixed a bug in the DOSFS file system which allowed a file to be opened
       as a directory using the DFS_OPENDIR option to DFS_OpenFile instead of
       returning that a directory of that name did not exist. This confused
       the Catalyst cp command when copying files into a directory.
    2. Fixed a bug in the Catalyst rm command that prevented recursive file
    3. Fixed a bug in the Lua threads module that prevented the number of 
       factories being reduced. Also, the Lua threads module documentation
       has been updated to reflect the fact that reducing the number of 
       factories now necessarily terminates all workers first (they are 
       restarted after the number of factories has been reduced) and that 
       this should therefore only be done from the main thread and when that 
       thread is executing on factory 1.
    4. Modified Lua to zero all newly allocated blocks of memory. Lua seems to
       assume all new blocks of memory will be initialized to zero, which is 
       not actually guaranteed by C, so this led to some Lua programs behaving
       unexpectedly. While this fix resolves the issue, it does so at a small 
       run-time cost, so further investigation is required. Multi-threaded Lua
       example 9 was badly affected by this issue and has been updated. The 
       Lua threads module documentation has also been updated.

    I have also updated the version of Multi-threaded Lua pre-compiled for the P2 Evaluation board which is attached to an earlier post.


  • RossHRossH Posts: 4,845

    As usual, I wish I had thought to do this before the release! :/

    Now that I have fixed Lua's memory issue, I thought I'd try compiling Multi-threaded Lua in NATIVE mode rather than COMPACT mode. Doing so means there is less memory available for Lua programs, but the programs will execute much faster. The command I used was:

    build_all P2_EVAL SIMPLE VT100 OPTIMIZE

    Here are the results for the 10 tutorial examples:

    ex1.lua, ex2.lua, ex3.lua, ex5.lua, ex7.lua, ex10.lua : All good. Can be executed from source (using mlua), or compiled (using lauc and mluax).

    ex4.lua : The increased execution speed highlights that the original program has a race condition. Adding a small delay to the ping and pong functions fixes the problem:

       function ping()
          t = threads
          for i = 1, t.shared("count") do
            ball = t.get("ping")
            t.output("ping ")
            t.msleep(10)             -- DELAY ADDED
            t.aput("pong", ball)
       function pong()
          t = threads
          for i = 1, t.shared("count") do
            ball = t.get("pong")
            t.msleep(10)             -- DELAY ADDED
            t.aput("ping", ball)

    ex6.lua : Must now be compiled. Otherwise, all good.

    ex8.lua : There is only enough memory available to execute 6 workers concurrently (not 12) and the increased execution speed is such that a small delay needs to be added to the Thread function to illustrate that all the workers are indeed executing in parallel:

       count = 6
       function Thread(me, iter)
          return function()
            t = threads
            -- wait till we are told to go
            repeat until t.shared("go")
              t.output(me .. " ")
              t.msleep(10)           -- DELAY ADDED
              iter = iter-1
            until iter == 0

    ex9.lua : There is only enough memory available to recycle up to 2 workers, not all 4:

       t.recycle(2)                  -- WAS 4

    Other than example 9, these programs are too small and simple to show much improvement in execution speed ... except (in strict accordance with Murphey's Law) where it highlights a problem in my example programs! :(


  • RossHRossH Posts: 4,845
    edited 2022-04-06 06:53

    There is an interesting synergy between Lua co-routines and threads. I will add this to the threads documentation in the next release, but the example program below can be executed with the current release, so I thought I would post a preview here because it shows what a "rich" language Lua is ...

    Even without the threads module, Lua has a simple type of multi-tasking. It has non-preemptive multi-tasking in the form of co-routines. The threads module adds preemptive multi-tasking. However, this has interesting implications when co-routines are executed using the threads module.

    Here is a simple example:

    -- Generate a function which can be executed 
    -- as either a coroutine or as a thread
    function Generate(me)
      return function ()
        for i = 1, 10 do
          threads.print(me ..":" .. i)
    -- Execute the functions as coroutines
    threads.print("\nFUNCTIONS AS COROUTINES")
    -- create 4 functions as coroutines and also
    -- wrap the coroutines inside another function
    fee = coroutine.wrap(Generate("fee"))
    fi  = coroutine.wrap(Generate("fi"))
    fo  = coroutine.wrap(Generate("fo"))
    fum = coroutine.wrap(Generate("fum"))
    -- execute the coroutines 
    -- and again
    -- Execute the functions as threads
    threads.print("\nFUNCTIONS AS THREADS")
    -- we only need one worker to execute any number of 
    -- threads if those threads explicitly "yield" 
    -- create (and start) 4 functions as threads"fee"))"fi"))"fo"))"fum"))
    -- wait for all threads to complete

    Here is the output this program produces:


    When the functions are executed as co-routines, then each time the function is called, it executes one iteration and then "yields". This "yield" call is the key to co-routine behavior. It returns control to the caller, but "suspends" the co-routine rather than exiting it. When the function is called again, it does not start from the beginning as a normal function would, it instead continues execution from where it was last suspended - i.e. just after the last "yield". This is normal co-routine behavior (for more details on co-routines, see the Lua documentation).

    The interesting thing is the consequence of calling "yield" when the functions are executed as threads instead of co-routines. When a thread yields then the thread is suspended, but the worker executing that thread is not - it moves on to resume execution of the next suspended thread. If there is no other suspended thread it will resume execution of the same thread. Since we started all our functions as threads, this means that one worker (which is one Posix thread) will execute all the functions concurrently (using non preemptive multitasking) provided those functions are written as co-routines. If the functions are not written as co-routines, then you need multiple workers available to execute them concurrently (using preemptive multitasking). Which of course is very easily done in this example - just change the number of workers from 1 to 4. You can try it, but in this simple example it makes little or no obvious difference to the output.

    In summary, with 1 worker the program uses non preemptive multitasking. With 4 workers it uses fully preemptive multitasking. With 2 or 3 workers, it would use a mixture of both.

    Isn't Lua an interesting language? :)


  • RossHRossH Posts: 4,845

    Catalina 5.0.2 has been released here.

    This release is a patch release for both Windows and Linux. It must be installed over Catalina 5.0.1. It adds no new functionality, but it fixes one Lua issue and adds a couple of new Lua examples. If you are not interested in Lua you don't need it - the changes will also be included in the next full release.

    Here is the relevant part of the README.TXT:

    RELEASE 5.0.2
    New Functionality
       This release contains no new functionality.
    Other Changes
    1. Fixed a bug in the Lua threads module when sending and receiving messages. 
       The program could lock up under certain circumstances. Since the Lua
       threads module is only supported on the Propeller 2, this affected the
       Propeller 2 only.
    2. Multi-threaded Lua examples 4 has been updated to eliminate a race 
    3. Multi-threaded Lua example 8 has been updated to make it more evident the
       example is using preemptive multi-tasking.
    4. Multi-threaded Lua examples 11 and 12 have been added to demonstrate
       interactions between co-routines and threads.
    5. The document Lua on the Propeller 2 with Catalina has been updated to
       reflect the above changes. Also, some terminology issues have been

    I have also updated the version of Lua pre-compiled for the P2 Evaluation board which is attached to an earlier post.


  • RossHRossH Posts: 4,845

    Interesting. Now that Lua 5.1 seems rock solid (yes, I realize I'm tempting fate here :smile: ) I have been re-looking at Lua 5.4, which is the latest and greatest version.

    When I looked at it a while ago, the first thing I noticed was that the initial code/data footprint of Lua 5.4 is much larger than that of Lua 5.1 - by about 40kb even in COMPACT mode. This was enough for me to stay with 5.1 as the default version even though 5.4 seemed to have some useful improvements.

    But it turns out I didn't look deeply enough - yes, the initial footprint of Lua itself is larger, but the footprint of each concurrent thread is smaller - by about 5kb. This means that if you have 8 or more workers (as you might if you have 8 cogs!), then Lua 5.4 actually ends up using less memory than Lua 5.1.

    Only one of the tutorial examples (ex8.lua) actually creates this many workers - this particular example is specifically designed to see how many workers it can execute concurrently. It turns out that you can execute more workers with Lua 5.4 than you can with Lua 5.1 - something I had not thought to check!

    As well as better memory management, Lua 5.4 also includes integer numeric types (like some versions of Basic, Lua originally only had floats) and bitwise operators, which makes it much more suitable for the type of applications common on the Propeller.

    Catalina will continue to support all versions of Lua (from 5.1 onwards) but unless I find a showstopper, I am likely to switch the default to Lua 5.4 in the next release.


  • RossHRossH Posts: 4,845

    I can't believe I missed this! I just found a version of the classic startrek game ported to Lua! I already had C, Pascal and Basic versions included with Catalina, but I had never thought to even look for a Lua version. It seems I am not the only one that remembers this game very fondly!

    The sources of the original Lua port are available here:

    In the attached zip file are two Lua versions that I have modified very slightly, because the originals were written before Lua 5.4 was released, and the math library has changed slightly. They also needed a few tweaks to the garbage collector to stop them running out of memory on the Propeller. One version is a faithful port of the original 1978 game (sst.lua) and the other is an "enhanced" version (sst-tos.lua) that incorporates dialog taken from the original scripts.

    I have not done extensive testing, but I have played them both for a few minutes each and they both seem to run ok when compiled with luac and executed using mluax.

    For instance, in Catalyst, you would use commands like:

    luac -o sst.out sst.lua
    mluax  sst.out


    luac -o sst-tos.out sst-tos.lua
    mluax  sst-tos.out

    Enjoy! :)

  • RossHRossH Posts: 4,845
    edited 2022-06-06 13:28

    I have been testing Catalina on the new P2 Edge module, and can confirm that Catalina works ok on it.

    However, while testing various things I found a bug in Catalina's SD Card plugin that may have prevented programs from being able to write to some types of SD Cards (reading was ok). I will include the updated version of the plugin with the next release of Catalina, but I have also attached it here - it can simply be copied over the current version in the target_p2 directory. Of course, you will have to recompile any programs that use it.

    Note that this bug affects the Propeller 2 only.

  • RossHRossH Posts: 4,845

    I have just posted Catalina 5.1 to SourceForge here.

    I am not getting much time for Catalina at the moment so there are not many changes, but the new SD Card plugin is included so I thought I had better do a release.

    Here is the relevant extract from the README.TXT:

    RELEASE 5.1
    New Functionality
    1. Decoding the CATALINA_DEFINE environment variable was taking place AFTER 
       the symbols to specify the clock frequency were defined, so the Catalina 
       symbols MHZ_220, MHZ_260 & MHZ_300 only worked when specified on the 
       command line, and had no effect if specified using CATALINA_DEFINE.
    2. Added MHZ_200 as a Catalina symbol, to make it easier to build Catalyst 
       using 200Mhz on the Propeller 2. Note that the Propeller 2 reference 
       manual, the tutorial Getting Started with Catalina and the documentation
       in the Propeller 2 VGA plugin source file all mistakenly referred to 
       MHZ_200 when they should have referred to the existing MHZ_220 symbol. 
       All these documents have now been updated.
    3. The Lua "propeller" module has had the functions sleep, msleep and sbrk
       added. These functions are the same as the ones in the "threads" module,
       but are handy when the propeller module is used in a non-threaded Lua
    4. The Lua "threads" and "propeller" modules now accepts a string parameter. 
       If "lua" is specified, these functions return the version of Lua. 
       Otherwise they return the version of the module
    5. Lua versions of the classic Star Trek game (sst.lua and sst-tos.lua) 
       are now included as Lua test programs.
    6. A change was made to the gettoken procedure in Dumbo Basic 1.0, which was 
       introduced in Catalina release 4.7. This change led to a syntax error when 
       executing TREK15.BAS. This change has been reverted in Dumbo Basic 1.1, but
       if this breaks any existing basic code, it can be re-implemented by 
       modifying the file basic.c and changing the #define of NEW_GETTOKEN to 1.
    7. When compiled for the Propeller, Dumbo Basic now has a delay on exit of 
       100ms to allow time for any pending output to be printed. This prevents 
       error messages or final program output from being truncated.
    Other Changes
    1. The command-line options to set the clock frequency (-f, -F and -E) were
       fully implemented, but not described in the documentation. These options 
       apply to the Propeller 2 only.
    2. On the Propeller 2, it is now recommended that Catalyst be compiled using
       a 200Mhz clock speed. This is a work-around for an obscure bug which only
       seems to affect some programs loaded from the SD card and which use a clock
       speed of 180Mhz.
    3. A bug in the SD Card plugin was preventing programs being able to write to 
       some SD cards (reading was ok). This affected the Propeller 2 only.
Sign In or Register to comment.